2016-11-28 4 views
1

Я только начинаю с XSLT, так что несите меня. Я обрабатываю довольно сложный документ со структурой, подобной той, что приведена ниже. Он разделен на две секции: data и meta. Для каждого data/item мне нужно найти «фактический» класс в соответствующем meta/item.XPath: выбор из набора узлов, возвращаемых функцией

<root> 
    <data> 
    <item id="i1"> 
     <h3 id="p2">akkakk</h3> 
     <p id="p3">osijaoid</p> 
     <p id="p4">jqidqjwd</p> 
    <item> 
    </data> 
    <meta> 
    <item ref="i1"> 
     <p ref="p2" class="heading"/> 
     <p ref="p3" class="heading"/> 
     <p ref="p4" class="body"/> 
    </item> 
    </meta> 
</root> 

мне нужно сгруппировать смежные p элементы meta на их атрибута класса. Я думал, что вспомогательная функция может сделать это немного более чистым:

<xsl:function name="fn:node-groups" as="node()*"> 
    <xsl:param name="parent"/> 
    <xsl:variable name="nodeRefs" select="root($parent)//meta/item[@ref = $parent/@id]/p"/> 
    <xsl:for-each-group select="$nodeRefs" group-adjacent="@class"> 
    <group class="{@class}"> 
     <xsl:for-each select="current-group()"> 
     <node ref="{@ref}"/> 
     </xsl:for-each> 
    </group> 
    </xsl:for-each-group> 
</xsl:function> 

И затем используйте его при обработке узлов данных, например. Моя проблема в том, что я не могу выбрать дальше от набора узлов, возвращаемых функцией.

<xsl:template match="//data/item"> 
    <!-- works --> 
    <xsl:variable name="test1" select="fn:node-groups(.)"/> 
    <!-- works --> 
    <xsl:variable name="test2" select="fn:node-groups(.)/*"/> 
    <!-- does not work --> 
    <xsl:variable name="test3" select="fn:node-groups(.)/group[@class = 'heading']"/> 
</xsl:template> 

I может написать звезду в test2, и это дает мне все node узлы. Но все остальное просто дает мне пустой набор узлов. Или, по крайней мере, это выглядит так, но на данный момент я действительно не знаю больше.

ответ

1

Я полагаю, ваша таблица стилей имеет декларацию сферу xmlns="http://example.com/foo" пространства имен для функции, которая помещает результат элементы в функции в этом пространстве имен, а затем, очевидно, fn:node-groups(.)/group не будет выбирать их, как он выбирает group элемента не имен. Поэтому убедитесь, что ваша функция переопределяет это пространство имен с помощью <xsl:for-each-group select="$nodeRefs" group-adjacent="@class" xmlns="">.

Другая причина может заключаться в том, что ваша таблица стилей определяет xpath-default-namespace.

Я также думаю, что ваша третья переменная должна быть <xsl:variable name="test3" select="mf:node-groups(.)/node"/>, как очевидно, последовательность узлов, возвращенный функцией уже является последовательность group элементов, если вы хотите, чтобы фильтровать эту последовательность затем использовать <xsl:variable name="test3" select="fn:node-groups(.)[@class = 'heading']"/>

+0

Спасибо! Проблема заключалась, конечно, в том, что мне нужно было выбрать 'fn: node-groups (.)/[@ Class = 'heading']' вместо 'fn: node-groups (.)/Group [@class = 'heading' ] '. Иногда вы застреваете и нуждаетесь в подталкивании в правильном направлении, чтобы иметь возможность продолжать. – svenax

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

  • Нет связанных вопросов^_^