PHP で書かれた高速な HTML パーサーが必要です。まず、いくつかの既存のパーサー (Ganon や QueryPath など) を試しましたが、私のプロジェクトでは非常に低速でした。最後に、最も高速な php 組み込み DOMDocument を使用することにしました。いくつかの裸のメソッドしかありません。だから私は自分自身を構築し始めなければなりませんでした。
DOMElement を拡張するクラスを作成しています。「addText」などの新しいメソッドは正常に機能していますが、タグ名を変更したい場合に問題が発生します。
タグ名を変更するには、ノードを置き換える必要があります。別のノードです。この後、それ以上のアクションはノードに影響しません。
更新: 今のところreturn $newNode;
、 newTag メソッドに a を追加し、次のように使用しています:$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」メソッドで新しいノードを現在のノードとして設定することは可能ですか?