dbarndt Posted November 30, 2007 Share Posted November 30, 2007 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); } } Quote Link to comment https://forums.phpfreaks.com/topic/79626-merging-xml-in-php-using-simplexml-and-dom/ Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.