Cómo ordenar un archivo xml usando DOM

Tengo un archivo xml estructurado como

   Jquery MVC Me 500   Php Me 600   Where to use IFrame Me 300   

Para ordenar este xml de acuerdo con la identificación del libro,

después de revisar este método de stackoverflow

codifiqué así

 $dom = new DOMDocument(); $dom->load('DOM.xml'); $library = $dom->documentElement; $xpath = new DOMXPath($dom); $result = $xpath->query('/library/book'); function sort_trees($t1,$t2){ return strcmp($t1['id'], $t2['id']); } usort($result, 'sort_trees'); print_r($result);*/ 

Pero me da un error

Advertencia: usort () espera que el parámetro 1 sea una matriz, objeto dado en /var/www/html/testphp/phpxml/readxml.php en la línea 24

La respuesta que citas es para SimpleXML, pero estás usando DOMDocument.

Si desea continuar utilizando DOMDocument, debe tener en cuenta su API.

 $dom = new DOMDocument(); $dom->load('DOM.xml'); $xp = new DOMXPath($dom); $booklist = $xp->query('/library/book'); // Books is a DOMNodeList, not an array. // This is the reason for your usort() warning. // Copies DOMNode elements in the DOMNodeList to an array. $books = iterator_to_array($booklist); // Second, your sorting function is using the wrong API // $node['id'] is SimpleXML syntax for attribute access. // DOMElement uses $node->getAttribute('id'); function sort_by_numeric_id_attr($a, $b) { return (int) $a->getAttribute('id') - (int) $b->getAttribute('id'); } // Now usort() usort($books, 'sort_by_numeric_id_attr'); // verify: foreach ($books as $book) { echo $book->C14N(), "\n"; } 

Si necesita crear un nuevo documento de salida con los nodos ordenados, cree un nuevo documento, importe el elemento raíz, luego importe los nodos del libro en orden ordenado y agréguelo al documento.

 $newdoc = new DOMDocument('1.0', 'UTF-8'); $libraries = $newdoc->appendChild($newdoc->importNode($dom->documentElement)); foreach ($books as $book) { $libraries->appendChild($newdoc->importNode($book, true)); } echo $newdoc->saveXML(); 

Sin embargo, un enfoque mucho mejor es usar XSLT:

 < ?xml version="1.0" encoding="UTF-8" ?>                

Luego use XSLTProcessor (o xsltproc desde la línea de comando):

 $xsltdoc = new DOMDocument(); $xsltdoc->load('sort_by_numeric_id.xsl'); $xslt = new XSLTProcessor(); $xslt->importStyleSheet($xsltdoc); // You can now use $xslt->transformTo*() methods over and over on whatever documents you want $libraryfiles = array('library1.xml', 'library2.xml'); foreach ($libraryfiles as $lf) { $doc = new DOMDocument(); $doc->load($lf); // write the new document $xslt->transformToUri($doc, 'file://'.preg_replace('/(\.[^.]+)?$/', '-sorted$0', $lf, 1); unset($doc); // just to save memory } 

(copiado de tu pregunta duplicada) Esto funciona

 $dom = new DOMDocument(); $dom->load('dom.xml'); $xp = new DOMXPath($dom); $booklist = $xp->query('/library/book'); $books = iterator_to_array($booklist); function sort_by_numeric_id_attr($a, $b) { return (int) $a->getAttribute('id') - (int) $b->getAttribute('id'); } usort($books, 'sort_by_numeric_id_attr'); $newdom = new DOMDocument("1.0"); $newdom->formatOutput = true; $root = $newdom->createElement("library"); $newdom->appendChild($root); foreach ($books as $b) { $node = $newdom->importNode($b,true); $root->appendChild($newdom->importNode($b,true)); } $newdom->save('DOM2.xml'); 

Como puede ver, necesita crear un nuevo DOMDocument y agregarle los elementos ordenados (a través de importNode para copiar los DOMNodes de un DOMDocument a otro).