2016-11-28 31 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