【发布时间】:2011-11-06 23:07:19
【问题描述】:
假设您有一个带有嵌套标签的 DOM 树,我想通过删除重复项来清理 DOM 对象。但是,这应该只适用于标签只有一个子标签的情况同类型。例如,
修复 <div><div>1</div></div> 而不是 <div><div>1</div><div>2</div></div>。
我试图弄清楚如何使用PHP's DOM extension 来做到这一点。以下是起始代码,我正在寻求帮助以找出所需的逻辑。
<?php
libxml_use_internal_errors(TRUE);
$html = '<div><div><div><p>Some text here</p></div></div></div>';
$dom = new DOMDocument;
$dom->preserveWhiteSpace = false;
$dom->formatOutput = true;
$dom->loadHTML($html);
function dom_remove_duplicate_nodes($node)
{
var_dump($node);
if($node->hasChildNodes())
{
for($i = 0; $i < $node->childNodes->length; $i++)
{
$child = $node->childNodes->item($i);
dom_remove_duplicate_nodes($child);
}
}
else
{
// Process here?
}
}
dom_remove_duplicate_nodes($dom);
我收集了一些帮助函数,这些函数可能会使处理 DOM 节点(如 JavaScript)变得更容易。
function DOM_delete_node($node)
{
DOM_delete_children($node);
return $node->parentNode->removeChild($node);
}
function DOM_delete_children($node)
{
while (isset($node->firstChild))
{
DOM_delete_children($node->firstChild);
$node->removeChild($node->firstChild);
}
}
function DOM_dump_child_nodes($node)
{
$output = '';
$owner_document = $node->ownerDocument;
foreach ($node->childNodes as $el)
{
$output .= $owner_document->saveHTML($el);
}
return $output;
}
function DOM_dump_node($node)
{
if($node->ownerDocument)
{
return $node->ownerDocument->saveHTML($node);
}
}
【问题讨论】:
-
我没有时间提供更详细的答案,但我认为使用正则表达式会更快更容易!
-
@janoliver,我无法想象一个正则表达式复杂到足以将节点级别考虑在内。
-
看在上帝的份上,除非绝对没有其他选择,否则不要使用正则表达式来解析 XML。如果您有格式错误的标记,请尝试使用 tidy 扩展来清理它,然后使用 DOM、SimpleXML 或 XMLReader 扩展来解析它。