Jump to content

Merging XML in PHP using SimpleXML and DOM


dbarndt

Recommended Posts

Hi,

 

I'm having trouble trying to merge two SimpleXML objects (user preference settings) in PHP.  It should be simple enough - the objects have the same root element, and I simply want to merge at the top child level.  However, the code I'm providing here, while it executes, does not work.  At the end of the merge() function, the merged preferences are empty.

 

I would very much appreciate if someone could tell me what I'm doing wrong or suggest another approach.  Thanks very much!

 

Example of desired XML result:

Before merge:

Old:
<xml version="1.0"/>
<preferences>
<setting1>value1</setting1>
<setting2 attr21="attr21Value" attr22="attr22Value" attr23="attr23Value"/>
</preferences>

New:
<xml version="1.0"/>
<preferences>
<setting1>value2</setting1>
<setting3 attr31="attrValue31" attr32="attr32Value" attr33="attrValue33"><setting31>value31</setting31><setting32>value32</setting32></setting3>
</preferences>

After merge:
<xml version="1.0"/>
<preferences>
<setting1>value2</setting1>
<setting2 attr21="attr21Value" attr22="attr22Value" attr23="attr23Value"/>
<setting3 attr31="attrValue31" attr32="attr32Value" attr33="attrValue33"><setting31>value31</setting31><setting32>value32</setting32></setting3>
</preferences>

-------------------

class UserPreferences
{
        const DEFAULT_STRING = "<preferences/>";

        $m_preferences = null;

        public function __construct()
        {
                $this->m_preferences = new SimpleXMLElement(self::DEFAULT_STRING);
        }

        // $new is a SimpleXMLElement containing the preferences to be merged
        public function merge($new)
        {
                $mergedDom = DOMDocument::loadXML(self::DEFAULT_STRING);

                $oldDom = DOMDocument::loadXML($this->m_preferences->asXML());

                // Compare existing/old preferences with the new
                // preferences.  If a match is found, delete the
                // old preference.
                foreach ($new->children() as $newChild)
                {
                        $i = 0;

                        foreach ($this->m_preferences->children() as $oldChild)
                        {
                                if ($newChild->asXML() == $oldChild->asXML())
                                {
                                        $oldDom->documentElement->removeChild($oldDom->documentElement->childNodes->item($i));
                                        $i--;
                                }
                                else
                                {
                                        $i++;
                                }
                        }

                        // Add the new preference to the merged list.
                        $newChildDom = DOMDocument::loadXML($newChild->asXML());
                        $mergedDom->documentElement->appendChild($mergedDom->importNode($newChildDom, true));
                }

                // Add the old preferences which did not match any of the new preferences to the merged list.
                $this->m_preferences = simplexml_import_dom($oldDom);

                foreach ($this->m_preferences->children() as $oldChild)
                {
                        $oldChildDom = DOMDocument::loadXML($oldChild->asXML());
                        $mergedDom->documentElement->appendChild($mergedDom->importNode($oldChildDom, true));
                }

                // Save the newly merged preferences.
                $this->m_preferences = simplexml_import_dom($mergedDom);
        }
}

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.