2013-07-08 133 views
4

這是我的XML(片段):遍歷XML樹來獲得屬性值

<?xml version="1.0" encoding="utf-8"?> 
<test> 
    <body label_position="left"> 
    <page number="1"> 
     <itemset name=""> 
     <item name="" id="1" /> 
     <item name="" id="2" label_position="right" /> 
    </itemset> 
    </page> 
    </body> 
</test> 

我想做到:
是否<item id="1">label_position屬性設置?
(1)如果是,請將其退回。
(2)如果沒有,請檢查節點的父節點是否屬於該屬性。 (3)如果父母具有該屬性,則返回該屬性。
(4)如果不是,則轉到步驟(2)。 <body>是要檢查的「最舊」節點。

我已經試過什麼:
我使用simplexmlxpath,我試圖選擇<item>及其所有祖先,然後向上遍歷樹並與label_position第一次出現停止。

$xml->xpath("//item[@id='1']::ancestors-or-self/@label_position"); 

產生了invalid expression

(1)如何獲得此表達式的工作方式?
(2)這可以通過「xpath-only」完成 - 無需遍歷樹並執行搜索?

編輯:感謝choroba & dirkk,我可以把它在一起:

$test = (string)array_reverse($xml->xpath("//item[@id='2']/ancestor-or-self::*/@label_position"))[0]; 

說明:如果兩個<item><body>具有屬性,xpath將返回這兩個值的數組,第一個是<body>。在這種情況下,我想先獲得<item>,這就是爲什麼array_reverse()

看到它的工作:http://codepad.viper-7.com/jDPIde

回答

2

你應該更加小心的XPath語法。你表達的正確形式是

//item[@id='1']/ancestor-or-self::*/@label_position 

謂詞後,您不能使用::,和你有一個軸後指定::

+0

謝謝,作品像一個魅力! – michi

2

您的XPath無效。軸步驟必須位於元素名稱的前面,例如類似axis::node,而不是其他方式。

以下應該工作。你的邏輯已經是xpath-only,遍歷樹是完全正確的。

(//item[@id='1']/ancestor-or-self::*/@label_position)[last()] 
+0

雖然'/ data()'產生了一個「無效表達式」,但沒有它,它就像一個魅力。謝謝! – michi

+0

@michi我更新了我的XPath以反映編輯中的更改。你可以單獨使用XPath來完成,不需要使用'array_reverse' – dirkk

+0

真的很棒!確實需要額外的行才能轉換爲字符串,但請參閱http://codepad.viper-7.com/NflXLz – michi