2014-02-10 77 views
0

這裏是我的基本結構:爲什麼這個基本的XPath選擇不工作

<div id="PrimaryContentBlock"> 
    <form> 
     ...... 

我試圖選擇表單中的元素,但XPath是沒有找到任何過去的primarycontentblock股利。

第一個查詢找到父節點,但第二個查詢找不到任何東西。

$dom->query('//*[@id="PrimaryContentBlock"]'); 
$dom->query('//*[@id="PrimaryContentBlock"]/form'); 

任何想法爲什麼XPath會變得如此奇怪?使用DOMXPath查詢時,我看到很多不一致的行爲。

+2

你可能有命名空間的問題。檢查結構中是否提到默認名稱空間(如xmlns =「...「) –

+1

你能展示更多的HTML結構嗎?你從哪裏得到它? – Robin

回答

0

鑑於你有上述的結構,並且要確保該文件是良好形成既您查詢WILL工作:

$xml = <<<EOF 
<div id="PrimaryContentBlock"> 
    <form></form> 
</div> 
EOF; 

$doc = new DOMDocument(); 
$doc->loadHTML($xml); 
$selector = new DOMXPath($doc); 

foreach($selector->query('//*[@id="PrimaryContentBlock"]/form') as $element) { 
    echo $element->nodeName; 
} 

輸出:

form 

如果以下句子對您適用:

使用DOMXPath查詢時,我看到很多不一致的行爲。

...那麼你對XPath沒有足夠的專業知識,或者你的輸入數據格式不正確。至少有一個原因適用於我,當我遇到某個查詢時遇到問題時。

1

這種情況發生的一種方式是,如果您有一個XHTML文檔(在根html元素上有xmlns錯位),並且您將其解析爲XML。在這樣的文檔中,所有元素都是http://www.w3.org/1999/xhtml名稱空間的一部分,您需要在查詢時指定此名稱。

你的第一個查詢,//*[@id="PrimaryContentBlock"],會發現任何元素與匹配id屬性,包括那些在XHTML命名空間(這是什麼*手段)。第二個查詢//*[@id="PrimaryContentBlock"]/form正在尋找form元素而不是在任何名稱空間中。這與文檔不匹配,因爲所有form元素都在默認的XHTML名稱空間中。

解決這個問題的最簡單方法是,如果這是一個XHTML文檔,則將其解析爲HTML。如果您目前正在做的事情,如:

$domdocument->loadXML(...); 

改變其使用loadHTML

$domdocument->loadHTML(...); 

如果你想解析文檔的XML,那麼你需要在查詢中指定命名空間。首先,你需要與DOMXPath實例register the namespace uri and prefix you are going to use,然後更改您的查詢,包括新的前綴:

$xpath = new DOMXPath($doc); 
$xpath->registerNamespace('xhtml', "http://www.w3.org/1999/xhtml"); 

$result = $xpath->query('//*[@id="PrimaryContentBlock"]/xhtml:form') 
+1

試試這個'// * [@ id =」PrimaryContentBlock「]/* [local-name()='form']'。If它的工作原理,然後它是一個命名空間問題 –

+0

謝謝亞特和lwburk的命名空間技巧。我懷疑命名空間可能是由於我一直經歷的一些不一致的責任,目前的錯誤是由於我自己的疏忽。以前文檔的初始XPath對象,但未重置我嘗試查詢的新文檔的DOM的XPath。 –

相關問題