XSLT 2.0 - зацикливание на переменной набора узлов, но нужно также обрабатывать другие элементы в цикле - PullRequest
0 голосов
/ 30 октября 2011

У меня есть такой XML-код:

<?xml version="1.0" encoding="UTF-8"?>

<nodes>
    <n c="value2"/>
    <n>Has a relation to node with value2</n>
    <n>Has a relation to node with value2</n>
    <n c="value"/>
    <n>Has a relation to node with value</n>
    <n c="value1"/>
    <n>Has a relation to node with value1</n>
</nodes>

Я сортирую все элементы, которые имеют атрибуты в переменной , затем перебираю эту переменную в для каждого цикла . Но в конце каждого цикла мне нужно вывести значение тех элементов, которые находятся ниже текущего обработанного элемента (в оригинальном XML) и не имеют атрибута.

Это означает: вызовите apply-templates для <n> без атрибута, но атрибут "select" attr. в apply-templates не работает, возможно потому, что я сейчас нахожусь в переменной loop .

Есть ли решение для этого? Спасибо

Вот XSL:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
    <xsl:template match="/">
        <xsl:apply-templates/>
    </xsl:template>

    <xsl:template match="nodes">

        <xsl:variable name="sorted">
            <xsl:for-each select="n[@c]">
                <xsl:sort select="@c"></xsl:sort>
                <xsl:copy-of select="."></xsl:copy-of>
            </xsl:for-each>
        </xsl:variable>

        <xsl:for-each select="$sorted/n">
            <xsl:value-of select="@c"></xsl:value-of>

            <xsl:apply-templates select="/nodes/n[2]"></xsl:apply-templates>
        </xsl:for-each>

    </xsl:template>

    <xsl:template match="n[not(@c)]">
        <xsl:value-of select="."></xsl:value-of>
    </xsl:template>

</xsl:stylesheet>

Это всего лишь пример, все это является частью более крупного проекта:)

Требуемый вывод с более сложным XPAth (теперь даже простой не работает):

Value
Has a relation to node with value
Value1
Has a relation to node with value1
Value2
Has a relation to node with value2
Has a relation to node with value2

Теперь немного понятнее?

1 Ответ

0 голосов
/ 30 октября 2011

Некоторые мысли: apply-templates без select обрабатывает дочерний узел текущего узла контекста; во входном примере элементы n вообще не имеют дочерних элементов. Кроме того, в вашей переменной вы делаете копию значения, вы создаете новые узлы, которые не имеют отношения к узлам во входной выборке. Поэтому, хотя я не уверен, что вы хотите достичь своей конструкции с применением шаблонов внутри for-each, не имеет смысла, учитывая введенный вами пример ввода и используемую переменную.

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

<xsl:template match="nodes">
  <xsl:for-each-group select="n" group-starting-with="n[@c]">
    <xsl:sort select="@c"/>
    <xsl:value-of select="@c"/>
    <xsl:apply-templates select="current-group() except ."/>
  </xsl:for-each-group>
</xsl:template>

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

[править] Теперь, когда вы опубликовали пример вывода, я публикую улучшенную версию моего предыдущего предложения:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">

<xsl:output method="text"/>

<xsl:template match="nodes">
  <xsl:for-each-group select="n" group-starting-with="n[@c]">
    <xsl:sort select="@c"/>
    <xsl:value-of select="@c"/>
    <xsl:text>&#10;</xsl:text>
    <xsl:apply-templates select="current-group() except ."/>
  </xsl:for-each-group>
</xsl:template>

<xsl:template match="n[not(@c)]">
   <xsl:value-of select="."/>
   <xsl:text>&#10;</xsl:text>
</xsl:template>

</xsl:stylesheet>

Когда я использую Saxon 9.3 и запускаю таблицу стилей для вашего последнего входного образца, результат будет следующим:

value
Has a relation to node with value
value1
Has a relation to node with value1
value2
Has a relation to node with value2
Has a relation to node with value2

Это то, о чем вы просили, я думаю, поэтому попробуйте этот подход с более сложным реальным вкладом.

...