I have 2 XML files.
I am trying to get data from XML File B and add it to XML File A. I want to first add an empty child to XML File A, and then in that child, I want to add data from XML File B (in this case, the animal
child element). I want to achieve this through either SimpleXML or DOMDocument. I have been stuck on this. Any help would be great!
personinfo.xml < XML File A
<personinfo>
<personN number="1">
<personL letter="A">
<fullname>
<firstname>Summer</firstname>
<lastname>Smith</lastname>
</fullname>
<favourites>
<color>pink</color>
</favourites>
</personL>
</personN>
<personN number="2">
<personL letter="B">
<fullname>
<firstname>Autumn</firstname>
<lastname>Smith</lastname>
</fullname>
<favourites>
<color>blue</color>
</favourites>
</personL>
</personN>
</personinfo>
favouritesinfo.xml < XML File B
<favouritesinfo>
<personN number="1">
<animal>cat</animal>
</personN>
<personN number="2">
<animal>dog</animal>
</personN>
</favouritesinfo>
Is this possible? If so, am I able to do this via XML DOM Document or SimpleXML?
I attempted doing it this way via a separate PHP file but it does not work/do anything with SimpleXML
$personXML = simplexml_load_file("personinfo.xml");
$faveXML = simplexml_load_file("favouritesinfo.xml");
$animal=$faveXML->personN[0]->animal;
$newFave=$personXML->personN->personL[0]->addChild("favourites");
$favourites->addChild($animal);
$personXML->asXML();
Desired output
<personinfo>
<personN number="1">
<personL letter="A">
<fullname>
<firstname>Summer</firstname>
<lastname>Smith</lastname>
</fullname>
<favourites>
<color>pink</color>
</favourites>
<favourites>
<color>cat</color>
</favourites>
</personL>
</personN>
<personN number="2">
<personL letter="B">
<fullname>
<firstname>Autumn</firstname>
<lastname>Smith</lastname>
</fullname>
<favourites>
<color>blue</color>
</favourites>
<favourites>
<color>dog</color>
</favourites>
</personL>
</personN>
</personinfo>
This is easier in DOM because you have access to the nodes and can copy them from one document to another. Use Xpath to fetch parts of a document.
// load the XML into DOM document and create Xpath instances
$personsDocument = new DOMDocument;
$personsDocument->preserveWhiteSpace = FALSE;
$personsDocument->loadXML($xmlPersons);
$personsXpath = new DOMXpath($personsDocument);
$favoritesDocument = new DOMDocument;
$favoritesDocument->preserveWhiteSpace = FALSE;
$favoritesDocument->loadXML($xmlFavorites);
$favoritesXpath = new DOMXpath($favoritesDocument);
// iterate the personN nodes in the favorties XML
foreach ($favoritesXpath->evaluate('.//personN') as $personFavorites) {
$personId = (int)$personFavorites->getAttribute('number');
// find the matching personL node in the persons XML
foreach ($personsXpath->evaluate('.//personN[@number='.$personId.']/personL') as $personNode) {
// check if it has a 'favourites' child already
$favoritesNode = $personsXpath->evaluate('favourites', $personNode)->item(0);
if (!$favoritesNode) {
// otherwise create one
$favoritesNode = $personNode->appendChild(
$personsDocument->createElement('favourites')
);
}
// now iterate the different favorites of a person
foreach ($personFavorites->childNodes as $favorite) {
// import and add
$favoritesNode->appendChild($personsDocument->importNode($favorite, TRUE));
}
}
}
$personsDocument->formatOutput = TRUE;
echo $personsDocument->saveXML();
Output:
<?xml version="1.0"?>
<personinfo>
<personN number="1">
<personL letter="A">
<fullname>
<firstname>Summer</firstname>
<lastname>Smith</lastname>
</fullname>
<favourites>
<color>pink</color>
<animal>cat</animal>
</favourites>
</personL>
</personN>
<personN number="2">
<personL letter="B">
<fullname>
<firstname>Autumn</firstname>
<lastname>Smith</lastname>
</fullname>
<favourites>
<color>blue</color>
<animal>dog</animal>
</favourites>
</personL>
</personN>
</personinfo>
Adding a favourites
parent for each favorite does not make much sense. So I added a check to my example. If you really want the parent nodes, you can remove it:
foreach ($personsXpath->evaluate('.//personN[@number='.$personId.']/personL') as $personNode) {
//create 'favourites' child
$favoritesNode = $personNode->appendChild(
$personsDocument->createElement('favourites')
);
foreach ($personFavorites->childNodes as $favorite) {
//...