2016-07-22 4 views
0

Попытка выяснить, как выбрать следующий узел XSLT-узла, когда узел был отсортирован в XSLT 1.0. Я искал, но не могу найти ничего для отсортированных узлов, так как он выбирает только брата из несортированного узла.Выбор следующего собора отсортированного узла

данных

<data> 
    <number order='4'>Four</number> 
    <number order='1'>One</number> 
    <number order='3'>Three</number> 
    <number order='2'>Two</number> 
</data> 

Код

<xsl:for-each select="/data/number"> 
    <xsl:sort select="@order"/> 
    <xsl:if test="position() mod 2 = 1"> 
     <xsl:value-of select="text()"/> 
     <xsl:text> - </xsl:text> 
     <xsl:value-of select="following-sibling::*/text()"/> 
    </xsl:if> 
</xsl:for-each> 

Ожидаемый результат

One - Two 
Three - Four 

Фактический выход

One - Three 
Three - Two 
+0

Можно попробовать использовать число мод (позиция()) 2 = 1 внутри теста. Поскольку position() вернет string.im не уверен, будет ли это работать, просто попробуйте –

ответ

1

При сортировке последовательности узлов вы получаете одни и те же узлы в новой последовательности. Поскольку они являются одними и теми же узлами, у них одинаковые братья и сестры, которые у них всегда были. Если вы копируете узлы в результирующее дерево, то копии будут иметь новых братьев и сестер, но это из-за действия записи их в дерево результатов, а не из-за действия сортировки.

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

Обработка упорядоченной последовательности узлов в XSLT 2.0 становится намного проще, что позволяет привязать такую ​​последовательность к переменной. XSLT 1.0 имеет только узловые множества, поэтому последовательности узлов в определенном порядке могут существовать только временно.

Но в данном случае, кажется, достаточно легко сделать

<xsl:value-of select="."/> 
<xsl:if test="position() mod 2 = 1"> 
    <xsl:text> - </xsl:text> 
</xsl:if> 
+0

Спасибо. Фактическая проблема, с которой я столкнулась, не была решена решением здесь, но вы ответили на мой вопрос о том, возможно ли то, что я пытался. Я отмечаю это как принятый ответ, поскольку он отвечает на вопрос, который я задал лучше всего. –

1

он выбирает только одноуровневый из несортированных узла.

Это верно. Почему бы вам не сделать просто:

<xsl:for-each select="/data/number"> 
    <xsl:sort select="@order"/> 
    <xsl:value-of select="."/> 
    <xsl:choose> 
     <xsl:when test="position() mod 2 = 1"> 
      <xsl:text>-</xsl:text> 
     </xsl:when> 
     <xsl:otherwise> 
      <xsl:text>&#10;</xsl:text> 
     </xsl:otherwise> 
    </xsl:choose> 
</xsl:for-each> 

Обратите внимание, что сортировки по умолчанию тип данных является text; вы, вероятно, захотите это сделать:

<xsl:sort select="@order" data-type="number"/> 
+0

Это работает для моего упрощенного примера, но фактическое место, где я пытаюсь использовать этот код, - это таблица html, которая не будет работать с теги строки таблицы разделены. Так что просто невозможно получить родного брата отсортированного узла в XSLT 1.0? –

+1

Если вам действительно нужно, чтобы они были братьями и сестрами, вы должны сначала скопировать их (или иным образом воссоздать их как новые узлы) в переменную. А в XSLT 1.0 вам также понадобится преобразовать эту переменную в набор узлов, прежде чем вы сможете ее обработать дальше. –

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