simplexmlelement simplexml_load_string simplexml_load_file ejemplo create attribute array php xml arrays simplexml

simplexml_load_string - simplexmlelement php get attribute



Cómo convertir array a SimpleXML (30)

Aquí está el código php 5.2 que convertirá la matriz de cualquier profundidad en un documento XML:

Array ( [''total_stud'']=> 500 [0] => Array ( [student] => Array ( [id] => 1 [name] => abc [address] => Array ( [city]=>Pune [zip]=>411006 ) ) ) [1] => Array ( [student] => Array ( [id] => 2 [name] => xyz [address] => Array ( [city]=>Mumbai [zip]=>400906 ) ) ) )

El XML generado sería como:

<?xml version="1.0"?> <student_info> <total_stud>500</total_stud> <student> <id>1</id> <name>abc</name> <address> <city>Pune</city> <zip>411006</zip> </address> </student> <student> <id>1</id> <name>abc</name> <address> <city>Mumbai</city> <zip>400906</zip> </address> </student> </student_info>

Fragmento de PHP

<?php // function defination to convert array to xml function array_to_xml( $data, &$xml_data ) { foreach( $data as $key => $value ) { if( is_numeric($key) ){ $key = ''item''.$key; //dealing with <0/>..<n/> issues } if( is_array($value) ) { $subnode = $xml_data->addChild($key); array_to_xml($value, $subnode); } else { $xml_data->addChild("$key",htmlspecialchars("$value")); } } } // initializing or creating array $data = array(''total_stud'' => 500); // creating object of SimpleXMLElement $xml_data = new SimpleXMLElement(''<?xml version="1.0"?><data></data>''); // function call to convert array to xml array_to_xml($data,$xml_data); //saving generated xml file; $result = $xml_data->asXML(''/file/path/name.xml''); ?>

Documentación en SimpleXMLElement::asXML utilizada en este fragmento

¿Cómo puedo convertir una matriz a un objeto SimpleXML en PHP?


Aquí está mi entrada, sencilla y limpia.

function array2xml($array, $xml = false){ if($xml === false){ $xml = new SimpleXMLElement(''<root/>''); } foreach($array as $key => $value){ if(is_array($value)){ array2xml($value, $xml->addChild($key)); }else{ $xml->addChild($key, $value); } } return $xml->asXML(); } header(''Content-type: text/xml''); print array2xml($array);


Aquí hay una función que hizo el truco para mí:

Solo llámalo con algo como

echo arrayToXml("response",$arrayIWantToConvert); function arrayToXml($thisNodeName,$input){ if(is_numeric($thisNodeName)) throw new Exception("cannot parse into xml. remainder :".print_r($input,true)); if(!(is_array($input) || is_object($input))){ return "<$thisNodeName>$input</$thisNodeName>"; } else{ $newNode="<$thisNodeName>"; foreach($input as $key=>$value){ if(is_numeric($key)) $key=substr($thisNodeName,0,strlen($thisNodeName)-1); $newNode.=arrayToXml3($key,$value); } $newNode.="</$thisNodeName>"; return $newNode; } }


Basado en todo lo demás aquí, maneja índices numéricos + atributos a través de un prefijo con @ , y podría inyectar xml a los nodos existentes:

Código

