如何查找特定节点的级别

时间:2014-10-08 13:52:18

标签: xml xslt xmlnode

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

我应用一些规则来获取特定节点。没关系。但是现在我需要从选定的menuId

获得上面的X(这个数字可以变化)级别

例如。如果X级别编号为2且menuId为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)之类的内容

感谢。

1 个答案:

答案 0 :(得分: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>