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

node-set current()

Обратите внимание: current нельзя применять в образцах, поскольку образцы должны быть независимы от пути обработки, а способы реализации таких структур, как циклы, в процессорах XSLT могут различаться.

Следующий пример, в котором я выбираю элементы <PLANET> при помощи шаблона (листинг 8.1), демонстрирует работу функции current. Внутрь шаблона я поместил элемент <xsclass="underline" for-each>, и шаблон применяется только в том случае, если выбранный шаблоном контекстный узел в то же время является и текущим узлом в очередной итерации в элементе <xsclass="underline" for-each>.

Листинг 8.1. Применение функции current

<?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>

   .

   .

   .

    <TABLE BORDER=2>

     <TR>

      <TD>Name</TD>

      <TD>Mass</TD>

      <TD>Radius</TD>

      <TD>Day</TD>

     </TR>

     <xsclass="underline" apply-templates/>

    </TABLE>

   </BODY>

  </HTML>

 </xsclass="underline" template>

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

  <xsclass="underline" for-each select="/PLANETS/*[.=current()]">

   <TR>

    <TD><xsclass="underline" value-of 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"/></TD>

   </TR>

  </xsclass="underline" for-each>

 </xsclass="underline" template>

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

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

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

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

 </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>

Результат применения этой таблицы стилей будет точно таким же, как если бы элемента <xsclass="underline" for-each> вообще не было, потому что тело элемента <xsclass="underline" for-each> применяется только тогда, когда контекстный узел совпадает с текущим узлом.

document()

Функция document особенно полезна, потому что с ее помощью можно читать несколько документов и обрабатывать их содержимое. Функция document применяется следующим образом:

node-set document(uri, base-uri?)

Функция принимает параметр uri, который может представлять собой URI читаемого документа или набор узлов, чьи строковые значения задают идентификаторы URI. Второй, необязательный параметр base-uri представляет собой набор узлов, базовый URI которого используется для вычисления всех относительных URI, могущих находиться в параметре uri.

В следующем примере (листинг 8.2) я обрабатываю в процессоре XSLT один документ, planets1.xml, и также считываю и обрабатываю второй документ, planets2.xml. Вот planets1.xml.

Листинг 8.2. planets1.xml

<?xml version="1.0"?>

<?xml-stylesheet type="text/xml" href="planets.xsl"?>

<PLANETS href="planets2.xml">

</PLANETS>

Вот planets2.xml — в элементе <PLANET> содержится одна планета (листинг 8.3).

Листинг 8.3. planets2.xml

<?xml version="1.0"?>

<PLANET>

 <NAME>Mercury</NAME>

 <MASS UNITS="(Earth = 1)">.0553</MASS>

 <DAY UNITS="days">58.65</DAY>

 <RADIUS UNITS="miles">1516</RADIUS>

 <DENSITY UNITS="(Earth = 1)">.983</DENSITY>

 <DISTANCE UNITS="million miles">43.4</DISTANCE><!--B перигелии-->

</PLANET>

А вот таблица стилей planets.xml, которую я применяю к planets1.xml. Таблица стилей содержит шаблон, выбирающий элемент <PLANET> в planets1.xml, и в этом шаблоне я считываю planets2.xml при помощи <xsclass="underline" apply-templates> и функции document (листинг 8.4).

Листинг 8.4. Применение функции document

<?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>

    <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>

     <xsclass="underline" apply-templates select="document(@href)"/>

    </TABLE>

   </BODY>

  </HTML>

 </xsclass="underline" template>

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

  <TR>

   <TD><xsclass="underline" value-of 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"/></TD>

  </TR>

 </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>

Эта таблица стилей обрабатывает данные в planets1.xml и также считывает и обрабатывает planets2.xml; вот полный результат — как видите, данные для planets2.xml добавились нужным образом: