如何使用DomDocument方法更改节点的根? [英] How to change root of a node with DomDocument methods?

查看:126
本文介绍了如何使用DomDocument方法更改节点的根?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何仅更改DOM节点的根标记名称?

How to only change root's tag name of a DOM node?

在DOM文档模型中,我们无法更改属性 documentElement DOMElement 对象,因此,我们需要重建节点...但是如何使用 childNodes进行重建 属性?

In the DOM-Document model we can not change the property documentElement of a DOMElement object, so, we need "rebuild" the node... But how to "rebuild" with childNodes property?

注意:我可以通过使用saveXML转换为字符串并通过正则表达式剪切根 ...但这是一种解决方法,而不是DOM解决方案。

NOTE: I can do this by converting to string with saveXML and cuting root by regular expressions... But it is a workaround, not a DOM-solution.

PHP例子(不起作用,但是为什么?):

PHP example (not works, but WHY?):

 // DOMElement::documentElement can not be changed, so... 

 function DomElement_renameRoot1($ele,$ROOTAG='newRoot') { 
    if (gettype($ele)=='object' && $ele->nodeType==XML_ELEMENT_NODE) {
   $doc = new DOMDocument();
   $eaux = $doc->createElement($ROOTAG); // DOMElement

       foreach ($ele->childNodes as $node)  
       if ($node->nodeType == 1)  // DOMElement 
               $eaux->appendChild($node);  // error!
       elseif ($node->nodeType == 3)  // DOMText
               $eaux->appendChild($node); // error!
       return $eaux;
    } else
        die("ERROR: invalid DOM object as input");
  }

appendChild($ node)导致错误:

 Fatal error: Uncaught exception 'DOMException' 
 with message 'Wrong Document Error'



Try-2



来自@can建议(仅指向链接)和我对可怜的 dom- domdocument-renamenode手册。

 function DomElement_renameRoot2($ele,$ROOTAG='newRoot') {
$ele->ownerDocument->renameNode($ele,null,"h1");
    return $ele;
 }

renameNode()方法导致错误,

The renameNode() method caused an error,

Warning: DOMDocument::renameNode(): Not yet implemented



Try-3



来自 PHP手册,注释1

 function renameNode(DOMElement $node, $newName)
 {
     $newNode = $node->ownerDocument->createElement($newName);
     foreach ($node->attributes as $attribute)
        $newNode->setAttribute($attribute->nodeName, $attribute->nodeValue);
     while ($node->firstChild)
        $newNode->appendChild($node->firstChild); // changes firstChild to next!?
     $node->ownerDocument->replaceChild($newNode, $node); // changes $node?
     // not need return $newNode; 
 }

replaceChild()方法导致错误,

The replaceChild() method caused an error,

Fatal error: Uncaught exception 'DOMException' with message 'Not Found Error'


推荐答案

由于尚未真正回答,您发现的错误未找到是由于 renameNode()您复制的函数。

As this has not been really answered yet, the error you get about not found is because of a little error in the renameNode() function you've copied.

有关在DOM中重命名不同元素的一些相关问题我也看到了这个问题,并且在我的答案中采用了该功能,但没有出现此错误:

In a somewhat related question about renaming different elements in the DOM I've seen this problem as well and used an adoption of that function in my answer that does not have this error:

/**
 * Renames a node in a DOM Document.
 *
 * @param DOMElement $node
 * @param string     $name
 *
 * @return DOMNode
 */
function dom_rename_element(DOMElement $node, $name) {
    $renamed = $node->ownerDocument->createElement($name);

    foreach ($node->attributes as $attribute) {
        $renamed->setAttribute($attribute->nodeName, $attribute->nodeValue);
    }

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

    return $node->parentNode->replaceChild($renamed, $node);
}

您可能已经在函数体的最后一行发现了它:使用-> parentNode 代替-> ownerDocument 。由于 $ node 不是文档的子级,因此您确实得到了错误。并且认为应该是错误的。而是使用parent元素在其中搜索要替换的子元素;)

You might have spotted it in the last line of the function body: This is using ->parentNode instead of ->ownerDocument. As $node was not a child of the document, you did get the error. And it also was wrong to assume that it should be. Instead use the parent element to search for the child in there to replace it ;)

到目前为止,PHP手册的用户注释中并未对此进行概述。请点击指向最初建议 renameNode()函数的博客文章的链接,您也可以在其下方找到提供此解决方案的注释。

This has not been outlined in the PHP manual usernotes so far, however, if you did follow the link to the blog-post that originally suggested the renameNode() function you could find a comment below it offering this solution as well.

无论如何,我的变体在这里使用略有不同的变量命名,并且在类型上更加不同。像PHP手册中的示例一样,它缺少处理名称空间节点的变体。我尚未预订最好的预订,例如创建一个处理它的附加功能,从节点上接管命名空间以重命名或在其他函数中显式更改命名空间。

Anyway, my variant here uses a slightly different variable naming and is more distinct about the types. Like the example in the PHP manual it misses the variant that deals with namespace nodes. I'm not yet booked what would be best, e.g. creating an additional function dealing with it, taking over namespace from the node to rename or changing the namespace explicitly in a different function.

这篇关于如何使用DomDocument方法更改节点的根?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