我如何解析部分HTML?

时间:2009-12-19 17:46:52

标签: php html dom parsing

我正在尝试用PHP解析一些带有DOM的HTML,但我遇到了一些问题。首先,如果这改变了解决方案,我所拥有的HTML不是一个完整的页面,而是它只是它的一部分。

<!-- This is the HTML that I have --><a href='/games/'>
<div id='game'>
<img src='http://images.example.com/games.gif' width='300' height='137' border='0'>
<br><b> Game </b>
</div>
<div id='double'>
<img src='http://images.example.com/double.gif' width='300' height='27' border='0' alt='' title=''>
</div>
</a>

现在我正在尝试只获取ID为double的div。我已经尝试了以下代码,但它似乎没有正常工作。我可能做错了什么?

//The HTML has been loaded into the variable $html
$dom=new domDocument;
$dom->loadHTML($html);
$dom->preserveWhiteSpace = false; 
$keepme = $dom->getElementById('double'); 

$contents = '<div style="text-align:center">'.$keepme.'</a></div>';
echo $contents;

5 个答案:

答案 0 :(得分:13)

我认为DOMDocument::getElementById不适用于您的情况:(引用)

  

要使此功能起作用,您将会这样做   需要设置一些ID属性   使用DOMElement::setIdAttribute或a   定义属性的DTD   类型ID。
在后一种情况下,你   需要验证您的文档   与DOMDocument::validate或   DOMDocument->validateOnParse之前   使用此功能。


可能有效的解决方案是使用一些XPath query来提取您要查找的元素。

首先,让我们像你第一次一样加载HTML部分:

$dom=new domDocument;
$dom->loadHTML($html);
var_dump($dom->saveHTML());

var_dump只是为了证明HTML部分已经成功加载 - 从它的输出来看,它有。


然后,实例化DOMXPath类,并使用它来查询您想要获取的元素:

$xpath = new DOMXpath($dom);
$result = $xpath->query("//*[@id = 'double']");
$keepme = $result->item(0);

我们现在必须要你想要的元素; - )


但是,为了将HTML内容注入另一个HTML段,我们必须首先获取其HTML内容。

我不记得任何“简单”的方法,但这样的事情可以做到这一点:

$tempDom = new DOMDocument();
$tempImported = $tempDom->importNode($keepme, true);
$tempDom->appendChild($tempImported);
$newHtml = $tempDom->saveHTML();
var_dump($newHtml);

而且......我们拥有您double <div>

的HTML内容
string '<div id="double">
<img src="http://images.example.com/double.gif" width="300" height="27" border="0" alt="" title="">
</div>
' (length=125)


现在,你只需要随心所欲地做任何事情; - )

答案 1 :(得分:3)

来自DomDocument::getElementById

  

要使此功能起作用,您将会这样做   需要设置一些ID属性   使用DOMElement :: setIdAttribute或a   定义属性的DTD   类型ID。在后一种情况下,你   需要验证您的文档   使用DOMDocument :: validate或   DOMDocument-&gt; validateOnParse之前   使用此功能。

了解更多信息

因为有人会迟早会提到使用正则表达式,所以这是您可以使用的模式:/<div id='double'>(.*)<\/div>/simU

此外,您可以使用常规字符串函数来提取div部分,例如

$div = strstr($html, '<div id="double">');
$div = substr($div, 0, strpos($div, '</div>') + 6);
echo $div;

虽然我同意,你不应该使用RegEx或String函数进行解析 HTML或XML,我觉得这样做是绝对可以的,只要您唯一关心的是获取这个来自片段的单个div 。保持简单。

答案 2 :(得分:0)

HTML Tidy应该能够“纠正”破碎和碎片化的HTML文档,将它们变成可以用其他工具解析的东西

http://devzone.zend.com/article/761

  

Tidy扩展是PHP 5中的新增功能,   并可从PHP版本获得   5.0b3向上。它基于TidyLib库,并允许   开发人员验证,修复和   解析HTML,XHTML和XML文档   来自PHP内部。

答案 3 :(得分:0)

XML文档在根级别只能有一个元素。也许,HTML解析器有类似的要求。尝试将内容包装在<body/>标记中。

似乎是别的东西。 This page描述了可能的原因。我建议您使用XPath来获取元素。

答案 4 :(得分:-1)

片段是HTML,但是要通过DOM解析它应该是XHTML。 每个开放标签都必须关闭。

在您的情况下,这意味着您应该将<br>替换为<br />,将<img ... >替换为<img ... />