1

我需要以最简单的方式检索一个节点的最大深度(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

是否有可能在不使用 PHP 编写复杂算法的情况下做到这一点?

谢谢

4

1 回答 1

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::*) 从该元素评估。

选择所有叶元素的 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::*)
于 2012-05-10T12:43:12.033 回答