简单的html dom的Xpath无法获取标签的text()

时间:2015-01-16 07:10:25

标签: php xpath

我希望获得主div的内容而不再有任何标签,例如我想废弃" Winter Skate由Harvard Pilgrim HealthCare带给您,提供白天和晚上的公共滑冰,是客舱发烧的完美补救措施这个冬天。 "从给定的代码。我使用xpath和简单的html dom,这是我的代码

foreach($dom->find('//*[@id="main"]/text()[1]') as $element){
    $details=$element;
}

但它既没有得到任何元素也没有进入foreach。 你能告诉我任何解决方案吗?

<div id="main">
    <div>a</div>
    <div>b</div>
    <div>c</div>
    <a name="abc"></a>Winter Skate brought to you by Harvard Pilgrim HealthCare, offering day and evening public skating, is the perfect remedy to cabin fever this winter.<br />
    <br />
    A fun and affordable activity for parents with children, Winter Skate is also an ideal lunch break getaway and a romantic addition to a dinner date at Patriot Place. <br />
    <br />
    The 60-by-140-foot, refrigerated ice surface is designed specifically for recreational skating and the professional surface is large enough to accommodate beginners and experts alike.<br />
    <br />
    On-site skate rentals, concessions and bathrooms are available and parking is free.<br />
    <br />
    <br />
    <b>Concessions</b><br />
    Dunkin Donuts will be on-site with coffee, hot chocolate and donuts available for purchase. Additionally, Patriot Place features 16 dining and quick service restaurants including: Bar Louie, Baskin Robbins, Blue Fin Lounge, CBS Scene, Davio’s, Five Guys Burgers, Godiva, Olive Garden, Qdoba, Red Robin, Skipjack’s, Studio 3, Tastings Wine Bar & Bistro, Tavolino Pizza Gourmet, Twenty8 Food & Spirits.<br />
    <br />
    NOTE: Hours may occasionally vary due to inclement weather, Patriots home games, or pre-scheduled private events – please check back or call 508-203-2100<br><br>
    <a name='hours' class='ranchor'></a>
</div>

1 个答案:

答案 0 :(得分:1)

SimpleHtmlDom没有实现官方的W3C DOM Api。它使用CSS选择器,而不是XPath。 CSS选择器不能用于选择文本节点,它们只匹配元素节点。

您可以使用PHP标准的原生DOM扩展:

$dom = new DOMDocument();
@$dom->loadHtml($html);

$xpath = new DOMXPath($dom);
var_dump(
  $xpath->evaluate('string(//*[@id="main"]/text()[normalize-space() != ""][1])')
);

输出:

string(149) "Winter Skate brought to you by Harvard Pilgrim HealthCare, offering day and evening public skating, is the perfect remedy to cabin fever this winter."

[normalize-space() != ""]是一个过滤仅包含空格的节点的条件。

string()将结果列表中的第一个节点转换为字符串,避免了循环的需要。

DOMDocument::loadHTML()DOMDocument::loadHTMLFile()尝试修复无效的html源代码。例如,如果它们不存在,则会添加htmlbody。这可以更改HTML,因此最好将HTML保存回字符串以获取新结构:

$html = <<<'HTML'
<div id="main" class="one" class="two">
    <div>a</div>
    <div>b</div>
    <div>c</div>
    <a name="abc"></a>Winter Skate brought to you by ...
HTML;

$dom = new DOMDocument();
@$dom->loadHtml($html);
echo $dom->saveHtml();

输出:

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
<html><body><div id="main" class="one">
    <div>a</div>
    <div>b</div>
    <div>c</div>
    <a name="abc"></a>Winter Skate brought to you by ...</div></body></html>

此外,@阻止HTML解析中的错误和警告。这在大多数情况下都有效,但更好的方法是使用libxml函数并处理/记录错误:

$dom = new DOMDocument();
libxml_use_internal_errors(TRUE);
$dom->loadHtml($html);

var_dump(libxml_get_errors());

输出:

array(1) {
  [0]=>
  object(LibXMLError)#2 (6) {
    ["level"]=>
    int(2)
    ["code"]=>
    int(42)
    ["column"]=>
    int(39)
    ["message"]=>
    string(26) "Attribute class redefined
"
    ["file"]=>
    string(0) ""
    ["line"]=>
    int(1)
  }
}

如果它报告一个空源,你需要检查DOMDocument :: loadHTMLFile是否可以获取它,尝试使用file_get_contents()来获取它。