Adding a root element is easy. You just load the XML into a string and then append and prepend as needed. However, grouping the various elements in items is a bit trickier and largely depends on the XML. The following code will work with the XML you show:
<?php
$xml = 'your xml from the question';
$dom = new DOMDocument;
$dom->loadXml("<root>$xml</root>");
$fixed = new DOMDocument();
$fixed->loadXML("<inventory><items/></inventory>");
$fixed->formatOutput = true;
$items = $fixed->getElementsByTagName('items')->item(0);
foreach ($dom->documentElement->childNodes as $node) {
if ($node->nodeName === 'name') {
$item = $fixed->createElement('item');
$item->appendChild($fixed->createElement($node->nodeName, $node->nodeValue));
$next = $node->nextSibling;
while ($next !== null) {
if ($next instanceof DOMElement) {
if ($next->nodeName !== 'name') {
$item->appendChild($fixed->createElement($next->nodeName, $next->nodeValue));
} else {
$items->appendChild($item);
break;
}
}
$next = $next->nextSibling;
}
}
}
echo $fixed->saveXML();
This will create two documents:
- Your legacy XML with a dummy
<root> element so we can process it
- A document with the root element
<inventory> and an empty element <items>.
We will then iterate all the elements in the legacy XML. When we find a <name> element, we create a new <item> element and add the <name> element as a child. We then check every following sibling to the <name> element. If it's not a <name> element, we will add it to the <item> as well. When it's another <name>, we add the <item> to the <items> collection and start over.
This will then produce:
<?xml version="1.0"?>
<inventory>
<items>
<item>
<name>Chair</name>
<price>$53</price>
<quantity>20</quantity>
<units>Piece</units>
</item>
<item>
<name>Lamp</name>
<price>$20</price>
<quantity>90</quantity>
<units>Piece</units>
</item>
<item>
<name>Table</name>
<price>$35</price>
<quantity>10</quantity>
<units>Piece</units>
<material>Wood</material>
</item>
</items>
</inventory>
You can probably do all of this in a single document. I felt it was easier to understand with two documents.