0

Given a base $xml and a file containing a <something> tag with attributes, children and children of its children, I would like to append it as first child and all of its children as raw XML.

Original XML:

<root>
 <people>
 <person>
 <name>John Doe</name>
 <age>47</age>
 </person>
 <person>
 <name>James Johnson</name>
 <age>13</age>
 </person>
 </people>
</root>

XML in file:

<something someval="x" otherthing="y">
 <child attr="val" ..> { some children and values ... }</child>
 <child attr="val2" ..> { some children and values ... }</child>
 ...
</something>

Result XML:

<root>
 <something someval="x" otherthing="y">
 <child attr="val" ..> { some children and values ... }</child>
 <child attr="val2" ..> { some children and values ... }</child>
 ...
 </something>
 <people>
 <person>
 <name>John Doe</name>
 <age>47</age>
 </person>
 <person>
 <name>James Johnson</name>
 <age>13</age>
 </person>
 </people>
</root>

This tag would contain several children both direct and recursively, so it would not be practical to build the XML via the SimpleXML operations. Besides, keeping it in a file would result in lower maintenance costs.

Technically it would simply be prepending one child. The problem is that this child would have other children and so on.

On the PHP addChild page there's a comment that says:

$x = new SimpleXMLElement('<root name="toplevel"></root>');
$f1 = new SimpleXMLElement('<child pos="1">alpha</child>');
$x->{$f1->getName()} = $f1; // adds $f1 to $x

However, this does not seem to treat my XML as raw XML therefore causing &lt; and &gt; escaped tags to appear. Several warnings concerning namespaces seem to appear as well.

I suppose I could do a quick replace of such tags but I am not sure whether it could cause future problems and it certainly does not feel right.

Manually hacking the XML is not an option and neither is adding children one by one. Choosing a different library could be.

Any clues on how to get this working?

Thanks!

asked Jan 5, 2015 at 13:02
3
  • possible duplicate of SimpleXML how to prepend a child in a node? Commented Jan 5, 2015 at 13:05
  • My main problem is actually adding the raw XML, not the order where the code is added although it would be very desirable for the tag to be on top. The referenced question does not deal with such issue. I just edited my question title to reflect such difference. Commented Jan 5, 2015 at 13:07
  • I just edited my question to reflect the real issue. Commented Jan 5, 2015 at 13:18

1 Answer 1

0

I'm really not sure if that will work. Try this or downvote this, but I hope it helps. Using DOMDocument (Reference)

<?php
$xml = new DOMDocument();
$xml->loadHTML($yourOriginalXML);
$newNode = DOMDocument::createElement($someXMLtoPrepend);
$nodeRoot = $xml->getElementsByTagName('root')->item(0);
$nodeOriginal = $xml->getElementsByTagName('people')->item(0);
$nodeRoot->insertBefore($newNode,$nodeOriginal);
$finalXmlAsString = $xml->saveXML();
?>

Sometimes UTF-8 can make problems, then try this:

<?php
$xml = new DOMDocument();
$xml->loadHTML(mb_convert_encoding($yourOriginalXML, 'HTML-ENTITIES', 'UTF-8'));
$newNode = DOMDocument::createElement(mb_convert_encoding($someXMLtoPrepend, 'HTML-ENTITIES', 'UTF-8'));
$nodeRoot = $xml->getElementsByTagName('root')->item(0);
$nodeOriginal = $xml->getElementsByTagName('people')->item(0);
$nodeRoot->insertBefore($newNode,$nodeOriginal);
$finalXmlAsString = $xml->saveXML();
?>
answered Jan 5, 2015 at 13:20
Sign up to request clarification or add additional context in comments.

9 Comments

I edited your third line to : $newNode = $xml->createElement($someXMLtoPrepend); but I am getting PHP Fatal error: Uncaught exception 'DOMException' with message 'Invalid Character Error' and several warnings related to namespaces. The XML is valid and not manually generated.
Are you sure this isn't a case: stackoverflow.com/questions/8524111/php-invalid-character-error ? I mean - none of your nodes name starts with number or something?
I don't have any tags with a digit at the beginning of their names. I'll look into it anyways.
@wtf8_decode I've added edit to answer, maybe it's this, but I'm really not sure. I only used DOMDocument with HTML, never with XML, there should be no big difference tho..
Still the same. My XML is not manually generated and even contains <![CDATA[ tags. I see DOMDocument is getting somewhat confused by it as it still tries to parse the inner XML. The problematic line appears to be the mb_convert_encoding one.
|

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.