PHP DOM - 访问新添加的节点

时间:2009-11-14 02:21:18

标签: php dom

我使用以下内容将一个html文档导入DOM:

$dom = new domDocument('1.0', 'utf-8');
$dom->loadHTML($html)

然后我将一些新内容添加到html中的元素:

$element = $dom->getElementById('mybox');
$f = $dom->createDocumentFragment();
$f->appendXML('<div id="newbox">foo</div>');
$element->appendChild($f);

但如果我现在想要操纵#newbox,我就无法做到,因为我无法使用getElementById()访问它。为了做到这一点,我必须执行以下操作(使用新的html重新加载):

$html = $dom->saveHTML();
$dom->loadHTML($html)

哪种方法很好,但是当必须在每次dom操作之间执行此操作时,它会在性能方面变得昂贵。

有没有更好的方法来“刷新”DOM,以便它可以使用新添加的元素?

提前致谢! :)

2 个答案:

答案 0 :(得分:1)

在保存并加载方法中,您还可以尝试Document.normalizeDocument。这应该将文档修复为好像已经保存循环,而实际上没有真正的序列化。应该做的一件事是重新计算文档类型的isID - 属性,您希望将其设置为HTML文档类型之一(通过idloadHTML定义为值类型ID的属性。

(还有Element.setIdAttribute可以用来声明Attr的一个实例来包含一个ID,但这对你没用,因为你必须先得到它。 )

我没有对此进行过测试,如果PHP没有正确实现这个DOM Level 3 Core的话,我也不会感到惊讶。根据我对the spec for isId的解释,我认为它应该已经自动获取了id类型定义。 (我自己的DOM实现肯定会。)但是在那种情况下你的代码会起作用。我认为appendXML毕竟是一种非标准的方法,所以没有什么可说的,它必须解决像loadXMLloadHTML这样的类型定义。

所以,也许解决方法是更好的计划。您可以使用DOMXPath@id属性选择元素,而不是真实ID。当然,这将比getElementById慢得多,但希望比normalizeDocument更快。

或者只是丢失XML字符串,并坚持使用DOM方法,如果可以的话;那么保持对创建元素的引用是微不足道的。 (如果您发现DOM方法对于您正在创建的内容量过于冗长,则可以使用辅助函数来更快地创建元素。)

答案 1 :(得分:0)

我所知道的唯一可以解决这个问题的方法就是......美妙的是蟒蛇的美味汤。 DOM全部拆分成一个解析树,您可以随意添加或删除它,您可以编写一个python脚本来处理html,然后通过数据库或系统调用来协调脚本。或者服务器端javascript可能值得调查。