function simple_xmlify($arr, SimpleXMLElement $root = null, $el = ''x'') { // based on, among others http://.com/a/1397164/1037948 if(!isset($root) || null == $root) $root = new SimpleXMLElement(''<'' . $el . ''/>''); if(is_array($arr)) { foreach($arr as $k => $v) { // special: attributes if(is_string($k) && $k[0] == ''@'') $root->addAttribute(substr($k, 1),$v); // normal: append else simple_xmlify($v, $root->addChild( // fix ''invalid xml name'' by prefixing numeric keys is_numeric($k) ? ''n'' . $k : $k) ); } } else { $root[0] = $arr; } return $root; }//-- fn simple_xmlify

Uso

// lazy declaration via "queryparam" $args = ''hello=4&var[]=first&var[]=second&foo=1234&var[5]=fifth&var[sub][]=sub1&var[sub][]=sub2&var[sub][]=sub3&var[@name]=the-name&var[@attr2]=something-else&var[sub][@x]=4.356&var[sub][@y]=-9.2252''; $q = array(); parse_str($val, $q); $xml = simple_xmlify($q); // dump $xml, or... $result = get_formatted_xml($xml); // see below

Resultado

<?xml version="1.0"?> <x> <hello>4</hello> <var name="the-name" attr2="something-else"> <n0>first</n0> <n1>second</n1> <n5>fifth</n5> <sub x="4.356" y="-9.2252"> <n0>sub1</n0> <n1>sub2</n1> <n2>sub3</n2> </sub> </var> <foo>1234</foo> </x>

Bono: Formato XML

function get_formatted_xml(SimpleXMLElement $xml, $domver = null, $preserveWhitespace = true, $formatOutput = true) { // http://.com/questions/1191167/format-output-of-simplexml-asxml // create new wrapper, so we can get formatting options $dom = new DOMDocument($domver); $dom->preserveWhiteSpace = $preserveWhitespace; $dom->formatOutput = $formatOutput; // now import the xml (converted to dom format) /* $ix = dom_import_simplexml($xml); $ix = $dom->importNode($ix, true); $dom->appendChild($ix); */ $dom->loadXML($xml->asXML()); // print return $dom->saveXML(); }//-- fn get_formatted_xml


Con FluidXML puede generar, a partir de una matriz de PHP , un XML para SimpleXML con ... solo dos líneas de código.

$fluidxml = fluidxml($array); $simplexml = simplexml_import_dom($fluidxml->dom());

Una matriz de ejemplo podría ser

$array = [ ''doc'' => [ ''fruit'' => ''orange'', ''cake'' => [ ''@id'' => ''123'', ''@'' => ''tiramisu'' ], [ ''pasta'' => ''matriciana'' ], [ ''pasta'' => ''boscaiola'' ] ] ];

FluidXML


De todos modos ... Tomé el código de onokazu (¡gracias!) Y agregué la capacidad de tener etiquetas repetidas en XML, también admite atributos, ¡espero que alguien lo encuentre útil!

<?php function array_to_xml(array $arr, SimpleXMLElement $xml) { foreach ($arr as $k => $v) { $attrArr = array(); $kArray = explode('' '',$k); $tag = array_shift($kArray); if (count($kArray) > 0) { foreach($kArray as $attrValue) { $attrArr[] = explode(''='',$attrValue); } } if (is_array($v)) { if (is_numeric($k)) { array_to_xml($v, $xml); } else { $child = $xml->addChild($tag); if (isset($attrArr)) { foreach($attrArr as $attrArrV) { $child->addAttribute($attrArrV[0],$attrArrV[1]); } } array_to_xml($v, $child); } } else { $child = $xml->addChild($tag, $v); if (isset($attrArr)) { foreach($attrArr as $attrArrV) { $child->addAttribute($attrArrV[0],$attrArrV[1]); } } } } return $xml; } $test_array = array ( ''bla'' => ''blub'', ''foo'' => ''bar'', ''another_array'' => array ( array(''stack'' => ''overflow''), array(''stack'' => ''overflow''), array(''stack'' => ''overflow''), ), ''foo attribute1=value1 attribute2=value2'' => ''bar'', ); $xml = array_to_xml($test_array, new SimpleXMLElement(''<root/>''))->asXML(); echo "$xml/n"; $dom = new DOMDocument; $dom->preserveWhiteSpace = FALSE; $dom->loadXML($xml); $dom->formatOutput = TRUE; echo $dom->saveXml(); ?>


Desde PHP 5.4

function array2xml($data, $root = null){ $xml = new SimpleXMLElement($root ? ''<'' . $root . ''/>'' : ''<root/>''); array_walk_recursive($data, function($value, $key)use($xml){ $xml->addChild($key, $value); }); return $xml->asXML(); }


Encontré esta solución similar al problema original.

<?php $test_array = array ( ''bla'' => ''blub'', ''foo'' => ''bar'', ''another_array'' => array ( ''stack'' => ''overflow'', ), ); class NoSimpleXMLElement extends SimpleXMLElement { public function addChild($name,$value) { parent::addChild($value,$name); } } $xml = new NoSimpleXMLElement(''<root/>''); array_walk_recursive($test_array, array ($xml, ''addChild'')); print $xml->asXML();


Encontré todas las respuestas para usar demasiado código. Aquí hay una manera fácil de hacerlo:

function to_xml(SimpleXMLElement $object, array $data) { foreach ($data as $key => $value) { if (is_array($value)) { $new_object = $object->addChild($key); to_xml($new_object, $value); } else { // if the key is an integer, it needs text with it to actually work. if ($key == (int) $key) { $key = "key_$key"; } $object->addChild($key, $value); } } }

Entonces es una simple cuestión de enviar la matriz a la función, que utiliza la recursión, por lo que manejará una matriz multidimensional:

$xml = new SimpleXMLElement(''<rootTag/>''); to_xml($xml, $my_array);

Ahora $ xml contiene un hermoso objeto XML basado en su matriz, exactamente cómo lo escribió.

print $xml->asXML();


Habría comentado la segunda respuesta más votada, porque no conserva la estructura y genera un xml incorrecto si hay matrices internas indexadas numéricamente.

Desarrollé mi propia versión basada en ella, porque necesitaba un simple conversor entre json y xml, independientemente de la estructura de los datos. Mi versión conserva la información de la clave numérica y la estructura de la matriz original. Crea elementos para los valores indexados numéricamente, envolviendo los valores en elementos de valor nominal con un atributo clave que contiene una clave numérica.

Por ejemplo

array(''test'' => array(0 => ''some value'', 1 => ''other''))

se convierte a

<test><value key="0">some value</value><value key="1">other</value></test>

Mi versión de array_to_xml -function (espero que ayude a alguien :)

function array_to_xml($arr, &$xml) { foreach($arr as $key => $value) { if(is_array($value)) { if(!is_numeric($key)){ $subnode = $xml->addChild("$key"); } else { $subnode = $xml->addChild("value"); $subnode->addAttribute(''key'', $key); } array_to_xml($value, $subnode); } else { if (is_numeric($key)) { $xml->addChild("value", $value)->addAttribute(''key'', $key); } else { $xml->addChild("$key",$value); } } } }


La mayoría de las respuestas anteriores son correctas. Sin embargo, se me ocurrió esta respuesta que resuelve el problema de compatibilidad array_walk_recursive y también el problema de las claves numéricas. También pasó todas las pruebas que hice:

function arrayToXML(Array $array, SimpleXMLElement &$xml) { foreach($array as $key => $value) { // None array if (!is_array($value)) { (is_numeric($key)) ? $xml->addChild("item$key", $value) : $xml->addChild($key, $value); continue; } // Array $xmlChild = (is_numeric($key)) ? $xml->addChild("item$key") : $xml->addChild($key); arrayToXML($value, $xmlChild); } }

También he agregado una clase de prueba para esto que puede encontrar útil:

class ArrayToXmlTest extends PHPUnit_Framework_TestCase { public function setUp(){ } public function tearDown(){ } public function testFuncExists() { $this->assertTrue(function_exists(''arrayToXML'')); } public function testFuncReturnsXml() { $array = array( ''name'' => ''ardi'', ''last_name'' => ''eshghi'', ''age'' => 31, ''tel'' => ''0785323435'' ); $xmlEl = new SimpleXMLElement(''<root/>''); arrayToXml($array, $xmlEl); $this->assertTrue($xmlEl instanceOf SimpleXMLElement); } public function testAssocArrayToXml() { $array = array( ''name'' => ''ardi'', ''last_name'' => ''eshghi'', ''age'' => 31, ''tel'' => ''0785323435'' ); $expectedXmlEl = new SimpleXMLElement(''<root/>''); $expectedXmlEl->addChild(''name'', $array[''name'']); $expectedXmlEl->addChild(''last_name'', $array[''last_name'']); $expectedXmlEl->addChild(''age'', $array[''age'']); $expectedXmlEl->addChild(''tel'', $array[''tel'']); $actualXmlEl = new SimpleXMLElement(''<root/>''); arrayToXml($array, $actualXmlEl); $this->assertEquals($expectedXmlEl->asXML(), $actualXmlEl->asXML()); } public function testNoneAssocArrayToXml() { $array = array( ''ardi'', ''eshghi'', 31, ''0785323435'' ); // Expected xml value $expectedXmlEl = new SimpleXMLElement(''<root/>''); foreach($array as $key => $value) $expectedXmlEl->addChild("item$key", $value); // What the function produces $actualXmlEl = new SimpleXMLElement(''<root/>''); arrayToXml($array, $actualXmlEl); $this->assertEquals($expectedXmlEl->asXML(), $actualXmlEl->asXML()); } public function testNestedMixArrayToXml() { $testArray = array( "goal", "nice", "funny" => array( ''name'' => ''ardi'', ''tel'' =>''07415517499'', "vary", "fields" => array( ''small'', ''email'' => ''[email protected]'' ), ''good old days'' ), "notes" => "come on lads lets enjoy this", "cast" => array( ''Tom Cruise'', ''Thomas Muller'' => array(''age'' => 24) ) ); // Expected xml value $expectedXmlEl = new SimpleXMLElement(''<root/>''); $expectedXmlEl->addChild(''item0'', $testArray[0]); $expectedXmlEl->addChild(''item1'', $testArray[1]); $childEl = $expectedXmlEl->addChild(''funny''); $childEl->addChild("name", $testArray[''funny''][''name'']); $childEl->addChild("tel", $testArray[''funny''][''tel'']); $childEl->addChild("item0", "vary"); $childChildEl = $childEl->addChild("fields"); $childChildEl->addChild(''item0'', ''small''); $childChildEl->addChild(''email'', $testArray[''funny''][''fields''][''email'']); $childEl->addChild("item1", ''good old days''); $expectedXmlEl->addChild(''notes'', $testArray[''notes'']); $childEl2 = $expectedXmlEl->addChild(''cast''); $childEl2->addChild(''item0'', ''Tom Cruise''); $childChildEl2 = $childEl2->addChild(''Thomas Muller''); $childChildEl2->addChild(''age'', $testArray[''cast''][''Thomas Muller''][''age'']); // What the function produces $actualXmlEl = new SimpleXMLElement(''<root/>''); arrayToXml($testArray, $actualXmlEl); $this->assertEquals($expectedXmlEl->asXML(), $actualXmlEl->asXML()); } }


Las respuestas proporcionadas aquí solo convierten la matriz a XML con nodos, no puede establecer atributos. He escrito una función php que le permite convertir una matriz a php y también establecer atributos para nodos particulares en el xml. La desventaja aquí es que tienes que construir una matriz de una manera particular con pocas convenciones (solo si quieres usar atributos)

El siguiente ejemplo le permitirá establecer atributos en XML también.

El ejemplo detallado y el uso se pueden encontrar aquí: http://www.lalit.org/lab/convert-php-array-to-xml-with-attributes/

<?php $books = array( ''@attributes'' => array( ''type'' => ''fiction'' ), ''book'' => array( array( ''@attributes'' => array( ''author'' => ''George Orwell'' ), ''title'' => ''1984'' ), array( ''@attributes'' => array( ''author'' => ''Isaac Asimov'' ), ''title'' => ''Foundation'', ''price'' => ''$15.61'' ), array( ''@attributes'' => array( ''author'' => ''Robert A Heinlein'' ), ''title'' => ''Stranger in a Strange Land'', ''price'' => array( ''@attributes'' => array( ''discount'' => ''10%'' ), ''@value'' => ''$18.00'' ) ) ) ); /* creates <books type="fiction"> <book author="George Orwell"> <title>1984</title> </book> <book author="Isaac Asimov"> <title>Foundation</title> <price>$15.61</price> </book> <book author="Robert A Heinlein"> <title>Stranger in a Strange Land</title> <price discount="10%">$18.00</price> </book> </books> */ ?>


Mi respuesta, improvisando las respuestas de otros. Esto debería corregir la falla para compensar las teclas numéricas:

function array_to_xml($array, $root, $element) { $xml = new SimpleXMLElement("<{$root}/>"); foreach ($array as $value) { $elem = $xml->addChild($element); xml_recurse_child($elem, $value); } return $xml; } function xml_recurse_child(&$node, $child) { foreach ($child as $key=>$value) { if(is_array($value)) { foreach ($value as $k => $v) { if(is_numeric($k)){ xml_recurse_child($node, array($key => $v)); } else { $subnode = $node->addChild($key); xml_recurse_child($subnode, $value); } } } else { $node->addChild($key, $value); } } }

La función array_to_xml() supone que la matriz está formada primero por teclas numéricas. Si su matriz tenía un elemento inicial, eliminaría las declaraciones foreach() y $elem de la función array_to_xml() y solo pasaría $xml lugar.


Otra mejora:

/** * Converts an array to XML * * @param array $array * @param SimpleXMLElement $xml * @param string $child_name * * @return SimpleXMLElement $xml */ public function arrayToXML($array, SimpleXMLElement $xml, $child_name) { foreach ($array as $k => $v) { if(is_array($v)) { (is_int($k)) ? $this->arrayToXML($v, $xml->addChild($child_name), $v) : $this->arrayToXML($v, $xml->addChild(strtolower($k)), $child_name); } else { (is_int($k)) ? $xml->addChild($child_name, $v) : $xml->addChild(strtolower($k), $v); } } return $xml->asXML(); }

Uso:

$this->arrayToXML($array, new SimpleXMLElement(''<root/>''), ''child_name_to_replace_numeric_integers'');


Podrías usar el XMLParser que he estado trabajando.

$xml = XMLParser::encode(array( ''bla'' => ''blub'', ''foo'' => ''bar'', ''another_array'' => array ( ''stack'' => ''overflow'', ) )); // @$xml instanceof SimpleXMLElement echo $xml->asXML();

Resultaría en:

<?xml version="1.0"?> <root> <bla>blub</bla> <foo>bar</foo> <another_array> <stack>overflow</stack> </another_array> </root>


Puede usar xmlrpc_encode para crear un xml desde una matriz si un xml detallado no es un problema. www.php.net/xmlrpc_encode

tenga cuidado, el xml creado difiere en caso de que use teclas asociativas y / o numéricas

<?php // /params/param/value/struct/member // there is a tag "member" for each element // "member" contains a tag "name". its value is the associative key $xml1 = xmlrpc_encode(array(''a''=>''b'',''c''=>''d'')); $simplexml1 = simplexml_load_string($xml1); print_r($xml1); print_r($simplexml1); // /params/param/value/array/data // there is a tag "data" for each element // "data" doesn''t contain the tag "name" $xml2 = xmlrpc_encode(array(''a'',''b'')); $simplexml2 = simplexml_load_string($xml2); print_r($xml2); print_r($simplexml2); ?>


Puedes usar la siguiente función en tu código directamente,

function artoxml($arr, $i=1,$flag=false){ $sp = ""; for($j=0;$j<=$i;$j++){ $sp.=" "; } foreach($arr as $key=>$val){ echo "$sp&lt;".$key."&gt;"; if($i==1) echo "/n"; if(is_array($val)){ if(!$flag){echo"/n";} artoxml($val,$i+5); echo "$sp&lt;/".$key."&gt;/n"; }else{ echo "$val"."&lt;/".$key."&gt;/n"; } } }

Llame a la función con el primer argumento como su matriz y el segundo argumento debe ser 1, esto se incrementará para una sangría perfecta, y el tercero debe ser verdadero.

por ejemplo, si la variable de matriz a convertir es $ array1, entonces, la llamada sería, la función de llamada debería estar encapsulada con <pre> etiqueta <pre> .

artoxml($array1,1,true);

Consulte la fuente de la página después de ejecutar el archivo, ya que los símbolos <y> no se mostrarán en una página html.


Quería un código que tome todos los elementos dentro de una matriz y los trate como atributos, y todas las matrices como subelementos.

Así que para algo como

array ( ''row1'' => array (''head_element'' =>array("prop1"=>"some value","prop2"=>array("empty"))), "row2"=> array ("stack"=>"overflow","overflow"=>"overflow") );

Obtendría algo como esto

<?xml version="1.0" encoding="utf-8"?> <someRoot> <row1> <head_element prop1="some value"> <prop2 0="empty"/> </head_element> </row1> <row2 stack="overflow" overflow="stack"/> </someRoot>

Para lograr esto, el código está debajo, pero tenga mucho cuidado, es recursivo y puede causar un :)

function addElements(&$xml,$array) { $params=array(); foreach($array as $k=>$v) { if(is_array($v)) addElements($xml->addChild($k), $v); else $xml->addAttribute($k,$v); } } function xml_encode($array) { if(!is_array($array)) trigger_error("Type missmatch xml_encode",E_USER_ERROR); $xml=new SimpleXMLElement(''<?xml version=/'1.0/' encoding=/'utf-8/'?><''.key($array).''/>''); addElements($xml,$array[key($array)]); return $xml->asXML(); }

Es posible que desee agregar verificaciones de la longitud de la matriz para que algún elemento se establezca dentro de la parte de datos y no como un atributo.


Si la matriz es asociativa y está codificada correctamente, probablemente sería más fácil convertirlo primero en xml. Algo como:

function array2xml ($array_item) { $xml = ''''; foreach($array_item as $element => $value) { if (is_array($value)) { $xml .= "<$element>".array2xml($value)."</$element>"; } elseif($value == '''') { $xml .= "<$element />"; } else { $xml .= "<$element>".htmlentities($value)."</$element>"; } } return $xml; } $simple_xml = simplexml_load_string(array2xml($assoc_array));

La otra ruta sería crear primero su xml básico, como

$simple_xml = simplexml_load_string("<array></array>");

y luego para cada parte de su matriz, use algo similar a mi bucle de creación de texto y en su lugar use las funciones simplexml "addChild" para cada nodo de la matriz.

Lo intentaré más tarde y actualizaré esta publicación con ambas versiones.


Si trabajas en Magento y tienes este tipo de matriz asociativa.

$test_array = array ( ''0'' => array ( ''category_id'' => ''582'', ''name'' => ''Surat'', ''parent_id'' => ''565'', ''child_id'' => ''567'', ''active'' => ''1'', ''level'' => ''6'', ''position'' => ''17'' ), ''1'' => array ( ''category_id'' => ''567'', ''name'' => ''test'', ''parent_id'' => ''0'', ''child_id'' => ''576'', ''active'' => ''0'', ''level'' => ''0'', ''position'' => ''18'' ), );

entonces esto es mejor para convertir una matriz asociativa a formato xml. Use este código en el archivo controlador.

$this->loadLayout(false); //header ("content-type: text/xml"); $this->getResponse()->setHeader(''Content-Type'',''text/xml''); $this->renderLayout(); $clArr2xml = new arr2xml($test_array, ''utf-8'', ''listdata''); $output = $clArr2xml->get_xml(); print $output; class arr2xml { var $array = array(); var $xml = ''''; var $root_name = ''''; var $charset = ''''; public function __construct($array, $charset = ''utf-8'', $root_name = ''root'') { header ("content-type: text/xml"); $this->array = $array; $this->root_name = $root_name; $this->charset = $charset; if (is_array($array) && count($array) > 0) { $this->struct_xml($array); } else { $this->xml .= "no data"; } } public function struct_xml($array) { foreach ($array as $k => $v) { if (is_array($v)) { $tag = ereg_replace(''^[0-9]{1,}'', ''item'', $k); // replace numeric key in array to ''data'' $this->xml .= "<$tag>"; $this->struct_xml($v); $this->xml .= "</$tag>"; } else { $tag = ereg_replace(''^[0-9]{1,}'', ''item'', $k); // replace numeric key in array to ''data'' $this->xml .= "<$tag><![CDATA[$v]]></$tag>"; } } } public function get_xml() { $header = "<?xml version=/"1.0/" encoding=/"" . $this->charset . "/"?><" . $this->root_name . ">"; $footer = "</" . $this->root_name . ">"; return $header . $this->xml . $footer; } }

Espero que ayude a todos.


Solo una edición en una función de arriba, cuando una clave es numérica, agregue un prefijo "key_"

// initializing or creating array $student_info = array(your array data); // creating object of SimpleXMLElement $xml_student_info = new SimpleXMLElement("<?xml version=/"1.0/"?><student_info></student_info>"); // function call to convert array to xml array_to_xml($student,$xml_student_info); //saving generated xml file $xml_student_info->asXML(''file path and name''); function array_to_xml($student_info, &$xml_student_info) { foreach($student_info as $key => $value) { if(is_array($value)) { if(!is_numeric($key)){ $subnode = $xml_student_info->addChild("$key"); array_to_xml($value, $subnode); } else{ $subnode = $xml_student_info->addChild("key_$key"); array_to_xml($value, $subnode); } } else { if(!is_numeric($key)){ $xml_student_info->addChild("$key","$value"); }else{ $xml_student_info->addChild("key_$key","$value"); } } } }


Toda la estructura XML se define en $ data Array:

function array2Xml($data, $xml = null) { if (is_null($xml)) { $xml = simplexml_load_string(''<'' . key($data) . ''/>''); $data = current($data); $return = true; } if (is_array($data)) { foreach ($data as $name => $value) { array2Xml($value, is_numeric($name) ? $xml : $xml->addChild($name)); } } else { $xml->{0} = $data; } if (!empty($return)) { return $xml->asXML(); } }


Utilizo un par de funciones que escribí hace un tiempo para generar el xml para pasar de PHP y jQuery, etc ... Ninguno de los marcos adicionales genera simplemente una cadena que se puede usar con SimpleXML (u otro marco) ) ...

Si es útil para alguien, por favor utilízalo :)

function generateXML($tag_in,$value_in="",$attribute_in=""){ $return = ""; $attributes_out = ""; if (is_array($attribute_in)){ if (count($attribute_in) != 0){ foreach($attribute_in as $k=>$v): $attributes_out .= " ".$k."=/"".$v."/""; endforeach; } } return "<".$tag_in."".$attributes_out.((trim($value_in) == "") ? "/>" : ">".$value_in."</".$tag_in.">" ); } function arrayToXML($array_in){ $return = ""; $attributes = array(); foreach($array_in as $k=>$v): if ($k[0] == "@"){ // attribute... $attributes[str_replace("@","",$k)] = $v; } else { if (is_array($v)){ $return .= generateXML($k,arrayToXML($v),$attributes); $attributes = array(); } else if (is_bool($v)) { $return .= generateXML($k,(($v==true)? "true" : "false"),$attributes); $attributes = array(); } else { $return .= generateXML($k,$v,$attributes); $attributes = array(); } } endforeach; return $return; }

Amor a todos :)


otra solución:

$marray=array(....); $options = array( "encoding" => "UTF-8", "output_type" => "xml", "version" => "simple", "escaping" => array("non-ascii, on-print, markup") ); $xmlres = xmlrpc_encode_request(''root'', $marray, $options); print($xmlres);


una corta

<?php $test_array = array ( ''bla'' => ''blub'', ''foo'' => ''bar'', ''another_array'' => array ( ''stack'' => ''overflow'', ), ); $xml = new SimpleXMLElement(''<root/>''); array_walk_recursive($test_array, array ($xml, ''addChild'')); print $xml->asXML();

resultados en

<?xml version="1.0"?> <root> <blub>bla</blub> <bar>foo</bar> <overflow>stack</overflow> </root>

Las claves y los valores se intercambian. Podría arreglar eso con array_flip() antes de array_walk. array_walk_recursive requiere PHP 5. en su lugar, podría usar array_walk , pero no obtendrá ''stack'' => ''overflow'' en el xml.


// Structered array for XML convertion. $data_array = array( array( ''#xml_tag'' => ''a'', ''#xml_value'' => '''', ''#tag_attributes'' => array( array( ''name'' => ''a_attr_name'', ''value'' => ''a_attr_value'', ), ), ''#subnode'' => array( array( ''#xml_tag'' => ''aa'', ''#xml_value'' => ''aa_value'', ''#tag_attributes'' => array( array( ''name'' => ''aa_attr_name'', ''value'' => ''aa_attr_value'', ), ), ''#subnode'' => FALSE, ), ), ), array( ''#xml_tag'' => ''b'', ''#xml_value'' => ''b_value'', ''#tag_attributes'' => FALSE, ''#subnode'' => FALSE, ), array( ''#xml_tag'' => ''c'', ''#xml_value'' => ''c_value'', ''#tag_attributes'' => array( array( ''name'' => ''c_attr_name'', ''value'' => ''c_attr_value'', ), array( ''name'' => ''c_attr_name_1'', ''value'' => ''c_attr_value_1'', ), ), ''#subnode'' => array( array( ''#xml_tag'' => ''ca'', ''#xml_value'' => ''ca_value'', ''#tag_attributes'' => FALSE, ''#subnode'' => array( array( ''#xml_tag'' => ''caa'', ''#xml_value'' => ''caa_value'', ''#tag_attributes'' => array( array( ''name'' => ''caa_attr_name'', ''value'' => ''caa_attr_value'', ), ), ''#subnode'' => FALSE, ), ), ), ), ), ); // creating object of SimpleXMLElement $xml_object = new SimpleXMLElement(''<?xml version=/"1.0/"?><student_info></student_info>''); // function call to convert array to xml array_to_xml($data_array, $xml_object); // saving generated xml file $xml_object->asXML(''/tmp/test.xml''); /** * Converts an structured PHP array to XML. * * @param Array $data_array * The array data for converting into XML. * @param Object $xml_object * The SimpleXMLElement Object * * @see https://gist.github.com/drupalista-br/9230016 * */ function array_to_xml($data_array, &$xml_object) { foreach($data_array as $node) { $subnode = $xml_object->addChild($node[''#xml_tag''], $node[''#xml_value'']); if ($node[''#tag_attributes'']) { foreach ($node[''#tag_attributes''] as $tag_attributes) { $subnode->addAttribute($tag_attributes[''name''], $tag_attributes[''value'']); } } if ($node[''#subnode'']) { array_to_xml($node[''#subnode''], $subnode); } } }


lo siguiente trata con los espacios de nombres. En este caso, usted construye el contenedor para incluir las definiciones de espacio de nombres y lo pasa a la función. Usa dos puntos para identificar el espacio de nombres.

Matriz de prueba

$inarray = []; $inarray[''p:apple''] = "red"; $inarray[''p:pear''] = "green"; $inarray[''p:peach''] = "orange"; $inarray[''p1:grocers''] = [''p1:local'' => "cheap", ''p1:imported'' => "expensive"]; $xml = new SimpleXMLElement( ''<p:wrapper xmlns:p="http://namespace.org/api" xmlns:p1="http://namespace.org/api2 /> ''); array_to_xml($xml,$inarray); function array_to_xml(SimpleXMLElement $object, array $data) { $nslist = $object->getDocNamespaces(); foreach ($data as $key => $value) { $nspace = null; $keyparts = explode(":",$key,2); if ( count($keyparts)==2) $nspace = $nslist[$keyparts[0]]; if (is_array($value)) { $key = is_numeric($key) ? "item$key" : $key; $new_object = $object->addChild($key,null,$nspace); array_to_xml($new_object, $value); } else { $key = is_numeric($key) ? "item$key" : $key; $object->addChild($key, $value,$nspace); } } }


<?php function array_to_xml(array $arr, SimpleXMLElement $xml) { foreach ($arr as $k => $v) { is_array($v) ? array_to_xml($v, $xml->addChild($k)) : $xml->addChild($k, $v); } return $xml; } $test_array = array ( ''bla'' => ''blub'', ''foo'' => ''bar'', ''another_array'' => array ( ''stack'' => ''overflow'', ), ); echo array_to_xml($test_array, new SimpleXMLElement(''<root/>''))->asXML();


function array2xml($array, $xml = false){ if($xml === false){ $xml = new SimpleXMLElement(''<?xml version=/'1.0/' encoding=/'utf-8/'?><''.key($array).''/>''); $array = $array[key($array)]; } foreach($array as $key => $value){ if(is_array($value)){ $this->array2xml($value, $xml->addChild($key)); }else{ $xml->addChild($key, $value); } } return $xml->asXML(); }


function toXML($data, $obj = false, $dom) { $is_first_level = false; if($obj === false) { $dom = new DomDocument(''1.0''); $obj = $dom; $is_first_level = true; } if(is_array($data)) { foreach($data as $key => $item) { $this->toXML($item, $obj->appendChild($dom->createElement($key)), $dom); } }else { $obj->appendChild($dom->createTextNode($data)); } if($is_first_level) { $obj->formatOutput = true; return $obj->saveXML(); } return $obj; }