我正在尝试从以下位置获取字符串"hinson lou ann":
<div class='owner-name'>hinson lou ann</div>
当我运行以下内容时:
$html = "http://gisapps.co.union.nc.us/ws/rest/v2/cm_iw.ashx?gid=12339";
$doc = new DOMDocument();
$doc->loadHTMLFile($html);
$xpath = new DOMXpath($doc);
$elements = $xpath->query("*/div[@class='owner-name']");
if (!is_null($elements)) {
foreach ($elements as $element) {
echo "<br/>[" . $element->nodeName . "]";
$nodes = $element->childNodes;
foreach ($nodes as $node) {
echo $node->nodeValue . "'n";
}
}
}
我收到以下错误:
警告: DOMDocument::loadHTMLFile(( [domdocument.loadhtmlfile]: htmlParseEntityRef: no name in http://gisapps.co.union.nc.us/ws/rest/v2/cm_iw.ashx?gid=12339, line: 1 in/home...在线。。。
这是指loadHTMLFILE
线。
注意:该文件不是有效的 HTML,它只包含div
标签!我加载了文件,然后在上面打了 HTML body
标签是什么?
如果你真的必须尝试解析它,试试这个:
<?php
$html = file_get_contents("http://gisapps.co.union.nc.us/ws/rest/v2/cm_iw.ashx?gid=12339");
$doc = new DOMDocument();
$doc->strictErrorChecking = false;
$doc->recover=true;
@$doc->loadHTML("<html><body>".$html."</body></html>");
$xpath = new DOMXpath($doc);
$elements = $xpath->query("//*/div[@class='owner-name']");
if (!is_null($elements)) {
foreach ($elements as $element) {
echo "<br/>[". $element->nodeName. "]";
$nodes = $element->childNodes;
foreach ($nodes as $node) {
echo $node->nodeValue. "'n";
}
}
}
?>
PS:你的XPath错了,我修好了。你的$nodes
不会有任何东西,因为那个DIV元素(.owner-name
(没有任何子元素。所以你需要修改它。
只需从源代码构建一个 HTML 文档,将其包装在缺少的元素中应该可以解决问题。
例如:-
<?php
$html = file_get_contents('http://gisapps.co.union.nc.us/ws/rest/v2/cm_iw.ashx?gid=12339');
$html = sprintf('<html><head><title></title></head><body>%s</body></html>', $html);
$doc = new DOMDocument;
$doc->loadHTML($html);
$xpa = new DOMXPath($doc);
$divs = $xpa->query('//div[@class="owner-name"]');
foreach($divs as $div) {
echo $div->nodeValue, PHP_EOL;
}
/*
hinson lou ann
*/
您收到错误是因为您加载的 HTML 包含&
字符,而不是有效的 HTML 实体。实体的名称错误:
... <td>HINSON J MARK & WF LOU ANN G</td> ...
^
在加载此类文档时,您将在这些情况下看到一个错误(如您所写(:
警告:DOMDocument::loadHTMLFile((: htmlParseEntityRef: no name
该name
与 HTML 实体(引用(的名称相关,模式如下:
&name;
^^^^
但是,此错误不会导致实际加载该 HTML 的任何问题。DOMDocument可以很好地处理这个(常见(错误(但是,您可能会在有问题的位置遇到截止(。
因此,您需要将该文件包装到 <body>
标签中的假设是错误的。在 HTML 中,<body>
标记是可选的。
您的具体问题是您无法理解如何在加载HTML文件后对其进行调试。只需使用 saveHTML
方法输出可以成功加载的内容。这样做已经向您显示 URL 已成功加载。
然后,这将引导您到Xpath表达式错误的下一个点:
*/div[@class='owner-name']
尽管您对<body>
标签的鼻子并不遥远:即使该HTML片段不包含<body>
标签,DOM也会拥有它!尽管里面有两个标签:
body/*/*/div[@class='owner-name']
大多数情况下,缩写形式是使用//
,它允许不专门表达标签位于哪个深度级别:
//div[@class='owner-name']
另请参阅:
- 禁用通过 DomDocument 加载格式不正确的 HTML 时的警告 (PHP( 在
- PHP 中写入 xml 时从字符串中删除 &
远程站点可能会返回导致此警告的无效 HTML。 DOMDocument
和DOMXPath
在HTML错误的情况下非常宽容。如果在调用DOMDocument::loadHTML()
后只有一个警告,并且代码的其余部分产生有效的结果,我建议您使用静音运算符@
抑制警告:
$doc = new DOMDocument();
// suppress warnings
$ret = @$doc->loadHTML($html);
// but check errors ...
if($ret === FALSE) {
die('Parse error');
}