2014-10-08 54 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

相关问题