Danc
Danc

Reputation: 167

Merge SimpleXML elements by attribute

I have 2 SimpleXMLElements. They both have the same elements (identical ID attributes), but different tags, and I want to merge them together.

Is there any SimpleXML function I can use to do this, or will I have to loop through all the elements to generate a new SimpleXmlElement?

File 1

<Elements>
    <Element ID="352">
        <SomeTag35>Some value</SomeTag35>
        <SomeTag99>Some other value</SomeTag99>
    </Element>
    <Element ID="353">
        <SomeTag35>A value</SomeTag35>
        <SomeTag99>Another value</SomeTag99>
    </Element>
</Elements>

File 2

<Elements>
    <Element ID="352">
        <SomeTag15>Value</SomeTag15>
        <SomeTag44>Value2</SomeTag44>
    </Element>

    <Element ID="353">
        <SomeTag15>Value</SomeTag15>
        <SomeTag44>Value</SomeTag44>
    </Element>
</Elements>

I'm looking to some how end up with

<Elements>
    <Element ID="352">
        <SomeTag35>Some value</SomeTag35>
        <SomeTag99>Some other value</SomeTag99>
        <SomeTag15>Value</SomeTag15>
        <SomeTag44>Value</SomeTag44>
    </Element>
    <Element ID="353">
        <SomeTag35>A value</SomeTag35>
        <SomeTag99>Another value</SomeTag99>
        <SomeTag15>Value</SomeTag15>
        <SomeTag44>Value</SomeTag44>
    </Element>
</Elements>

Upvotes: 1

Views: 508

Answers (1)

Nigel Ren
Nigel Ren

Reputation: 57121

SimpleXML is good for doing simple tasks like this. The idea is to read the first document and then use XPath to find the corresponding element in the second document. Then copy the elements from the second document into the first.

$doc1 = simplexml_load_file('file1.xml');
$doc2 = simplexml_load_file('file2.xml');
foreach ( $doc1 as $element )  {
    $extraData = $doc2->xpath("//Element[@ID=\"{$element['ID']}\"]");
    foreach ( $extraData[0]->children() as $newElements ){
        $element->addChild($newElements->getName(), (string)$newElements);
    }
}

echo $doc1->asXML();

Note that this only works with simple structures. If your document has nested data or attributes, you are better off using DOMDocument where you can copy nodes using importNode which allows you to copy the content with all sub elements as well.

Upvotes: 2

Related Questions