【问题标题】:How to find the level of a specific Node如何找到特定节点的级别
【发布时间】:2014-10-08 13:52:18
【问题描述】:

我的 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::*) &gt;= (count(ancestor::node[@id = $menuId]) - X) 的内容

谢谢。

【问题讨论】:

    标签: xml xslt xmlnode


    【解决方案1】:

    我认为解决此问题的最有效方法是将计数参数向下传递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>
    

    【讨论】:

    • 谢谢@Ian。我缺少的是这个 targetDepth。这正是我需要的。抱歉,我不能投票。 :)
    • @Adriano 请注意,要使其工作,项目 ID 必须 是唯一的 - 如果有两个不同的 item 元素具有相同的 ID,那么 targetDepth 将结束是它们各自深度的总和
    • 我知道。我完全意识到这一点,并且已经告诉我的团队它必须是独一无二的。谢谢。
    猜你喜欢
    • 2017-03-14
    • 2023-03-21
    • 2018-06-22
    • 2016-02-17
    • 2014-07-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多