2014-10-08 57 views
0

我的XML:如何找到一個特定節點的水平

<menu> 
    <item id=1> 
    <item id=1.1> 
     <item id=1.1.1> 
     <item id=1.1.1.1> 
     <item id=1.1.1.2> 
     <item id=1.1.1.3> 
     </item> 
    </item> 
    <item id=1.2> 
     <item id=1.2.1> 
     <item id=1.2.1.1> 
     <item id=1.2.1.2> 
     <item id=1.2.1.3> 
     </item> 
    </item> 
    </item> 
</menu> 

我的XSLT:

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/> 
<xsl:strip-space elements="*"/> 

<xsl:param name="menuId"/> 

<xsl:template match="*"> 
    <xsl:if test="descendant-or-self::*[@id=$menuId]"> 
     <xsl:copy> 
      <xsl:copy-of select="@*"/> 
      <xsl:apply-templates /> 
     </xsl:copy> 
    </xsl:if> 
</xsl:template> 

<xsl:template match="item"> 
    <xsl:if test="descendant-or-self::*[@id=$menuId] | 
           parent::*[@id=$menuId] | 
           preceding-sibling::*[@id=$menuId] | 
           following-sibling::*[@id=$menuId] | 
           preceding-sibling::*/child::*[@id=$menuId] | 
           following-sibling::*/child::*[@id=$menuId]"> 
    <xsl:copy> 
      <xsl:copy-of select="@*"/> 
     <xsl:apply-templates select="item"/> 
    </xsl:copy> 
    </xsl:if> 
</xsl:template> 


</xsl:stylesheet> 

我申請了一些規則,得到的只是一個特定節點。沒關係。但現在我需要從選擇菜單Id

例如得到的只是X(此數可能有所不同)以上的水平。如果X級別數爲2和菜單Id爲1.1.2.3的結果將是:

<menu> 
    <item id=1.1> 
     <item id=1.1.1> 
     <item id=1.1.1.1> 
     <item id=1.1.1.2> 
     <item id=1.1.1.3> 
     </item> 
    </item> 
    <item id=1.2> 
    </item> 
</menu> 

如果X級數爲1,結果將是:

<menu> 
     <item id=1.1.1> 
     <item id=1.1.1.1> 
     <item id=1.1.1.2> 
     <item id=1.1.1.3> 
     </item> 
</menu> 

爲了得到當前我會使用count(ancestor::*)。但我不知道如何獲取節點[@id = $ menuId]級別。 我需要包括我的IF

由於裏面的東西一樣count(ancestor::*) >= (count(ancestor::node[@id = $menuId]) - X)

回答

0

最有效的方法我能想到接近,這將是通過計數參數下來apply-templates鏈:

<xsl:variable name="targetDepth" select="count(//item[@id=$menuId]/ancestor::item)" /> 
<!-- I haven't thought this through in great detail, it might need a +1 --> 

<xsl:template match="item"> 
    <xsl:param name="depth" select="0" /> 
    .... 
    <xsl:if test=".... and ($targetDepth - $depth) &lt;= $numLevels"> 
    <xsl:copy> 
     <xsl:copy-of select="@*"/> 
     <xsl:apply-templates select="item"> 
     <xsl:with-param name="depth" select="$depth + 1" /> 
     </xsl:apply-templates> 
    </xsl:copy> 
    </xsl:if> 
</xsl:template> 
+0

感謝@Ian。對於我來說缺少的是這個目標。這正是我需要的。對不起,但我不能投票。 :) – Adriano 2014-10-08 14:44:14

+0

@Adriano注意,這個工作的項目IDS _must_是唯一的 - 如果有兩個不同的'item'具有相同ID的元素,然後'targetDepth'最終會是它們各自的深度的_sum_。 – 2014-10-08 16:16:55

+0

我知道。我完全意識到這一點,並已告知我的團隊它必須是獨一無二的。謝謝。 – Adriano 2014-10-08 16:44:57

相關問題