2017-04-17 135 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

相关问题