How do you merge two XML documents in PHP using SimpleXML?
I have a database row that looks like this.
ID (int): 123
Name (string): SomeName
Data (string): <data><foo>one</foo></bar>two</bar></data>
I need to format this data as XML in the following way.
<row>
<id>123</id>
<name>SomeName</name>
<data>
<foo>one</foo>
<bar>two</bar>
</data>
<row>
I'm currently using SimpleXML to try to build this, but I'm not sure how to go about inserting the existing XML into the new XML document I'm trying to build.
If there are other standard XML builders that come with PHP, I'm open to using those, too. String concatenation is not an acceptable answer.
Edit: It looks as though SimpleXML won't do what I need. I guess at this point, I need suggestions for other XML pars开发者_如何转开发ers.
$xml = new SimpleXMLElement('<row></row>');
$xml->addChild('id', /*database ID column*/);
$xml->addChild('name', /*database Name column*/);
$data = new SimpleXMLElement(/*database Data column*/);
$xml->addChild('data');
$xml->data->addChild('foo', $data->foo);
$xml->data->addChild('bar', $data->bar);
Tested and it works. It should be trivial to convert this to your actual application. There may be a more flexible way of doing it, but I'm not aware of it. They don't call it SimpleXML for nothing :)
$xml = '<data><foo>one</foo><bar>two</bar></data>'; // your data field
$row = new SimpleXMLElement('<row></row>'); // new row to inject your database fields into
$data = new SimpleXMLElement($xml); // new object from your xml data field
$row->id = '123'; // your id field
$row->name = 'Somename'; // your name field
$row->data->foo = $data->foo; // your foo record from your xml data field
$row->data->bar = $data->bar; // your bar record from your xml data field
$final_xml = $row->saveXML(); // restructure your xml file/string
echo $final_xml; // <?xml version="1.0"?><row><id>123</id><name>Somename</name><data><foo>one</foo><bar>two</bar></data></row>
Tested this code and it also works.
You will have to create two SimpleXml Objects like the answer above. Other than that you can just add
additional elements like adding class vars. A <?xml version="1.0"?>
will be added to the final xml string/file.
Not sure if you need the <?xml version="1.0"?>
.
If not you can take it out with:
$final_xml = str_replace("<?xml version=\"1.0\"?>\n",'',$final_xml);
You can check out http://www.php.net/manual/en/simplexmlelement.asxml.php for more info on re-saving SimpleXml objects back to xml strings/files.
/**
* Converts your record to XML.
*
* @param array/object $record
* @return SimpleXMLElement
*/
function ConvertToXml($record){
// Objects need to be arrays
if(is_object($record)){
$record = get_object_vars($record);
}
// We need an array argument
if(!is_array($record)){
trigger_error('$record must be an object or an array.', E_USER_WARNING);
return null;
}
// Now we build XML
ob_start();
echo '<xml>', PHP_EOL;
foreach($record as $name => $value){
if(is_object($value) or is_array($value) or is_resource($value)){
trigger_error('$record must have only scalar values.', E_USER_WARNING);
return null;
}
if(!is_string($name) or !preg_match('~[a-z_][a-z0-9]*~i', $name)){
trigger_error('$record must have only XML-tag friendly string keys.', E_USER_WARNING);
return null;
}
// NULL produces an empty node
if(is_null($value)){
echo "<{$name} />", PHP_EOL;
continue;
}
// Numerics don't need to be XML encoded
if(is_integer($value) or is_float($value) or is_bool($value)){
echo "<{$name}>{$value}</{$name}>", PHP_EOL;
continue;
}
// We must have a string now
if(!is_string($name)){
trigger_error('$record must have only scalar values.', E_USER_WARNING);
return null;
}
// Do we have an XML field?
if(preg_match('~^\s*<.+>\s*$~s', $value)){
// Test it for real!
if($xml = @simplexml_load_string("<xml>{$value}</xml>")){
echo $value, PHP_EOL;
continue;
}
}
// Now output random strings
echo "<{$name}>", htmlentities($value, ENT_QUOTES, 'utf-8'), "</{$name}>", PHP_EOL;
}
echo '</xml>', PHP_EOL;
// Store built XML
$xml = ob_get_clean();
// Load the built XML
return @simplexml_load_string($xml);;
}
// Prepare an array
$record = array();
$record['ID'] = 1;
$record['Name'] = 'SomeName';
$record['Data'] = '<data><foo>one</foo><bar>two</bar></data>';
if($xml = ConvertToXml($record)){
echo $xml->asXML();
}
^ An answer for posterity.
精彩评论