Adding child nodes using SimpleXML
I have an XML document and want to insert a new node at a specific spot using SimpleXML.
The original XML is this:
<epp
xmlns="urn:ietf:params:xml:ns:epp-1.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="urn:ietf:params:xml:ns:epp-1.0 epp-1.0.xsd"
>
<command>
<create>
<domain:create
xmlns:domain="urn:ietf:params:xml:ns:domain-1.0"
xsi:schemaLocation="urn:ietf:params:xml:ns:domain-1.0 domain-1.0.xsd"
>
<domain:period unit="y"></domain:period>
</domain:create>
</create>
</command>
</e开发者_运维百科pp>
after <domain:create>
I need to add the following node:
<domain:ns>
<domain:hostAttr>
<domain:hostName></domain:hostName>
<domain:hostAddr ip="v4"></domain:hostAddr>
</domain:hostAttr>
</domain:ns>
How can I do that? I have tried this:
$xmlObj = simplexml_load_file('myXMLFile.xml');
$nsNode = $xmlObj->command->create->children(self::OBJ_URI_DOMAIN)->create->addChild('domain:ns');
$hostAttr = $nsNode->addChild('domain:hostAttr');
$hostName = $hostAttr->addChild('domain:hostName');
$hostAddr = $hostAttr->addChild('domain:hostAddr');
$hostAddr->addAtribute('ip', 'v4');
On this first line, I'm getting this warning:
Warning: SimpleXMLElement::addChild() [simplexmlelement.addchild]: Cannot add child. Parent is not a permanent member of the XML tree
On the second line, and because of this, I'm getting:
Fatal error: Call to a member function addChild() on a non-object
Thanks in advance.
Additional notes: - The php version is higher then 5.1; - I have successfully added child nodes later on this same XML.
I cannot reproduce the first error
<?php
echo phpversion(), "\n";
// $xmlObj = simplexml_load_file('myXMLFile.xml');
$xmlObj = getDoc();
$nsNode = $xmlObj->command->create->children('urn:ietf:params:xml:ns:domain-1.0')->create->addChild('domain:ns');
$nsNode->addChild('foo', 'Mary had a little lamb...');
echo $xmlObj->asxml();
function getDoc() {
return new SimpleXMLElement('<epp
xmlns="urn:ietf:params:xml:ns:epp-1.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="urn:ietf:params:xml:ns:epp-1.0 epp-1.0.xsd"
>
<command>
<create>
<domain:create
xmlns:domain="urn:ietf:params:xml:ns:domain-1.0"
xsi:schemaLocation="urn:ietf:params:xml:ns:domain-1.0 domain-1.0.xsd"
>
<domain:period unit="y"></domain:period>
</domain:create>
</create>
</command>
</epp>');
}
prints
5.3.2
<?xml version="1.0"?>
<epp xmlns="urn:ietf:params:xml:ns:epp-1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:ietf:params:xml:ns:epp-1.0 epp-1.0.xsd">
<command>
<create>
<domain:create xmlns:domain="urn:ietf:params:xml:ns:domain-1.0" xsi:schemaLocation="urn:ietf:params:xml:ns:domain-1.0 domain-1.0.xsd">
<domain:period unit="y"/>
<domain:ns><domain:foo>Mary had a little lamb...</domain:foo></domain:ns></domain:create>
</create>
</command>
</epp>
You want the child added to <create>
.
$nsNode = $xmlObj->command->create->addChild('domain:ns');
The children()
method returns a filtered list of child nodes. This list is - just as the error message indicates - not a permanent member of the document tree, it cannot be added to.
Adding a child works on the respective parent element only, or the operation would not be called "addChild", but "addSibling" - and this is not how the concept of the DOM works.
PS: Your second error message ("Call to a member function on a non-object") is the result of regular sloppiness. You can't just use an object without checking that it is actually there, your code lacks this check:
if ($nsNode !== null) {
$hostAttr = $nsNode->addChild('domain:hostAttr');
$hostName = $hostAttr->addChild('domain:hostName');
$hostAddr = $hostAttr->addChild('domain:hostAddr');
$hostAddr->addAttribute('ip', 'v4');
} else {
echo "Oops, addChild() failed!";
}
精彩评论