我需要一个快速的HTML解析器,用PHP编写。首先,我尝试了一些现有的解析器(如Ganon或QueryPath),但它们对于我的项目来说非常缓慢。最后我决定使用php内置的DOMDocument,这是所有内容中最快的。它只有一些裸露的方法。所以我不得不开始建立我自己的。如何在扩展DOMElement的自定义类中设置新的HTML标记(在PHP中使用DOMDocument)?
我正在写一个扩展DOMElement的类。像'addText'这样的新方法工作正常,但当我想要更改标签名称时遇到问题。
为了更改标签名称,节点必须被替换。这是另一个节点。在此之后,任何进一步的操作不会再影响节点。
更新:现在,我已经添加在newTag方法return $newNode;
和我使用这样的:$node = $node->newTag('h1');
但一致性我真的想只需使用:$node->newTag('h1');
请参阅代码(简化):
<?php
class my_element extends DOMElement {
public function __construct() { parent::__construct();}
public function newTag($newTagName) {
$newNode = $this->ownerDocument->createElement($newTagName);
$this->parentNode->replaceChild($newNode, $this);
foreach ($this->attributes as $attribute) {
$newNode->setAttribute($attribute->name, $attribute->value);
}
foreach (iterator_to_array($this->childNodes) as $child) {
$newNode->appendChild($this->removeChild($child));
}
//at this point, $newnode should become $this... How???
}
//append plain text
public function addText ($text = '') {
$textNode = $this->ownerDocument->createTextNode($text);
$this->appendChild($textNode);
}
//... some other methods
}
$html = '<div><p></p></div>';
$dom = new DOMDocument;
$dom->loadHTML($html);
$xPath = new DOMXPath($dom);
$dom->registerNodeClass("DOMElement", "my_element"); //extend DOMElement class
$nodes = $xPath->query('//p'); //select all 'p' nodes
$node = $nodes->item(0); // get the first
//Start to change the selected node
$node->addText('123');
$node->newTag('h1');
$node->addText('345'); //This is not working because the node has changed!
echo $dom->saveHTML();
此代码将输出<div><h1>123</h1></div>
正如你所看到的,文字345
未添加后,我改变了标签名。
要继续使用选定节点可以做些什么?是否可以将新节点设置为'newTag'方法中的当前节点?
是的,这是一个可行的解决方案。请参阅我的更新。但是你认为不是使用'$ node = $ node-> newTag('h1');'有任何解决方案使它工作只是'$ node-> newTag('h1');'?不知怎的,没有'return $ newNode;'。 – Victor
据我所知,不使用'DOMDocument :: renameNode()'。 –