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

   <TD><xsclass="underline" value-of select="NAME"/></TD>

   <TD><xsclass="underline" value-of select="MASS"/></TD>

   <TD><xsclass="underline" value-of select="RADIUS"/></TD>

   <TD><xsclass="underline" value-of select="DAY"/></TD>

  </TR>

 </xsclass="underline" template>

</xsclass="underline" stylesheet>

Создание образцов выбора

Как вы могли ожидать, исходя из того, что "child::MASS" можно представить в виде "MASS" и применения шаблонов, таких как "/", "/PLANETS" и т.д., вплотную познакомиться с созданием образцов выбора не так-то просто — этому посвящена вся глава 4.

Образцы выбора (match pattern) являются подмножеством полного языка XPath, их можно использовать в элементах <xsclass="underline" template>, <xsclass="underline" key> и <xsclass="underline" number>. В частности, в образец можно установить атрибут match у <xsclass="underline" template> и <xsclass="underline" key>, и атрибуты count и from элемента <xsclass="underline" number>. В следующем списке приведен ряд примеров образцов выбора, много других примеров будет показано в главе 4 при подробном обсуждении использования XPath для выбора узлов и атрибутов:

• "/" выбирает корневой узел;

• "*" выбирает элементы узлов (но не всех узлов, как зачастую ошибочно полагают);

• "PLANET" выбирает элементы <PLANET>;

• "PLANET/MASS" выбирает все элементы <MASS>, дочерние для элемента <PLANET>;

• "//PLANET" выбирает все элементы <PLANET>, производные от корневого узла;

• "." выбирает текущий узел (технически это не образец выбора, а выражение XPath, как мы увидим в главе 7).

Образцы можно также использовать в атрибуте select элементов <xsclass="underline" apply-templates>, <xsclass="underline" value-of>, <xsclass="underline" for-each>, <xsclass="underline" copy-of> и <xsclass="underline" sort>; фактически атрибут select этих элементов может содержать полные выражения XPath, а не только образцы выбора. Атрибут select элемента <xsclass="underline" value-of> определяет дочерний узел, значение которого нужно получить:

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

 <TR>

  <TD><xsclass="underline" value-of select="NAME"/></TD>

  <TD><xsclass="underline" value-of select="MASS"/></TD>

  <TD><xsclass="underline" value-of select="RADIUS"/></TD>

  <TD><xsclass="underline" value-of select="DAY"/></TD>

 </TR>

</xsclass="underline" template>

Теперь пора воспользоваться атрибутом select элемента <xsclass="underline" apply-templates>, поскольку это даст нам возможность указать, какой шаблон использовать и когда.

Выбор применяемого шаблона

Вплоть до нынешнего момента я использовал только версию элемента <xsclass="underline" apply-templates> по умолчанию, как, например:

<TABLE BORDER="2">

 <TR>

  <TD>Name</TD>

  <TD>Mass</TD>

  <TD>Radius</TD>

  <TD>Day</TD>

 </TR>

 <xsclass="underline" apply-templates/>

</TABLE>

Простое использование только <xsclass="underline" apply-templates/> указывает процессору XSLT осуществлять поиск всех шаблонов, выбирающих дочерние узлы контекстного узла, — это использование по умолчанию. Однако иногда это не лучший вариант, поскольку может потребоваться применять шаблоны в определенном порядке или иным образом выбрать применяемые шаблоны (последнее можно сделать при помощи атрибута select элемента <xsclass="underline" apply-templates/>).

Например, до сих пор мы только получали значение каждого элемента <MASS>, <DAY> и <RADIUS> при помощи <xsclass="underline" value-of>:

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

    </Н1>

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

  <TR>

   <TD><xsclass="underline" value-of select="NAME"/></TD>

   <TD><xsclass="underline" value-of select="MASS"/></TD>

   <TD><xsclass="underline" value-of select="RADIUS"/></TD>

   <TD><xsclass="underline" value-of select="DAY"/></TD>

  </TR>

 </xsclass="underline" template>

</xsclass="underline" stylesheet>

Здесь только извлекается «сырое» строковое значение каждого узла, которое помещается в HTML-таблицу. Однако может потребоваться дополнительная обработка каждого элемента — например, получить также значения атрибутов UNITS каждого элемента и отобразить их:

<?xml version="1.0"?>

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

<PLANETS>

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

 .

 .

 .

Для этого нельзя просто применить элемент <xsclass="underline" value-of>, поскольку он вернет значение узла только как текст, а не как значения атрибута. Вместо этого нужно создать новый набор шаблонов, по одному для каждого интересующего нас элемента: <MASS>, <RADIUS> и <DAY>. У элемента <NAME> нет никаких атрибутов, поэтому для него не нужны шаблоны — нужно только значение узла. Каждому из этих новых шаблонов требуется получить значение элемента, а также значение атрибута UNITS.