Выбрать главу

Например, элемент <xsclass="underline" value-of select="180+420"/> вставит в выходной документ строку "600". В следующем примере выбираются все планеты, у которых отношение дня (измеренного в днях Земли) к массе (где масса Земли принята за 1) больше 100:

<xsclass="underline" template match="PLANETS">

 <HTML>

  <BODY>

   <xsclass="underline" apply-templates select="PLANET[DAY div MASS > 100]"/>

  </BODY>

 </HTML>

</xsclass="underline" template>

XPath также поддерживает следующие функции работы с числами:

• ceiling(). Возвращает наименьшее целое, большее, чем переданное функции число;

• floor(). Возвращает наибольшее целое, меньшее, чем переданное функции число;

• round(). Округляет переданное число до ближайшего целого;

• sum(). Возвращает сумму переданных функции чисел.

Например, среднюю массу планет в planets.xml можно найти так, как в листинге 4.8:

Листинг 4.8. Вычисление средней массы планет

<?xml version="1.0"?>

<xsclass="underline" stylesheet version="1.0"

 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

 <xsclass="underline" output method="xml"/>

 <xsclass="underline" template match="PLANETS">

  <HTML>

   <BODY>

    The average planetary mass is:

    <xsclass="underline" value-of select="sum(child::PLANET/child::MASS) div count(child::PLANET)"/>

   </BODY>

  </HTML>

 </xsclass="underline" template>

</xsclass="underline" stylesheet>

Строки

В XPath строки формируются из символов Unicode, как можно было предположить. Ряд функций специально предназначен для работы со строками:

• string(object object1). Преобразует объект в строку;

• starts-with(string string1, string string2). Возвращает истину, если первая строка начинается (starts with) со второй строки;

• contains(string string1, string string2). Возвращает истину, если первая строка содержит (contains) вторую строку;

• substring(string string1, number offset number length). Возвращает length символов из строки, начиная со смещения offset;

• substring-before(string string1, string string2). Возвращает часть строки string1 до первого вхождения строки string2;

• substring-after(string string1, string string2). Возвращает часть строки string1 после первого вхождения string2;

• string-length(string string1). Возвращает количество символов в строке string1;

• normalize-space(string string1). Возвращает строку string1 после отбрасывания лидирующих и завершающих символов-разделителей и замены нескольких последовательных разделителей на один пробел;

• translate(string string1, string string2, string string3). Возвращает строку string1, в которой все вхождения символов в строке string2 заменены на соответствующие символы в строке string3;

• concat(string string1, string string2, ...). Возвращает конкатенацию (объединение) всех строк.

Есть еще одна строковая функция, о которой вам следует знать, входящая не в XPath, а в XSLT:

• format-number(number number1, string string2, string string3). Возвращает строку, содержащую число number1 в виде форматированной строки, используя string2 в качестве форматирующей строки (форматирующие строки создаются так же, как для метода Java java.text.DecimalFormat) и string3 как возможную строку локализации.

В листинге 4.9 я выбираю текстовые узлы, в которых текст начинается с 'Е', чтобы выбрать Earth (Земля), и добавляю текст '(the World)' (мир), получая 'Earth (the World)'. Для этого я применяю предикат "text()[starts-with(., 'Е')]".

Листинг 4.9. Применение функции starts-with

<?xml version="1.0"?>

<xsclass="underline" stylesheet version="1.0"

 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

 <xsclass="underline" template match="/PLANETS">

  <HTML>

   <HEAD>

    .

    .

    .

   </BODY>

  </HTML>

 </xsclass="underline" template>

 <xsclass="underline" template match="PLANET">

  <TR>

   <TD><xsclass="underline" apply-templates select="NAME"/></TD>

   <TD><xsclass="underline" apply-templates select="MASS"/></TD>

   <TD><xsclass="underline" apply-templates select="RADIUS"/></TD>

   <TD><xsclass="underline" apply-templates select="DAY"/></ТD>

  </TR>

 </xsclass="underline" template>

 <xsclass="underline" template match="text()[starts-with(., 'E')]">

  <xsclass="underline" text>(the World)</xsclass="underline" text>

 </xsclass="underline" template>

 <xsclass="underline" template match="NAME">

  <xsclass="underline" value-of select="."/>

  <xsclass="underline" text> </xsclass="underline" text>

  <xsclass="underline" value-of select="@UNITS"/>

  <xsclass="underline" apply-templates/>

 </xsclass="underline" template>

 .

 .

 .

 <xsclass="underline" template match="DAY">

  <xsclass="underline" value-of select="."/>

  <xsclass="underline" text> </xsclass="underline" text>

  <xsclass="underline" value-of select="@UNITS"/>

 </xsclass="underline" template>

</xsclass="underline" stylesheet>

А вот результат — заметьте, что заголовок для Земли стал "Earth (the World)":

<HTML>

 <HEAD>

  <TITLE>

   The Planets Table

  </TITLE>

 </HEAD>

 <BODY>

  <H1>

   The Planets Table

  </H1>

  <TABLE BORDER="2">

   <TR>

    <TD>Name</TD>

    <TD>Mass</TD>

    <TD>Radius</TD>

    <TD>Day</TD>

   </TR>

   <TR>

    <TD>Earth (the World)</TD>

    <TD>1 (Earth = 1)</TD>

    <TD>2107 miles</TD>

    <TD>1 days</TD>

   </TR>

  </TABLE>

 </BODY>

</HTML>

Этот документ показан на рис. 4.2.