如何使用'htmlParseEntityRef:no name'错误加载HTMLFile()?

时间:2013-06-27 20:31:05

标签: html dom xpath php

我正试图将字符串“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:http://gisapps.co.union.nc.us/ws/rest/v2/cm_iw.ashx?gid=12339中没有名字,第1行:/ home ...在线......

其中指loadHTMLFILE行。

注意:该文件无效HTML只包含div个标签!我加载了什么文件,然后在其上打了HTML body标签?

4 个答案:

答案 0 :(得分:8)

如果确实必须尝试解析它,请尝试以下操作:

<?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)没有任何孩子..所以你需要修改它。

答案 1 :(得分:3)

只需从源代码构建一个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
*/

答案 2 :(得分:3)

您收到错误是因为您加载的HTML包含&字符而不是有效的HTML实体。该实体的名称正在酝酿:

... <td>HINSON J MARK & WF LOU ANN G</td> ...
                      ^

在加载此类文档时,您会在这些情况下看到错误(如您所写):

  

警告:DOMDocument :: loadHTMLFile():htmlParseEntityRef:没有名字

nameHTML Entity (reference)的名称相关,格式为:

&name;
 ^^^^

但是,此错误不会导致实际加载该HTML的任何问题。 DOMDocument可以处理这个(常见的)错误(但是你可能会遇到a cut-off at the problematic position)。

因此,您假设需要将该文件包装到<body>标记中是错误的。在HTML中,<body>标记是可选的。

您的具体问题是,在加载之后,您无法理解如何调试HTML文件。只需使用saveHTML method输出可以成功加载的内容。这样做会向您显示,URL已成功加载。

然后会引导您到Xpath表达式错误的那一点:

*/div[@class='owner-name']

虽然你对<body>标签的看法并不遥远:即使那个HTML片段不包含<body>标签,DOM也会拥有它!虽然它里面有两个标签:

body/*/*/div[@class='owner-name']

通常,简短形式是使用//,这样就无法明确表达标签所处的深度级别:

//div[@class='owner-name']

参见:

答案 3 :(得分:1)

远程站点可能会返回导致此警告的无效HTML。在HTML错误的情况下,DOMDocumentDOMXPath非常宽容。如果在调用DOMDocument::loadHTML()之后只有一个警告并且其余代码产生了有效结果,我建议您使用静默运算符@来抑制警告:

$doc = new DOMDocument();

// suppress warnings
$ret = @$doc->loadHTML($html);

// but check errors ...
if($ret === FALSE) {
    die('Parse error');
}