SimpleXMLElement::addChild()
(PHP 5 >= 5.1.3, PHP 7)
Adds a child element to the XML node
说明
public SimpleXMLElement::addChild(string $name[,string $value[,string $namespace]]): SimpleXMLElement
Adds a child element to the node and returns a SimpleXMLElement of the child.
参数
- $name
The name of the child element to add.
- $value
If specified, the value of the child element.
- $namespace
If specified, the namespace to which the child element belongs.
返回值
TheaddChildmethod returns a SimpleXMLElement object representing the child added to the XML node.
范例
Note:Listed examples may includeexample.php, which refers to the XML string found in the first example of the basic usage guide.
Example #1 Add attributes and children to a SimpleXML element
<?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(); ?>
以上例程的输出类似于:
<?xml version="1.0" standalone="yes"?> <movies type="documentary"> <movie> <title>PHP: Behind the Parser</title> <characters> <character> <name>Ms. Coder</name> <actor>Onlivia Actora</actor> </character> <character> <name>Mr. Coder</name> <actor>El ActÓr</actor> </character> </characters> <plot> So, this language. It's like, a programming language. Or is it a scripting language? All is revealed in this thrilling horror spoof of a documentary. </plot> <great-lines> <line>PHP solves all my web problems</line> </great-lines> <rating type="thumbs">7</rating> <rating type="stars">5</rating> </movie> <movie> <title>PHP2: More Parser Stories</title> <plot>This is all about the people who make it work.</plot> <characters> <character> <name>Mr. Parser</name> <actor>John Doe</actor> </character> </characters> <rating type="stars">5</rating> </movie> </movies>
参见
- SimpleXMLElement::addAttribute() Adds an attribute to the SimpleXML element
- Basic SimpleXML usage
To complete Volker Grabsch's comment, stating : "Note that although addChild() escapes "<" and ">", it does not escape the ampersand "&"." To work around that problem, you can use direct property assignment such as : <?php $xmlelement->value = 'my value < > &'; // results in <value>my value < > &</value> ?> instead of doing : <?php $xmlelement->addChild('value', 'my value < > &'); // results in <value>my value < > &</value> (invalid XML) ?> See also: http://stackoverflow.com/questions/552957 (Rationale behind SimpleXMLElement's handling of text values in addChild and addAttribute) HTH
Here is a class with more functions for SimpleXMLElement : <?php /** * * Extension for SimpleXMLElement * @author Alexandre FERAUD * */ class ExSimpleXMLElement extends SimpleXMLElement { /** * Add CDATA text in a node * @param string $cdata_text The CDATA value to add */ private function addCData($cdata_text) { $node= dom_import_simplexml($this); $no = $node->ownerDocument; $node->appendChild($no->createCDATASection($cdata_text)); } /** * Create a child with CDATA value * @param string $name The name of the child element to add. * @param string $cdata_text The CDATA value of the child element. */ public function addChildCData($name,$cdata_text) { $child = $this->addChild($name); $child->addCData($cdata_text); } /** * Add SimpleXMLElement code into a SimpleXMLElement * @param SimpleXMLElement $append */ public function appendXML($append) { if ($append) { if (strlen(trim((string) $append))==0) { $xml = $this->addChild($append->getName()); foreach($append->children() as $child) { $xml->appendXML($child); } } else { $xml = $this->addChild($append->getName(), (string) $append); } foreach($append->attributes() as $n => $v) { $xml->addAttribute($n, $v); } } } } ?>
In the docs for google sitemaps it is required an element for mobile sitemaps that looks like this: <mobile:mobile/> I used some time to figure out how to make it, but it is quite simple when understood. $mobile_schema = 'http://www.google.com/schemas/sitemap-mobile/1.0'; //Create root element $xml_mobile = new SimpleXMLElement(' <?xml version="1.0" encoding="UTF-8"?> <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:mobile="'.$mobile_schema.'"></urlset> '); //Add required children $url_mobile = $xml_b_list_mobile->addChild('url'); $url_mobile->addChild('loc', 'your-mobile-site-url'); $url_mobile->addChild('mobile:mobile', null, $mobile_schema); For this to work properly the attribute xmlns:mobile must be set in the root node, and then used as namespace(third argument) when creating the mobile:mobile child with null as value.
Note that although addChild() escapes "<" and ">", it does not escape the ampersand "&". So addChild() is unsuited to handle user-defined input! Instead, you will have to replace all "&" with "&" before calling addChild(). Or, use htmlspecialchars() which also replaces other characters, but won't do any harm as addChild() won't replace those again.
Want to continue the ampersand (&) chain problem. Sometimes, you would want to assign (=) addChild. This trick will helps you to do this. <?php $webOrders = new SimpleXMLElement('<?xml version="1.0"?><WebOrders></WebOrders>'); $webOrder = $webOrders->addChild('WebOrder'); $product = $webOrder->addChild('Product'); $product[0] = 'T&M'; $product->addAttribute('price', 19.99); $product->addAttribute('qty', 2); var_dump($webOrders->asXML()); ?> OUTPUT would be: <?xml version="1.0" encoding="UTF-8"?> <WebOrders> <WebOrder> <Product price="19.99" qty="2">T&M</Product> </WebOrder> </WebOrders>
Here's my solution for creating XML from Multidimensional Array. <?php //DATA $xmlDAta = array( array( "name" => "nameVal", "value" => "valVal", "css" => "cssVal" ), array( "name" => "name1Val", "value" => "val1Val", "css" => "css1Val" ), "tname" => array( array( "iTname" => "iTname", "iTname2" => "iTname1", "iTname2" => "iTname2", "iTbname3" => array( "iiTbname" => "tbName", "iiTbname1" => "tbName1", ), ), ), "tdata" => "otheerDAta" ); /** * Create XML using string or array * * @param mixed $data input data * @param SimpleXMLElement $xml * @param string $child name of first level child * * @return adding Xml formated data into SimpleXmlElement */ function data2XML(array $data, SimpleXMLElement $xml, $child = "items") { foreach($data as $key => $val) { if(is_array($val)) { if(is_numeric($key)) { $node = $xml->addChild($child); $nodes = $node->getName($child); } else { $node = $xml->addChild($key); $nodes = $node->getName($key); } $node->addChild($nodes, self::data2Xml($val, $node)); } else { $xml->addChild($key, $val); } } } //Use $xml = new SimpleXMLElement("<root/>"); Util::data2XML($xmlDAta, $xml, "Items"); ?>
Be aware that simply because you can <?php $dom->addChild();?> doesn't mean your XML is valid under simple XML itself: <?php $dom=simplexml_load_string("<test></test>"); $dom->addChild("3D","1,2,3"); $xml=$dom->asXML(); echo $xml; /* echos: <?xml version="1.0"?> <test><3D>1,2,3</3D></test> */ $dom=simplexml_load_string($xml); /* generates a whole lots of warnings, and refuses to create an object. */ ?> Same in PHP 5.3 and 5.4
This method returns a reference to the specific SimpleXMLElement. If you use: <?php $xml= new SimpleXMLElement('<root></root>'); $xml->father['name']= 'Fathers name'; // creates automatically a father tag with attribute name $son= $xml->father->addChild('son'); // uses the first father tag $son['name']= 'first son'; $otherSon= $xml->father->addChild('son'); // uses the first father tag but now, in a second son tag $otherSon['name']= 'second son'; echo htmlentities($xml->asXML()); ?> The result will be <root> <father> <son name='first son' /> <son name='second son' /> </father> </root> So, once you change something to the just added child, you are actually accessing the element inside the SimpleXMLElement as a reference.
If you're looking for a way to append children you may be interested in this: <?php $x = new SimpleXMLElement('<root name="toplevel"></root>'); $f1 = new SimpleXMLElement('<child pos="1">alpha</child>'); $f2 = new SimpleXMLElement('<child pos="2">beta</child>'); $f3 = new SimpleXMLElement('<child pos="3">gamma</child>'); $x->{$f1->getName()} = $f1; $x->{$f2->getName()}[] = $f2; $x->{$f3->getName()}[] = $f3; echo 'count child=',$x->count(),"\n"; echo $x->asXML(); foreach ( $x->children() as $foo ) { var_dump($foo); } ?>
<?php class MySimpleXMLElement extends SimpleXMLElement { /** * Add SimpleXMLElement code into a SimpleXMLElement * * @param SimpleXMLElement $append */ public function appendXML($append) { if ($append) { if (strlen(trim((string)$append)) == 0) { $xml = $this->addChild($append->getName()); } else { $xml = $this->addChild($append->getName(), (string)$append); } foreach ($append->children() as $child) { $xml->appendXML($child); } foreach ($append->attributes() as $n => $v) { $xml->addAttribute($n, $v); } } } } ?>