tutorial simplexmlelement simplexml_load_file leer convertir array archivo php xml simplexml

php - simplexml_load_file - simplexmlelement object



Ordenar XML a través del valor de atributo PHP (6)

Así que tengo un archivo XML que estoy tratando de recorrer en orden, de acuerdo con el atributo, "orden".

Aquí hay un ejemplo:

<page> <talentTrees> <tree name="Football" order="2"> <tree name="Baseball" order="0"> <tree name="Frisbee" order="1"> </talentTrees> </page>

Mi objetivo es recorrer cada "árbol" utilizando foreach, pero quiero leerlos en orden del atributo de orden: Béisbol, Frisbee, Fútbol. (0,1,2).

Lo siento por un inglés pobre, no es mi primer idioma.


Si tienes muchos elementos como este

$string = <<<EOS <page> <talentTrees> <tree name="Football" order="2" /> <tree name="Baseball" order="0" /> <tree name="Frisbee" order="1" /> </talentTrees> <talentTrees> <tree name="Football2" order="1" /> <tree name="Baseball2" order="2" /> <tree name="Frisbee2" order="0" /> </talentTrees> </page> EOS;

Puedes usar foreach :

$xml = simplexml_load_string($string); function sort_trees($t1, $t2) { return $t1[''order''] - $t2[''order'']; } foreach($xml->talentTrees as $talentTrees){ foreach($talentTrees->tree as $tree){ $trees[]= $tree; } usort($trees, ''sort_trees''); print_r($trees); unset($trees); }

salida:

Array ( [0] => Array ( [0] => SimpleXMLElement Object ( [@attributes] => Array ( [name] => Baseball [order] => 0 ) ) [1] => SimpleXMLElement Object ( [@attributes] => Array ( [name] => Frisbee [order] => 1 ) ) [2] => SimpleXMLElement Object ( [@attributes] => Array ( [name] => Football [order] => 2 ) ) ) [1] => Array ( [0] => SimpleXMLElement Object ( [@attributes] => Array ( [name] => Frisbee2 [order] => 0 ) ) [1] => SimpleXMLElement Object ( [@attributes] => Array ( [name] => Football2 [order] => 1 ) ) [2] => SimpleXMLElement Object ( [@attributes] => Array ( [name] => Baseball2 [order] => 2 ) ) ) )

Para otro ejemplo: https://.com/a/44379495/3506219


Esto debería darte lo que quieres:

$string = <<<EOS <page> <talentTrees> <tree name="Football" order="2" /> <tree name="Baseball" order="0" /> <tree name="Frisbee" order="1" /> </talentTrees> </page> EOS; $xml = simplexml_load_string($string); $trees = $xml->xpath(''/page/talentTrees/tree''); function sort_trees($t1, $t2) { return strcmp($t1[''order''], $t2[''order'']); } usort($trees, ''sort_trees''); var_dump($trees);

$trees ahora están ordenados por el atributo order.


Esta página da algunos ejemplos geniales que adelgazo podrías usar


Escribí una versión recursiva y expandida que ordenará por cualquier cantidad de atributos, en orden:

//sort_xml_by_attr($simplexmlobject,array(''attr_one'',''attr_two'',''attr_three'')) class SortXML { public $xml; var $attr; function SortXML($xml,$attr) { $this->xml = $xml; $this->attr = $attr; } function cmp_attr($a,$b) { $a1 = (string)$a->xml[(string)$a->attr]; $b1 = (string)$b->xml[(string)$b->attr]; if (is_numeric($a1) && is_numeric($b1)) { if (is_float($a1) && is_float($b1)) { $a1 = (float)$a1; $b1 = (float)$b1; } else { $a1 = (int)$a1; $b1 = (int)$b1; } } if ($a1 == $b1) return 0; return ($a1 > $b1) ? +1 : -1; } } function sort_xml_by_attr($xml_obj,$attr) { if (count($attr)>1) { // break up array by unique values of the first attribute in the list $unique_attrs = array(); foreach ($xml_obj as $i) $unique_attrs[] = (string)$i[$attr[0]]; $unique_attrs = array_unique($unique_attrs); sort($unique_attrs); // create an array of arrays who share a unique attribute value foreach ($unique_attrs as $i) { foreach ($xml_obj as $p) { if ($p[$attr[0]] == $i) $xml_arrays[$i][] = $p; } } // remove first element to progress the recursion to the next attribute array_shift($attr); $new_array = array(); // concatenate sorted arrays foreach ($xml_arrays as $i) { $new_array = array_merge($new_array,sort_xml_by_attr($i,$attr)); } return $new_array; } else { // create wrapper objects with new comparison function foreach ($xml_obj as $i) $new_obj[] = new SortXML($i,$attr[0]); usort($new_obj,array(''SortXML'',''cmp_attr'')); foreach ($new_obj as $i) $sorted_obj[] = $i->xml; return $sorted_obj; } }


Para futuras referencias, aquí hay algo que puede usar para consultar nodos a través de XPath y también puede ordenar el resultado a través de XPath: SimpleDOM . En este ejemplo, ordeno todos los nodos <tree/> por valores del atributo order :

include ''SimpleDOM.php''; $page = simpledom_load_string(''<page> <talentTrees> <tree name="Football" order="2"/> <tree name="Baseball" order="0"/> <tree name="Frisbee" order="1"/> </talentTrees> </page>''); $nodes = $page->sortedXPath(''//tree'', ''@order''); foreach ($nodes as $node) { echo $node->asXML(), "/n"; }