如何在xpath 1.0中获得一个节点的最大深度

时间:2012-05-10 09:32:41

标签: php xpath

我需要以最简单的方式检索一个节点的最大深度(PHP 5,XPATH 1.0)

XML示例:

<node>
    <node id="nodeBase">
        <node>
            <node />
        </node>
        <node>
            <node>
                <node />
            </node>
        </node>
    </node>
</node>
  1. 我得到节点 nodeBase
  2. 执行XPATH查询以从 nodeBase获取最大深度
  3. 结果必须为3
  4. 如果没有在PHP中编写复杂的算法编码,是否可以做到这一点?

    谢谢

1 个答案:

答案 0 :(得分:1)

  

1.我得到节点nodeBase

     

2.执行XPATH查询以从nodeBase获取最大深度

     

3.结果必须是3如果没有在PHP中编写复杂的算法编码,是否有可能做到这一点?

与使用XPath 2.0不同,XPath 1.0中单个XPath表达式无法生成所需结果

最简单的解决方案将涉及来自宿主语言的一些计算(在本例中为PHP)。

  1. 您可以获取作为指定元素后代的所有叶元素。

  2. 对于每个人评估count(ancestor::*)然后在PHP中找到这些中的最大值。

  3. 最后,从找到的最大绝对深度中减去指定元素的深度,再次count(ancestor::*)评估此元素。

  4. 选择所有叶元素的XPath表达式(上面1.中需要)是

    //node[@id='nodeBase']//*[not(*)]
    

    此算法的XSLT 1.0实现

    <xsl:stylesheet version="1.0"
     xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
     <xsl:output method="text"/>
     <xsl:strip-space elements="*"/>
    
     <xsl:template match="/">
         <xsl:variable name="vBase" select="//*[@id='nodeBase']"/>
    
         <xsl:for-each select="$vBase//*">
          <xsl:sort select="count(ancestor::*)" data-type="text" order="descending"/>
    
          <xsl:if test="position() = 1">
           <xsl:value-of select="count(ancestor::*) - count($vBase/ancestor::*)"/>
          </xsl:if>
         </xsl:for-each>
     </xsl:template>
    </xsl:stylesheet>
    

    在提供的XML文档上应用此转换时:

    <node>
        <node id="nodeBase">
            <node>
                <node />
            </node>
            <node>
                <node>
                    <node />
                </node>
            </node>
        </node>
    </node>
    

    产生了想要的正确结果

    3
    

    通过这个,您可以了解如何在PHP中实现该算法。

    为了完整起见,这是一个产生相同结果的单个XPath 2.0表达式

     max((//*[@id='nodeBase'])[1]//*[not(*)]/count(ancestor::*))
    -
     (//*[@id='nodeBase'])[1]/count(ancestor::*)