echo innerHTML,没有外部节点标签

Posted

技术标签:

【中文标题】echo innerHTML,没有外部节点标签【英文标题】:echo innerHTML, without outer node tags 【发布时间】:2013-05-26 07:04:51 【问题描述】:

我正在使用DOMDocument 类来解析一个相当不可预测的标记字符串。它的格式不是很好,我需要一些数据。当然,正则表达式是正确的。 到目前为止,我得到了这个:

$dom = new DOMDocument;
$dom->loadhtml($str);
$contents = $dom->getElementsByTagName('body')->item(0);
echo $dom->saveXML($contents);

现在这给了我:

<body>
    <p>What I'm really after</p>
    <ul><li>Foo</li><li>Bar</li></ul>
    <h6>And so on</h6>
</body>

真正让我烦恼的是那些&lt;body&gt; 标签。我要他们走。浏览网络后,我偶然发现了最奇怪的解决方法。有些人比其他人更hacky,所以最后,我选择了:

echo substr($dom->saveXML($contents), 6, -7);

我仍然觉得很老套,但这是我能找到的最好的了。有没有更可靠的方法来获取 DOM 的 innerHTML,从给定节点开始,而不实际显示相应的标签?

我已经看到使用正则表达式的建议(恕我直言),甚至循环遍历所有子节点,呼应那些拥有自己的 childNodes 的子节点,并将那些没有的子节点串在一起:

if ($contents->hasChildNodes())

    $children = $contents->getElementsByTagName('*');
    foreach($children as $child)
    
        if ($child->hasChildNodes() || $child->nodeName === 'br')
        //or isset($standaloneNodes[$child->nodeName])
            echo $dom->saveXML($child);
            continue;
        

        echo '<'.$child->nodeName.'>'.$child->nodeValue.'</'.$child->nodeName.'>';
    

但对我来说,这似乎更荒谬......

【问题讨论】:

&lt;body&gt; 标签是否始终存在?是否要删除所有标签? @Harsh:&lt;body&gt; 标签是由DOMDocument 添加的(连同一个doctype 和&lt;head&gt; 标签。我要做的就是解析HTML,所以我可以得到一些我需要的数据位,并返回标记的规范化版本 看看这个:***.com/questions/2087103/… @Harsh:我已经有了,与substr($dom-&gt;saveXML($contents), 6, -7);相比,那里的答案方式太低效了。 如果您追求速度,Kolink 的解决方案还不错:) 【参考方案1】:

导出 HTML 时,您必须有一个根元素。在大多数情况下,最有用的是body。由于您正在加载 HTML 片段,因此您肯定知道它不会有任何属性,因此 substr(...,6,-7) 是完全可预测且很好的。

【讨论】:

感谢您的快速回复。仍然感觉有点老套……无论如何:我已经完成了这一天的工作,但我回家后会接受你的回答。 是的,它很老套,但做得很好。虽然我害怕使用它,因为它的目的不透明。 :P @Harsh:这就是为什么我用过的所有编程语言都允许 cmets... @Harsh: 那和preg_replace('/^[^&gt;]+&gt;(.+)&lt;[^&gt;]+&gt;$/',$1',$dom-&gt;saveXML($contents));,理论上是在一行中剥离外部标签的更可靠的方法,调用Cthulu

以上是关于echo innerHTML,没有外部节点标签的主要内容,如果未能解决你的问题,请参考以下文章

创建/附加节点与innerHTML

JS text节点无innerHTML

如何使用 XPath 获取节点值/innerHTML?

获取不在另一个标签内的元素的 InnerHTML

获取元素节点

元素节点中内容的操作