tutorial simplexmlelement print new instalar ejemplo attribute array php simplexml

print - PHP-SimpleXML-AddChild con otro SimpleXMLElement



simplexmlelement php ejemplo (3)

Estoy tratando de construir un documento XML bastante complejo.

Tengo un montón de secciones del documento XML que se repite. Pensé que usaría varias plantillas de cadena como documento base para las secciones y crearía instancias de elementos XML usando simplexml_load_string.

Así que tengo una instancia de SimpleXMLElement como el documento base

$ root = simplexml_load_string ($ template_root);

Luego recorro algunos elementos en mi base de datos, creo un nuevo SimpleXMLElement, algo como esto:

para (bla bla bla):

$ item = simplexml_load_string ($ template_item); // hacer cosas con el elemento // tratar de agregar un elemento al documento raíz ...
// atascado aquí .. no puedo hacer $ root-> items-> addChild ($ item)

endfor

No puedo llamar a addChild porque solo espera un nombre y un valor de etiqueta ... no puede agregar otro SimpleXMLElement de Child.

¿Me estoy perdiendo de algo? Parece realmente tonto que addChild no puede tomar un SimpleXMLELement como parámetro.

Hay alguna otra manera de hacer esto? (aparte de usar un lib xml diferente)


El ejemplo xml_adopt () no conserva los nodos de espacio de nombres.
Mi edición fue rechazada porque cambió mucho? fue spam ?.

Aquí hay una versión de xml_adopt () que conserva los espacios de nombres.

function xml_adopt($root, $new, $namespace = null) { // first add the new node // NOTE: addChild does NOT escape "&" ampersands in (string)$new !!! // replace them or use htmlspecialchars(). see addchild docs comments. $node = $root->addChild($new->getName(), (string) $new, $namespace); // add any attributes for the new node foreach($new->attributes() as $attr => $value) { $node->addAttribute($attr, $value); } // get all namespaces, include a blank one $namespaces = array_merge(array(null), $new->getNameSpaces(true)); // add any child nodes, including optional namespace foreach($namespaces as $space) { foreach ($new->children($space) as $child) { xml_adopt($node, $child, $space); } } }

(edición: ejemplo añadido)

$xml = new SimpleXMLElement( ''<?xml version="1.0" encoding="utf-8"?> <rss version="2.0" xmlns:media="http://search.yahoo.com/mrss/"> <channel></channel></rss>''); $item = new SimpleXMLElement( ''<item xmlns:media="http://search.yahoo.com/mrss/"> <title>Slide Title</title> <description>Some description</description> <link>http://example.com/img/image.jpg</link> <guid isPermaLink="false">A1234</guid> <media:content url="http://example.com/img/image.jpg" medium="image" duration="15"> </media:content> </item>''); $channel = $xml->channel; xml_adopt($channel, $item); // output: // Note that the namespace is (correctly) only preserved on the root element ''<?xml version="1.0" encoding="utf-8"?> <rss xmlns:media="http://search.yahoo.com/mrss/" version="2.0"> <channel> <item> <title>Slide Title</title> <description>Some description</description> <link>http://example.com/img/image.jpg</link> <guid isPermaLink="false">A1234</guid> <media:content url="http://example.com/img/image.jpg" medium="image" duration="15"> </media:content> </item> </channel> </rss>''


Podría usar esta función que se basa en la creación de los hijos con atributos de la fuente:

function xml_adopt($root, $new) { $node = $root->addChild($new->getName(), (string) $new); foreach($new->attributes() as $attr => $value) { $node->addAttribute($attr, $value); } foreach($new->children() as $ch) { xml_adopt($node, $ch); } } $xml = new SimpleXMLElement("<root/>"); $child = new SimpleXMLElement("<content><p a=/"aaaaaaa/">a paragraph</p><p>another <br/>p</p></content>"); xml_adopt($xml, $child); echo $xml->asXML()."/n";

Esto producirá:

<?xml version="1.0"?> <root><content><p a="aaaaaaa">a paragraph</p><p>another p<br/></p></content></root>


Por lo que sé, no puede hacerlo con SimpleXML porque addChild no hace una copia profunda del elemento (es necesario superar el nombre de la etiqueta para que se pueda superar fácilmente llamando a SimpleXMLElement::getName() ).

Una solución sería usar DOM en su lugar:

Con esta función:

function sxml_append(SimpleXMLElement $to, SimpleXMLElement $from) { $toDom = dom_import_simplexml($to); $fromDom = dom_import_simplexml($from); $toDom->appendChild($toDom->ownerDocument->importNode($fromDom, true)); }

Tenemos para

<?php header("Content-type: text/plain"); $sxml = simplexml_load_string("<root></root>"); $n1 = simplexml_load_string("<child>one</child>"); $n2 = simplexml_load_string("<child><k>two</k></child>"); sxml_append($sxml, $n1); sxml_append($sxml, $n2); echo $sxml->asXML();

La salida

<?xml version="1.0"?> <root><child>one</child><child><k>two</k></child></root>

Vea también algunos comentarios de usuarios que usan funciones recursivas y addChild , por ejemplo, este .