2012-05-10 55 views
1

我需要检索的最大深度为最简单的方法一个节点(PHP 5,XPATH 1.0)XML的如何获得最大深度为一个节点的XPath 1.0

例子:

<node> 
    <node id="nodeBase"> 
     <node> 
      <node /> 
     </node> 
     <node> 
      <node> 
       <node /> 
      </node> 
     </node> 
    </node> 
</node> 
  1. 我得到的节点nodeBase
  2. XPath查询的执行从nodeBase
  3. 获得最大深度
  4. 结果必须是3

有可能做到这一点无需编码在PHP中一个复杂的算法?

谢谢

回答

1

1.I得到XPath查询的节点nodeBase

2.Execution摆脱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::*) 
+0

由于它的工作原理,但它是一个遗憾,XPATH2.0不存在PHP ... – Epharion

+0

@ Epharion:我们需要展示大多数开发人员需要XPath 2.0(和XSLT 2.0)的编程语言供应商。目前XPath 3.0即将成为W3C官方建议书(它处于“最后通话”状态) - 这意味着PL供应商在游戏中很晚 - 他们仍然没有实施2.0。 –