
Question:
I would like to add a child, on a very specific place (so I'm also using DOM and not only simpleXML) for <domain:create>
node.
I have tried to use the $ns attribute on simpleXML construct.
$nsNode = new SimpleXMLElement('<domain:ns>', $options = 0, $ns='urn:ietf:params:xml:ns:domain-1.0'); //transform the target into dom object for manipulation $nodeRegistrantDom = dom_import_simplexml($nodeRegistrant);
But I'm getting:
I/O warning : failed to load external entity
"<domain:ns>"
I've tried to register the prefix after creating the element, but I use no xpath after this, so this was quite a useless try...
//creates the simpleXML object node to be inserted. $nsNode = new SimpleXMLElement('<ns/>'); //this will not work, because we will not use xpath after it :s $nsNode->registerXPathNamespace('domain', 'urn:ietf:params:xml:ns:domain-1.0');
Since the xml is loaded from a file, and that file as this ns declared, maybe we should grab it from that file?
Here is an overall of the above, so that we can better understand the context: We are loading a XML file that contains an overall structure:
$xmlObj = simplexml_load_file('EppCreateDomain.xml');
They we will grab an element that we will use as a target:
//grab the target. $nodeRegistrant = $xmlObj->command->create->children(self::OBJ_URI_DOMAIN)->create->registrant; //transform the target into a dom object for later manipulation $nodeRegistrantDom = dom_import_simplexml($nodeRegistrant); //we try to use simpleXML to create the node that we want to add after our target. $nsNode = new SimpleXMLElement('<domain:ns>'); //grabs the node and all his children (none in this case), by importing the node we want to add, //into the root object element that contains the <domain:registrant> node. $nsNodeDom = $nodeRegistrantDom->ownerDocument->importNode(dom_import_simplexml($nsNode), true); $nodeRegistrantDom->parentNode->insertBefore($nsNodeDom, $nodeRegistrantDom->nextSibling); $simpleXmlNsNode = simplexml_import_dom($nsNodeDom);
Now we have our node placed on a proper place. And converted to simpleXML so, we can now easily add some children and fill the rest of the xml file..
$hostAttr = $simpleXmlNsNode->addChild('domain:hostAttr'); $hostName = $hostAttr->addChild('domain:hostName');
Please advice, MEM
Solution:1
<?php // test document, registrant as first/last element and somewhere in between $xmlObj = new SimpleXMLElement('<epp> <domain:create xmlns:domain="urn:someurn"> <domain:name></domain:name> <domain:registrant></domain:registrant> <domain:contact></domain:contact> </domain:create> <domain:create xmlns:domain="urn:someurn"> <domain:name></domain:name> <domain:contact></domain:contact> <domain:registrant></domain:registrant> </domain:create> <domain:create xmlns:domain="urn:someurn"> <domain:registrant></domain:registrant> <domain:name></domain:name> <domain:contact></domain:contact> </domain:create> </epp>'); foreach( $xmlObj->children("urn:someurn")->create as $create ) { $registrant = $create->registrant; insertAfter($registrant, 'domain:ns', 'some text'); } echo $xmlObj->asXML(); function insertAfter(SimpleXMLElement $prevSibling, $qname, $val) { $sd = dom_import_simplexml($prevSibling); $newNode = $sd->ownerDocument->createElement($qname, $val); $newNode = $sd->parentNode->insertBefore($newNode, $sd->nextSibling); return simplexml_import_dom($newNode); }
prints
<?xml version="1.0"?> <epp> <domain:create xmlns:domain="urn:someurn"> <domain:name/> <domain:registrant/><domain:ns>some text</domain:ns> <domain:contact/> </domain:create> <domain:create xmlns:domain="urn:someurn"> <domain:name/> <domain:contact/> <domain:registrant/><domain:ns>some text</domain:ns> </domain:create> <domain:create xmlns:domain="urn:someurn"> <domain:registrant/><domain:ns>some text</domain:ns> <domain:name/> <domain:contact/> </domain:create> </epp>
Solution:2
Since the xml is loaded from a file, and that file as this ns declared, maybe we should grab it from that file?
If that file is a XML file, yes, you should load the whole the file, not just a portion.
Once the namespace is declared, adding a namespaced element is easy:
<?php $xml = <<<XML <epp> <domain:create xmlns:domain="urn:someurn" xmlns:ietf="urn:thaturn"> <domain:name></domain:name> <domain:registrant></domain:registrant> <domain:contact></domain:contact> </domain:create> </epp> XML; $sxml = new SimpleXMLElement($xml); $sxml->children("domain", true)->create->addChild("newElem", "value", "urn:thaturn"); echo $sxml->saveXML();
gives
<?xml version="1.0"?> <epp> <domain:create xmlns:domain="urn:someurn" xmlns:ietf="urn:thaturn"> <domain:name/> <domain:registrant/> <domain:contact/> <ietf:newElem>value</ietf:newElem></domain:create> </epp>
Note:If u also have question or solution just comment us below or mail us on toontricks1994@gmail.com
EmoticonEmoticon