简体   繁体   English

如何在扩展DOMElement的自定义类中设置新的HTML标记(在php中使用DOMDocument)?

[英]How to set new HTML tag in custom class that extends DOMElement (using DOMDocument in php)?

I need a fast HTML parser, written in php. 我需要一个用php编写的快速HTML解析器。 First I've tried some existing parsers (like Ganon or QueryPath) but they were very slow for my project. 首先,我尝试了一些现有的解析器(例如Ganon或QueryPath),但对于我的项目而言它们非常慢。 Finally I've decided to use the php built-in DOMDocument, being the fastest of all. 最终,我决定使用php内置的DOMDocument,它是最快的。 It has just some bare methods. 它只有一些裸露的方法。 So I had to start to build my own. 所以我不得不开始建立自己的。

I'm writing a class thats extends DOMElement. 我正在编写扩展DOMElement的类。 New methods like 'addText' are working fine but I have a problem when I want to change the tag name. 像“ addText”这样的新方法可以正常工作,但是当我想更改标签名称时遇到了问题。

In order to change the tag name, the node has to be replaced. 为了更改标签名称,必须替换节点。 It is another node. 这是另一个节点。 After this any further actions will not affect the node anymore. 此后,任何其他操作将不再影响该节点。

UPDATE: For now, I've added a return $newNode; 更新:现在,我已经添加了一个return $newNode; in the newTag method and I'm using it like this: $node = $node->newTag('h1'); 在newTag方法中,我像这样使用它: $node = $node->newTag('h1'); but for consistency I would really like to use just: $node->newTag('h1'); 但是为了保持一致,我真的只想使用: $node->newTag('h1');

Please see the code (simplified): 请查看代码(简体):

        <?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();

This code will output <div><h1>123</h1></div> As you can see, the text 345 was not added after I have changed the tag name. 这段代码将输出<div><h1>123</h1></div>如您所见,更改标签名称后,未添加文本345

What can be done in order to continue to work with the selected node? 为了继续与所选节点一起工作,可以做什么? Is it possible to set the new node as the current node in the 'newTag' method? 是否可以在“ newTag”方法中将新节点设置为当前节点?

The ideal solution would be DOMDocument::renameNode() , but it isn't available in PHP yet. 理想的解决方案是DOMDocument::renameNode() ,但是PHP尚不可用。

Perhaps this would work instead, called as $node = $node->parentNode->renameChild($node, 'h1') : 也许这可以代替工作,称为$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;
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM