2017-04-17 42 views
0

考慮下面的代碼:爲什麼這個DOMXpath查詢合併了兄弟節點值?

$html = "<h1>foo</h1><h2>bar</h2>"; 
$document = new DOMDocument(); 
$document->loadHTML($html, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD); 
$xpath = new DOMXPath($document); 
$h1Nodes = $xpath->query('//h1'); 
foreach ($h1Nodes as $h1Node) { 
    var_dump($h1Node->nodeValue); 
} 

H1標籤只包含文本節點與文本「富」。文本「欄」位於兄弟標題節點(h2)中。我期望輸出是'foo'。

但是,輸出是'foobar'。

爲什麼?

+2

'LIBXML_HTML_NOIMPLIED'用於關閉隱含的html/body ...元素的自動添加。所以,如果您添加'LIBXML_HTML_NOIMPLIED',那麼您必須在您的html中添加''標籤。如果您刪除了'LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD'然後你的輸出如預期。 –

回答

0

謝謝你的評論,hardik solanki

它讓我回答:有效的標記必須有一個根元素。

標記,我已經提供了沒有,標記我已經使用防止庫隱式添加一個。所以第一個標籤被視爲一個根元素,結果有點混亂。

刪除這些標誌有助於解決此問題,但我將其用於某個目的。我只想操縱HTML的片段,而不是整個文檔。我想通過調用DOMDocument::saveHTML()得到這個片段(轉換後)。沒有文檔類型/ <html>/<body>標籤。

我已經結束了這樣做:

  • 我添加的doctype/<html>/<body>標記HTML片段我想manipluate有臨時有效證件
  • 負荷將其與DOM文檔
  • 改造它,我需要
  • 保存它DOMDocument::saveHTML()
  • 擺脫過多的doctype的方式/ <html>/<body>標籤標記

它的工作原理。

+1

你正在做DOM自己做的東西。如果使用'loadHTML()'而不使用選項,它會添加html/body標籤(就像@hardik solanki所說的那樣)。並且您可以提供節點saveHTML()來僅保存body元素的子節點。 'foreach($ xpath-> evaluate('// body/*')as $ node)$ result。= $ document-> saveHtml($ node);' – ThW

+0

你說得對。感謝您的評論。 – Luigi