我使用以下内容将一个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,以便它可以使用新添加的元素?
提前致谢! :)
答案 0 :(得分:1)
在保存并加载方法中,您还可以尝试Document.normalizeDocument
。这应该将文档修复为好像已经保存循环,而实际上没有真正的序列化。应该做的一件事是重新计算文档类型的isID
- 属性,您希望将其设置为HTML文档类型之一(通过id
将loadHTML
定义为值类型ID的属性。
(还有Element.setIdAttribute
可以用来声明Attr
的一个实例来包含一个ID,但这对你没用,因为你必须先得到它。 )
我没有对此进行过测试,如果PHP没有正确实现这个DOM Level 3 Core的话,我也不会感到惊讶。根据我对the spec for isId
的解释,我认为它应该已经自动获取了id
类型定义。 (我自己的DOM实现肯定会。)但是在那种情况下你的代码会起作用。我认为appendXML
毕竟是一种非标准的方法,所以没有什么可说的,它必须解决像loadXML
或loadHTML
这样的类型定义。
所以,也许解决方法是更好的计划。您可以使用DOMXPath按@id
属性选择元素,而不是真实ID。当然,这将比getElementById
慢得多,但希望比normalizeDocument
更快。
或者只是丢失XML字符串,并坚持使用DOM方法,如果可以的话;那么保持对创建元素的引用是微不足道的。 (如果您发现DOM方法对于您正在创建的内容量过于冗长,则可以使用辅助函数来更快地创建元素。)
答案 1 :(得分:0)
我所知道的唯一可以解决这个问题的方法就是......美妙的是蟒蛇的美味汤。 DOM全部拆分成一个解析树,您可以随意添加或删除它,您可以编写一个python脚本来处理html,然后通过数据库或系统调用来协调脚本。或者服务器端javascript可能值得调查。