0

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」メソッドで新しいノードを現在のノードとして設定することは可能ですか?

4

1 に答える 1

1

理想的なソリューションはDOMDocument::renameNode()ですが、PHP ではまだ利用できません。

おそらく、これは次のように呼び出されて代わりに機能し$node = $node->parentNode->renameChild($node, 'h1')ます。

<?php

class MyDOMNode extends DOMNode {
    public function renameChild($node, $name) {
        $newNode = $this->ownerDocument->createElement($name);

        foreach ($node->attributes as $attribute) {
            $newNode->setAttribute($attribute->name, $attribute->value);
        }

        while ($node->firstChild) {
            $newNode->appendChild($node->firstChild);
        }

        $this->replaceChild($newNode, $node);

        return $newNode;
    }
}
于 2013-11-07T00:10:44.073 に答える