To add another XML-Element including one or more Tags instead of just one Tag, use this recursive function:
<?php
function AddXMLElement(SimpleXMLElement $dest, SimpleXMLElement $source)
{
$new_dest = $dest->addChild($source->getName(), $source[0]);
foreach ($source->children() as $child)
{
AddXMLElement($new_dest, $child);
}
}
?>
SimpleXMLElement::addChild
(PHP 5 >= 5.1.3)
SimpleXMLElement::addChild — XML ノードに子要素を追加する
説明
SimpleXMLElement addChild
( string $name
[, string $value
[, string $namespace
]] )
ノードに子要素を追加し、子要素の SimpleXMLElement を返します。
パラメータ
- name
-
追加する子要素の名前。
- value
-
指定されている場合は、子要素の値。
- namespace
-
指定されている場合は、その子要素が所属する名前空間。
返り値
addChild メソッドは、 XML ノードに追加した子要素を表す SimpleXMLElement オブジェクトを返します。
例
例1 SimpleXML 要素への属性と子要素の追加
<?php
include 'example.php';
$sxe = new SimpleXMLElement($xmlstr);
$sxe->addAttribute('type', 'documentary');
$movie = $sxe->addChild('movie');
$movie->addChild('title', 'PHP2: More Parser Stories');
$movie->addChild('plot', 'This is all about the people who make it work.');
$characters = $movie->addChild('characters');
$character = $characters->addChild('character');
$character->addChild('name', 'Mr. Parser');
$character->addChild('actor', 'John Doe');
$rating = $movie->addChild('rating', '5');
$rating->addAttribute('type', 'stars');
echo $sxe->asXML();
?>
SimpleXMLElement::addChild
Anonymous
20-Nov-2009 07:36
20-Nov-2009 07:36
Andy
10-Sep-2009 01:31
10-Sep-2009 01:31
Warning: addChild doesn't escape like addAttribute does.
For example:
<?php
$test = '<test/>';
$msg = "This is a test & stuff.";
$xml = new SimpleXMLElement($test);
$xml->addAttribute('foo', $msg);
echo htmlentities($xml->asXML());
$xml->addChild('bar', $msg);
echo htmlentities($xml->asXML());
?>
Outputs:
<?xml version="1.0"?>
<test foo="This is a test & stuff."/>
Warning: SimpleXMLElement::addChild() [simplexmlelement.addchild]: unterminated entity reference stuff. in file.php on line 13
<?xml version="1.0"?>
<test foo="This is a test & stuff."><bar>This is a test </bar></test>
Instead of the expected:
<?xml version="1.0"?>
<test foo="This is a test & stuff."><bar>This is a test & stuff.</bar></test>
This can be avoided by using the following:
<?php
// Generates an error:
// $xml->addChild('bar', $msg);
// Works as expected:
$bar = $xml->addChild('bar');
$bar[0] = $msg;
?>
Dmitry Dulepov
02-Sep-2009 09:53
02-Sep-2009 09:53
addChild will automatically escape all XML characters as necessary. You do not have to do any magic when adding values like "if a > b then...".
d dot smith at sharedlog dot com
01-Jun-2009 08:38
01-Jun-2009 08:38
If you want to add a child element that is prefixed by a namespace like this one:
<content:encoded>
then this is what you need to do:
<?php
$parent->addChild('content:encoded', 'some actual content here', ''http://purl.org/rss/1.0/modules/content/'');
?>
Make sure you declared the namespace at some parent element, preferrably at root:
<root xmlns:content="http://purl.org/rss/1.0/modules/content/">
This will create a child element that will look like this when object dumpted as xml string:
<content:encoded>
If you are adding child this way:
<?php
$parent->addChild('encoded', 'some actual content here', ''content'');
?>
then your child element will look like this:
<encoded xmlns="content">
which is also a valid xml tag and basically has the same exact value as <content:encoded> but just looks different.
ldmc at yahoo dot com
18-Mar-2009 03:14
18-Mar-2009 03:14
Simple way to add a text node:
<?php
$x=simplexml_load_string('<test />');
$x->addAttribute('id','x01');
$x[0]='text node';
echo $x->asXML();
?>
Result:
<?xml version="1.0"?>
<test id="x01">text node</test>
Any numeric array subscript (in this case 0) will work.
jonasmartinez at gmail dot com
17-Mar-2009 11:56
17-Mar-2009 11:56
The class:
<?php
class SimpleXMLExtend extends SimpleXMLElement
{
public function addCData($nodename,$cdata_text)
{
$node = $this->addChild($nodename); //Added a nodename to create inside the function
$node = dom_import_simplexml($node);
$no = $node->ownerDocument;
$node->appendChild($no->createCDATASection($cdata_text));
}
}
?>
And to use:
<?php
$xml = new SimpleXMLExtended('<?xml version = "1.0" encoding = "UTF-8"?><root></root>');
$xml->addCData("newnode","contenthere with & $ % etc");
echo $xml->asXml();
?>
Donet
02-Oct-2008 11:11
02-Oct-2008 11:11
I found this easy way to create a CDATA section as child value:
I extend the class SimpleXMLElement:
<?php
class SimpleXMLExtended extends SimpleXMLElement
{
public function addCData($cdata_text)
{
$node= dom_import_simplexml($this);
$no = $node->ownerDocument;
$node->appendChild($no->createCDATASection($cdata_text));
}
}
?>
Then in the main code:
<?php
$xml = new SimpleXMLExtended('<?xml version = "1.0" encoding = "UTF-8"?><root></root>');
$mynode = $xml->addChild("myname");
$mynode->addCData("my name contains everything I want &%<>");
echo $xml->asXml();
?>
essen at dev-extend dot eu
18-Jul-2008 01:06
18-Jul-2008 01:06
Easy and fast deleting of a node:
<?php
$oNode = dom_import_simplexml($oSimpleXMLNodeToDelete);
$oNode->parentNode->removeChild($oNode);
?>
The node can have childs, attributes, and be anywhere in your document, it'll get deleted. The deletion will appear immediately in your SimpleXML object after calling removeChild, there's nothing else to do.
kobrasrealm at gmail dot com
29-Jun-2008 06:22
29-Jun-2008 06:22
Here's a handy workaround to accommodate the lack of a $xml->deleteChild() function. It's not perfect, but it's a start (and it works for what I'm using it for):
<?php
// Workaround by Kobra.
function simplexml_deleteChild($parent, $childname, $parentname)
{
$temp = simplexml_load_string(str_replace("#","?","<#xml version=\"1.0\"#>\n<".$parentname.">\n</".$parentname.">"));
foreach($parent as $t)
{
if($t->getName() != $childname)
{
$name = $t->getName();
$value = eval("return \$parent->".$name.";");
$temp->addChild($t->getName(), $value);
}
}
return $temp;
}
?>
I have not tested this with multi-level XML files; but like I said, it's a start.
danz at gethitz dot info
30-Jan-2008 10:12
30-Jan-2008 10:12
Object cloning ...
So using the 'clone' keyword here lets you work on $new separately, and attributes added to $new don't show up in $sxe
without the 'clone' all changes to $new will be reflected in the larger $sxe tree
<?php
$new = clone $sxe->AddChild("comment",$comment);
$new->AddAttribute("name",$name);
$new->AddAttribute("url",$url);
$new->AddAttribute("ip",$ip);
$new->AddAttribute("time",$time);
?>
ron @ rotflol dot cx
11-Jul-2007 01:37
11-Jul-2007 01:37
Replacing a node is an easy mod of the simplexml_append
<?php
function simplexml_replace(SimpleXMLElement $parent, SimpleXMLElement $new_child){
$node1 = dom_import_simplexml($parent);
$dom_sxe = dom_import_simplexml($new_child);
$node2 = $node1->ownerDocument->importNode($dom_sxe, true);
$node1->parentNode->replaceChild($node2,$node1);
}
?>
r dot versluis at millipede dot nl
22-May-2007 10:23
22-May-2007 10:23
<?php
// phpversion <= 5.1.2
function simplexml_addChild($parent, $name, $value=''){
$new_child = new SimpleXMLElement("<$name>$value</$name>");
$node1 = dom_import_simplexml($parent);
$dom_sxe = dom_import_simplexml($new_child);
$node2 = $node1->ownerDocument->importNode($dom_sxe, true);
$node1->appendChild($node2);
return simplexml_import_dom($node2);
}
function simplexml_addAttribute($parent, $name, $value=''){
$node1 = dom_import_simplexml($parent);
$node1->setAttribute($name,$value);
return simplexml_import_dom($node1);
}
?>
l dot j dot peters at student dot utwente dot nl
01-Feb-2007 01:51
01-Feb-2007 01:51
Rob Richards and I have come up with a very easy way to append one SimpleXML tree to another:
<?php
function simplexml_append(SimpleXMLElement $parent, SimpleXMLElement $new_child){
$node1 = dom_import_simplexml($parent);
$dom_sxe = dom_import_simplexml($new_child);
$node2 = $node1->ownerDocument->importNode($dom_sxe, true);
$node1->appendChild($node2);
}
?>
And adding a textnode is also easy:
<?php
//$sxe1 (refers to SimpleXMLElement)
$node1 = dom_import_simplexml($sxe1);
$node1->appendChild(new DOMText("my text"));
?>
Ofcourse, you could use this to extend the SimpleXMLElement class and overwrite and improve the existing addChild function.
Have fun, Luuk Peters.
thomas dot ekdahl at empatix dot no
18-Sep-2006 09:57
18-Sep-2006 09:57
Because SimpleXML transforms the values & to & whe reading from file or string, the values becomes invalid for use when adding childs later on. This simple conversion to the example above fixes this problem.
<?php
class XMLElement extends SimpleXMLElement
{
public function addElement (SimpleXMLElement $xmlTree,$root=false)
{
if($root)
{
$child = $this->addChild ($xmlTree->getName());
foreach ($xmlTree->attributes() as $k => $v)
{
$child->addAttribute($k,$v);
}
$child->addElement($xmlTree);
}
else
{
foreach ($xmlTree as $childName => $childTree)
{
$child = $this->addChild($childName,$this->fix_content((string) $childTree)); // this is not comletely correct
foreach ($childTree->attributes() as $k => $v)
{
$child->addAttribute($k,$v);
}
$child->addElement($childTree->children());
}
}
}
#When the xml is read by simplexml_load_file or simplexml_load_file the values that contains & is converted to &. And then it is not possible to add these values without getting errors.
#THis function should fix this
public function fix_content($value) {
return str_replace('&', '&', $value);
}
}
?>
fred at misterbob dot nl
04-Aug-2006 01:23
04-Aug-2006 01:23
Method to append (Simple)XMLElements to each other.
<?php
class XMLElement extends SimpleXMLElement {
public function addElement (XMLElement $xmlTree,$root=false) {
if ($root) {
$child = $this->addChild ($xmlTree->getName());
foreach ($xmlTree->attributes() as $k => $v) {
$child->addAttribute($k,$v);
}
$child->addElement($xmlTree);
} else {
foreach ($xmlTree as $childName => $childTree) {
$child = $this->addChild($childName,(string) $childTree); // this is not comletely correct
foreach ($childTree->attributes() as $k => $v) {
$child->addAttribute($k,$v);
}
$child->addElement($childTree->children());
}
}
}
}
$xmlMovies = "<movies><movie name=\"Shawshank Redemption\"><plot>The life of Andy Dufresne changes when he is convicted and jailed for the murder of his wife.</plot></movie></movies>";
$elMovies = new XMLElement($xmlMovies);
$xmlGodfather = "<movie name=\"Godfather\"><plot>The aging patriarch of an organized crime dynasty transfers control of his clandestine empire to his reluctant son.</plot></movie>";
$elGodfather = new XMLElement ($xmlGodfather);
$elMovies->addElement($elGodfather,true);
echo $elMovies->asXML();
?>
