печать счетчика с помощью XSLT

У меня есть файл XML, который я пытаюсь преобразовать в XHTML с помощью файла XSLT. Мне было интересно, можно ли подсчитать, сколько раз был вызван шаблон. Это мой XML:

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" encoding="UTF-8" href="car.xslt" version="1.0"?>
<vehicle>
  <car>
    <make>Honda</make>
    <color>blue</color>
  </car>
  <car>
    <make>Saab</make>
    <color>red</color>
  </car>
</vehicle>

А это мой XSLT:

<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet xmlns="http://www.w3.org/1999/xhtml" version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:template match="/">
<html xmlns="http://www.w3.org/1999/xhtml">
<body>
  <table cellpadding="5" border="1">
    <tr><td>number</td><td>make</td><td>color</td></tr>
        <xsl:apply-templates/>
  </table>
</body>
</html>
</xsl:template>

<xsl:template match="car">
    <tr>
      <td>#</td><td><xsl:value-of select="make"/></td><td><xsl:value-of select="color"/></td>
    </tr>
</xsl:template>

</xsl:stylesheet>

Я хочу напечатать количество раз, когда машина была напечатана вместо #, чтобы это выглядело так:

номер сделать цвет 1 Honda синий 2 Saab красный

вместо того:

номер марки цвет # Honda синий # Saab красный

У кого-нибудь есть идеи? Я надеялся, что это можно сделать с помощью только xsl: value-of и XPath


person Community    schedule 08.10.2009    source источник


Ответы (3)


Заменять

#

С участием

<xsl:value-of select="position()"/>
person ChaosPandion    schedule 08.10.2009
comment
что печатает: номер сделать цвет 2 синий Honda 4 красный Saab, но я хотел, чтобы номер сделал цвет 1 синий Honda 2 красный Saab Я проверяю, есть ли какие-либо аргументы в пользу позиции о глубине и т. д. - person ; 08.10.2009
comment
можно было бы сказать position () * 0.5 ... но почему все умножается на два? - person ; 08.10.2009
comment
Когда вы используете position() в этом контексте, XSLT перечисляет дочерние узлы элемента vehicle. Дочерние узлы в исходном примере: (1) текстовый узел (набор пробелов); (2) элемент car; (3) текстовый узел (больше пробелов); (4) элемент car; (5) текстовый узел (больше пробелов). Итак, когда вы сопоставляете car элементов, вы получаете элементы номер 2 и номер 4. - person Greg Hewgill; 08.10.2009

Вы можете немного изменить это, чтобы вместо использования <xsl:apply-templates/> сделать что-то вроде этого:

<tr><td>number</td><td>make</td><td>color</td></tr>
<xsl:for-each select="/vehicle/car">
  <tr>
    <td><xsl:value-of select="position()" /></td><td>...</td>
  </tr>
</xsl:for-each>

В этом случае функция position() будет ссылаться на номер итерации связанного цикла for-each. Это может дать вам то, что вы ищете.

person Greg Hewgill    schedule 08.10.2009
comment
Это был бы мой предпочтительный метод. Просто мне было лень его печатать. - person ChaosPandion; 08.10.2009

Минимальное изменение:

<xsl:stylesheet 
  version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns="http://www.w3.org/1999/xhtml"
>
  <xsl:template match="/vehicle">
    <html>
      <body>
        <table cellpadding="5" border="1">
          <tr>
            <td>number</td>
            <td>make</td>
            <td>color</td>
          </tr>
          <xsl:apply-templates select="car" />
        </table>
      </body>
    </html>
  </xsl:template>

  <xsl:template match="car">
    <tr>
      <td><xsl:value-of select="position()" /></td>
      <td><xsl:value-of select="make" /></td>
      <td><xsl:value-of select="color" /></td>
    </tr>
  </xsl:template>

</xsl:stylesheet>

Обратите внимание на атрибут select="car" на <xsl:apply-templates>. Он следит за тем, чтобы учитывались только <car> узлов, поэтому ваш position() не выключен.

Также обратите внимание, что основной шаблон теперь соответствует элементу документа, а не корневому узлу.

person Tomalak    schedule 08.10.2009