我有这个基本代码不起作用。如何将 Xpath 与 html5lib php 一起使用?或者以任何其他方式使用 HTML5 的 Xpath。
$url = 'http://en.wikipedia.org/wiki/PHP';
$response = GuzzleHttpget($url);
$html5 = new MastermindsHTML5();
$dom = $html5->loadHTML($response);
$xpath = new DOMXPath($dom);
$elements = $xpath->query('//h1');
//$elements = $dom->getElementsByTagName('h1');
foreach ($elements as $element)
{
var_dump($element);
}
未找到任何元素。使用$xpath->query('.')
可以获取根元素(xpath通常似乎有效(。 $dom->getElementsByTagName('h1')
正在工作。
使用disable_html_ns
选项。
$url = 'http://en.wikipedia.org/wiki/PHP';
$response = GuzzleHttpget($url)->getBody();
$html5 = new MastermindsHTML5(array(
'disable_html_ns' => true, // add `disable_html_ns` option
));
$dom = $html5->loadHTML($response);
$xpath = new DOMXPath($dom);
$elements = $xpath->query('//h1');
foreach ($elements as $element) {
var_dump($element);
}
https://github.com/Masterminds/html5-php#options
disable_html_ns
(布尔值(:防止解析器自动将 HTML5 命名空间分配给 DOM 文档。这适用于非命名空间感知的 DOM 工具。
所以看起来html5lib正在为我们设置一个默认的命名空间。
$url = 'http://en.wikipedia.org/wiki/PHP';
$response = GuzzleHttpget($url)->getBody();
$html5 = new MastermindsHTML5();
$dom = $html5->loadHTML($response);
$de = $dom->documentElement;
if ($de->isDefaultNamespace($de->namespaceURI)) {
echo $de->namespaceURI . "n";
}
这输出:
http://www.w3.org/1999/xhtml
若要使用 xpath 查询命名空间节点,需要注册命名空间并在查询中使用前缀。
$xpath = new DOMXPath($dom);
$xpath->registerNamespace('n', $de->namespaceURI);
$elements = $xpath->query('//n:h1');
foreach ($elements as $element)
{
echo $element->nodeValue;
}
这将输出PHP
.
通常,当涉及默认命名空间时,我发现在 xpath 查询中为所有内容添加前缀很乏味,所以我只是去掉它。
$de = $dom->documentElement;
$de->removeAttributeNS($de->getAttributeNode("xmlns")->nodeValue,"");
$dom->loadXML($dom->saveXML()); // reload the existing dom, now sans default ns
之后,您可以使用原始的xpath,它将正常工作。
$elements = $xpath->query('//h1');
foreach ($elements as $element)
{
echo $element->nodeValue;
}
现在这也输出PHP
。
因此,该示例的修改版本如下所示:
例:
$url = 'http://en.wikipedia.org/wiki/PHP';
$response = GuzzleHttpget($url)->getBody();
$html5 = new MastermindsHTML5();
$dom = $html5->loadHTML($response);
$de = $dom->documentElement;
if ($de->isDefaultNamespace($de->namespaceURI)) {
$de->removeAttributeNS($de->getAttributeNode("xmlns")->nodeValue,"");
$dom->loadXML($dom->saveXML());
}
$xpath = new DOMXPath($dom);
$elements = $xpath->query('//h1');
foreach ($elements as $element)
{
var_dump($element);
}
输出:
class DOMElement#11 (18) {
public $tagName =>
string(2) "h1"
public $schemaTypeInfo =>
NULL
public $nodeName =>
string(2) "h1"
public $nodeValue =>
string(3) "PHP"
...
public $textContent =>
string(3) "PHP"
}