2010-05-26 2 views
4

я файл XML какVariable приращение XSLT

<node> 
<elm val="data1"/> 
<elm val="data2"/> 
<elm val="data3"/> 
<elm val="data4"/> 
<elm val="data5"/> 
<elm val="data6"/> 
<elm val="data7"/> 
</node> 

мне нужно написать XSLT для этого XML-файла для отображения в таблице как

появляются две
1 dat1 
    2 dat2 
    3 dat3 
    4 dat4 
    5 dat5 
    6 dat6 
    7 dat7 

, пожалуйста, помогите мне сделать это

+0

Какой у вас XSLT? – Oded

+0

Хороший вопрос (+1). См. Мой ответ для правильного и полного решения. Поймите, почему решение Одеда ... НЕПРАВИЛЬНО. :) –

ответ

2
<xsl:tempate match="node"> 
    <table> 
    <xsl:call-template select="elm"/> 
    </table> 
</xsl:template> 

<xsl:template match="elm"> 
    <tr> 
    <td> 
     <xsl:value-of select="count(preceding-sibling::elm) + 1"/> 
    </td> 
    <td> 
     <xsl:value-of select="@val"/> 
    </td> 
    </tr> 
</xsl:template> 

в качестве альтернативы, если требуется точная Ouput использовать следующий шаблон для elm.

<xsl:template match="elm"> 
    <xsl:param name="pos" select="count(preceding-sibling::elm) + 1"/> 
    <tr> 
    <td> 
     <xsl:value-of select="$pos"/> 
    </td> 
    <td> 
     <xsl:text>dat</xsl:text> 
     <xsl:value-of select="$pos"/> 
    </td> 
    </tr> 
</xsl:template> 

Или в случае вывода текста:

<xsl:tempate match="node"> 
    <xsl:foreach select="elm"> 
    <xsl:value-of select="count(preceding-sibling::elm) + 1"/> 
    <xsl:text> dat</xsl:text> 
    <xsl:value-of select="count(preceding-sibling::elm) + 1"/> 
    <xsl:text disable-output-escaping="yes">&amp;#xA;</xsl:text> 
    </xsl:foreach> 
</xsl:template> 
0
<xsl:template match="node"> 
    <table> 
     <xsl:apply-templates select="elm"/> 
    </table> 
</xsl:template> 

<xsl:template match="elm"> 
    <tr> 
     <td><xsl:value-of select="position()"/></td> 
     <td>dat<xsl:value-of select="position()"/></td> 
    </tr> 
</xsl:template> 
+0

См. Здесь (http://www.dpawson.co.uk/xsl/sect2/N6099.html) по той причине, что позиция не идеальна. – AxelEckenberger

1

Вы можете использовать функцию position()

<xsl:template match="elm"> 
    <xsl:value-of select="concat(position(), ' ', @val)" /> 
</xsl:template> 

Примечание: Формат таблицы в вашем примере не совпадает со значением из атрибута val, но я предположил, что вы хотите, чтобы оба были одинаковыми (вывод первой строки shoul d be 1 data1 вместо 1 dat1.

Как отметил в своем ответе @Dimitre Novatchev, это предполагает, что ваш исходный документ не имеет узлов только в белом пространстве. В своем ответе он обращается к этому, удаляя все узлы «белого пространства» из входного документа (используя директиву <xsl:strip-space elements="*"/>) и добавляя новый символ строки (&#xA;) в конце конкатенации.

+2

См. Здесь (dpawson.co.uk/xsl/sect2/N6099.html) по той причине, что позиция не идеальна. – AxelEckenberger

+0

@Obalix - в этом случае 'position()' отлично, поскольку контекстным узлом является 'elm'. – Oded

+0

Почему downvote? 'position()' может быть неправильно понято некоторыми, но является совершенно прекрасной функцией для использования в определенных обстоятельствах, включая этот. – Oded

-1

XSLT «переменные» являются неизменными переменными. Как только вы их установите, вы не можете их произвольно изменить.

Единственные хаки вокруг него - использовать функцию position() и другие функции «+1», но вы не получаете гибкости истинной переменной.

Существует много статей о неизменяемости «переменных» XSLT.

Цитируя статью о «http://www.xml.com/pub/a/2001/02/07/trxml9.html»

XSLT переменные на самом деле имеют гораздо больше общего с константами во многих языках программирования и используются для подобных целей.

Счетчики в XSLT невозможны, поскольку XSLT не является процедурным языком, он декларативный. Для downvoter: пожалуйста, укажите причину. Если это не так, тогда, пожалуйста, докажите обратное.

2

Это неправильно:

<xsl:stylesheet version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output omit-xml-declaration="yes" indent="yes"/> 

<xsl:template match="elm"> 
    <xsl:value-of select="concat(position(), ' ', @val)"/> 
</xsl:template> 
</xsl:stylesheet> 

При запуске с большим количеством процессоров XSLT это будет производить следующее (нежелательный) вывод:

2 data1 
4 data2 
6 data3 
8 data4 
10 data5 
12 data6 
14 data7 

Причина заключается в том, что когда шаблоны применяются к дочерним элементам верхнего элемента, это включает в себя дочерние объекты, которые являются текстовыми узлами только в белом пространстве - между ev ery два последовательных elm элементов.

Таким образом, решение Одеда неверно.

Вот одно правильное решение (и один из самых коротких по возможности):

<xsl:stylesheet version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output method="text"/> 
    <xsl:strip-space elements="*"/> 

<xsl:template match="elm"> 
    <xsl:value-of select="concat(position(), ' ', @val, '&#xA;')"/> 
</xsl:template> 
</xsl:stylesheet> 

Это преобразование производит правильный результат:

1 data1 
2 data2 
3 data3 
4 data4 
5 data5 
6 data6 
7 data7 

Обратите внимание:

  1. Использование <xsl:strip-space elements="*"/> для управления процессором XSLT для удаления любых текстовых узлов только в белом пространстве.

  2. Использование функции XPath concat() для склеивания позиции, данных и символа NL.

Смежные вопросы