2016-11-28 74 views
1

我刚开始使用XSLT,请耐心等待。我正在处理一个相当复杂的文档,其结构与下面的结构类似。它分为两个部分,datameta。对于每个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> 

我需要组中meta相邻p元件在其类别属性。我认为帮助功能可以使这个有点清洁:

<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> 

可以写一个明星为test2,这给了我所有node节点。但其他任何东西只是给我一个空的节点集。或者至少看起来是这样,但在这一点上,我真的不知道了。

回答

1

我想你的样式表具有用于把结果元素的功能在命名空间,那么很明显,因为它选择在没有命名空间的元素groupfn:node-groups(.)/group不选择它们的功能的xmlns="http://example.com/foo"命名空间声明范围。因此,请确保您的函数使用<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