如何找到一个特定节点的水平
问题描述:
我的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)
。
答
最有效的方法我能想到接近,这将是通过计数参数下来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) <= $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>
感谢@Ian。对于我来说缺少的是这个目标。这正是我需要的。对不起,但我不能投票。 :) – Adriano 2014-10-08 14:44:14
@Adriano注意,这个工作的项目IDS _must_是唯一的 - 如果有两个不同的'item'具有相同ID的元素,然后'targetDepth'最终会是它们各自的深度的_sum_。 – 2014-10-08 16:16:55
我知道。我完全意识到这一点,并已告知我的团队它必须是独一无二的。谢谢。 – Adriano 2014-10-08 16:44:57