2009-11-17 2 views
0

Я создал рекурсивный шаблон для получения первого числа элементов из моего XML.xsl рекурсивный узел цикла по индексу

Он использует индекс (счетчик), как и в цикле for. Теперь, как я могу получить узел из моего XML с помощью индекса?

Я попытался [position() = $ index], но у него было странное поведение при попытке получить более глубокие узлы в иерархии XML.

Если у меня есть XML, такие как:

<0> 
<1> 
    <2>item</2> 
    <2>item</2> 
    <2>item</2> 
    <2>item</2> 
    <2>item</2> 
    <2>item</2> 
</1> 
</0> 

Я хочу, чтобы иметь возможность рассчитывать до конца и скопировать 2-х, пока у меня столько, сколько я хочу.

ответ

0

Я бы использовал < xsl: for-each ... > наряду с позицией() вместо рекурсии.

+0

Извинения - слепо дал тот же ответ, как и ты, не обращая внимания. –

0

Я не совсем понимаю, зачем вам нужен рекурсивный шаблон для этого. Для этого вы можете использовать < xsl: для каждого >. (я изменил название элемента, чтобы сделать его законным) Например:

<xsl:variable name='n' select='10'/> 
<xsl:for-each select='two[position() &lt; $n]'> 
    <!-- do whatever you need to do --> 
</xsl:for-each> 

Вы можете использовать выберите атрибут вы хотите, и вы могли бы включать в себя < XSL: сортировать > в наличии для каждого, если ваш вклад более сложный, чем ваш пример.

+0

Извините, может быть, я должен был добавить еще одну деталь. Я действительно хочу, чтобы выводить элементы в группах, я хочу обобщить группы до их вывода. Но сначала мне нужно сгруппировать их в дерево фрагментов, чтобы я мог выполнять функции в каждой группе. Это то, что у меня есть цикл. Так что мне просто нужно получить соответствующий узел в соответствии с индексом. Или это невозможно? Я ноб. – Ben

+0

Вы используете XSLT версии 1 или 2? XSLT 2.0 сделает это намного проще, чем я подозреваю - в XSLT 2.0 есть группировки операторов, в которых вам нужно перевернуть свои собственные в 1.0 –

1

Вы говорите, что хотите обрабатывать свои элементы в группах по n. Следующий XSLT 1.0 решение делает это:

<xsl:stylesheet 
    version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
> 
    <xsl:param name="pGroupCount" select="3" /> 

    <xsl:template match="/lvl-0"> 
    <xsl:copy> 
     <!-- select the nodes that start a group --> 
     <xsl:apply-templates mode="group" select=" 
     lvl-1/lvl-2[position() mod $pGroupCount = 1] 
     " /> 
    </xsl:copy> 
    </xsl:template> 

    <xsl:template match="lvl-2" mode="group"> 
    <!-- select the nodes belong to the current group --> 
    <xsl:variable name="current-group" select=" 
     . | following-sibling::lvl-2[position() &lt; $pGroupCount] 
    " /> 
    <!-- output the current group, you can also do calculations with it --> 
    <group id="{position()}"> 
     <xsl:copy-of select="$current-group" /> 
    </group> 
    </xsl:template> 
</xsl:stylesheet> 

При применении этого входного документа:

<lvl-0> 
<lvl-1> 
    <lvl-2>item.0</lvl-2> 
    <lvl-2>item.1</lvl-2> 
    <lvl-2>item.2</lvl-2> 
    <lvl-2>item.3</lvl-2> 
    <lvl-2>item.4</lvl-2> 
    <lvl-2>item.5</lvl-2> 
    <a>foo</a><!-- to prove that position() calculations still work --> 
    <lvl-2>item.6</lvl-2> 
    <lvl-2>item.7</lvl-2> 
    <lvl-2>item.8</lvl-2> 
    <lvl-2>item.9</lvl-2> 
</lvl-1> 
</lvl-0> 

Следующий вывод генерируется:

<lvl-0> 
    <group id="1"> 
    <lvl-2>item.0</lvl-2> 
    <lvl-2>item.1</lvl-2> 
    <lvl-2>item.2</lvl-2> 
    </group> 
    <group id="2"> 
    <lvl-2>item.3</lvl-2> 
    <lvl-2>item.4</lvl-2> 
    <lvl-2>item.5</lvl-2> 
    </group> 
    <group id="3"> 
    <lvl-2>item.6</lvl-2> 
    <lvl-2>item.7</lvl-2> 
    <lvl-2>item.8</lvl-2> 
    </group> 
    <group id="4"> 
    <lvl-2>item.9</lvl-2> 
    </group> 
</lvl-0> 

Чтобы понять это, вы должны знать, как position() работает. При использовании, как это:

lvl-1/lvl-2[position() mod $pGroupCount = 1] 

это относится к положению lvl-2 узлов в пределах их родителя (!). В этом случае, есть только один из родителей, поэтому item.0 имеет позицию 1 и item.9 имеет позицию 10.

При использовании, как это:

following-sibling::lvl-2[position() &lt; $pGroupCount] 

это относится к относительному положению вдоль оси following-sibling::. В этом контексте item.1 будет иметь относительное положение 1 в отношении item.0. (В принципе, это то же самое, что и выше, который только подсчитывает вдоль (неявной) child:: оси.)

При использовании самостоятельно, как здесь:

<group id="{position()}"> 

это относится к позиции из текущий узел в пакете, который обрабатывается в данный момент.В нашем случае «партия» состоит из узлов, которые начинают группу (item.0, item.3, item.6, item.9), поэтому она идет от 1 до 4.