How can I change the prefix of the root element of an XML with PHP using DomDocument or SimpleXML or any other library?
I tried like this:
$xml = new \SimpleXMLElement($content, \LIBXML_PARSEHUGE, false, "p", true);
or
$dom = new \DOMDocument();
$response = $dom->loadXML($content);
$root = $dom->documentElement;
$root->setAttributeNS(
'http://www.w3.org/2000/xmlns/',
'xmlns:p',
'p'
);
But it doesn't seem to work as expected.
The results that I expect should be:
<p:rootElement>
<other>tag</other>
</p:rootElement>
CodePudding user response:
I'm not sure that you would be able to modify the root node as you are trying to do here. The namespace URI should be http://www.w3.org/2000/xmlns/p
if it is p
that you are trying to use as the prefix and you would use p:root
as the qualifiedName but that would result in the root node being modified like this <root xmlns:p="http://www.w3.org/2000/xmlns/p" p:root="p"/>
A possible alternative approach to get the output you seek might be to add a new node - append all the child nodes from the original root to it and delete the original. Admittedly it is hacky
and a better solution might well exist...
Given the source XML as:
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<root>
<domain>cdiinvest.com.br</domain>
<domain>savba.sk</domain>
<domain>laboratoriodiseno.cl</domain>
<domain>upc.ro</domain>
<domain>nickel.twosuperior.co.uk</domain>
<domain>hemenhosting.org</domain>
<domain>hostslim.eu</domain>
</root>
Then, to modify the source XML:
# local XML source file
$file='xml/netblock.xml';
# new node namespace properties
$nsuri='http://www.w3.org/2000/xmlns/p';
$nsname='p:root';
$nsvalue=null;
# create the DOMDocument and load the XML
libxml_use_internal_errors( true );
$dom=new DOMDocument;
$dom->formatOutput=true;
$dom->validateOnParse=true;
$dom->preserveWhiteSpace=false;
$dom->strictErrorChecking=false;
$dom->recover=true;
$dom->load( $file );
libxml_clear_errors();
# create the new root node
$new=$dom->createElementNS( $nsuri, $nsname, $nsvalue );
$dom->appendChild( $new );
# find the original Root
$root=$dom->documentElement;
# iterate backwards through the childNodes - inserting into the new root container in the original order
for( $i=$root->childNodes->length-1; $i >= 0; $i-- ){
$new->insertBefore( $root->childNodes[ $i ],$new->firstChild );
}
# remove original root
$root->parentNode->removeChild( $root );
# save the XML ( or, as here, print out modified XML )
printf('<textarea cols=80 rows=10>%s</textarea>', $dom->saveXML() );
Which results in the following output:
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<p:root xmlns:p="http://www.w3.org/2000/xmlns/p">
<domain>cdiinvest.com.br</domain>
<domain>savba.sk</domain>
<domain>laboratoriodiseno.cl</domain>
<domain>upc.ro</domain>
<domain>nickel.twosuperior.co.uk</domain>
<domain>hemenhosting.org</domain>
<domain>hostslim.eu</domain>
</p:root>
CodePudding user response:
The root element is the root element. You change it by creating a new document with the root element of your choice.
If the the job is left to import all root elements children from another document, then be it (SimpleXML is not that fitting for that, DOMDocument is, see DOMDocument::importNode
and mind the $deep
flag).
If you don't actually want to change the root element but rewrite the XML then XMLReader
/ XMLWriter
is likely what you're looking for.
(This is not entirely clear with your question as it misses the input document of the example)
Compare as well with the reference Q&A How do you parse and process HTML/XML in PHP?.