2012-05-10 237 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。 –