我需要一个快速的 HTML 解析器,用 php 编写。首先,我尝试了一些现有的解析器(如 Ganon 或 QueryPath),但它们对我的项目来说非常慢。最后我决定使用 php 内置的 DOMDocument,它是最快的。它只有一些简单的方法。所以我不得不开始建立自己的。
我正在编写一个扩展 DOMElement 的类。像“addText”这样的新方法运行良好,但是当我想更改标签名称时出现问题。
为了更改标签名称,必须替换节点。它是另一个节点。在此之后,任何进一步的操作将不再影响节点。
更新:现在,我return $newNode;
在 newTag 方法中添加了一个,我正在使用它:$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”方法中将新节点设置为当前节点?