Frage an php, sorting, xml – So sortieren Sie eine XML-Datei mit DOM

3

Ich habe eine XML-Datei wie folgt aufgebaut

<code><?xml version="1.0"?>
 <library>
<book id="1003">
    <title>Jquery MVC</title>
    <author>Me</author>
    <price>500</price>
</book>
<book id="1001">
    <title>Php</title>
    <author>Me</author>
    <price>600</price>
</book>
<book id="1002">
    <title>Where to use IFrame</title>
    <author>Me</author>
    <price>300</price>
</book>
</library>
</code>

Um diese XML nach der Buch-ID zu sortieren,

nach der Überprüfungdiese Methode von Stackoverflow

Ich habe so codiert

<code>$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);*/
</code>

Aber es gibt mir einen Fehler

Warnung: usort () erwartet, dass Parameter 1 ein Array ist, ein Objekt, das in /var/www/html/testphp/phpxml/readxml.php in Zeile 24 angegeben ist

Deine Antwort

2   die antwort
0

(kopiert von Ihrer doppelten Frage) Dies funktioniert

<code>$dom = new DOMDocument();
$dom->load('dom.$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.
</code>

Wie Sie sehen, müssen Sie ein neues DOMDocument erstellen und die sortierten untergeordneten Elemente hinzufügen (über importNode, um die DOMNodes von einem DOMDocument in ein anderes zu kopieren).

10

Sie verwenden jedoch DOMDocument.

Wenn Sie DOMDocument weiterhin verwenden möchten, müssen Sie die API berücksichtigen.

<code>$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";
}
</code>

Wenn Sie ein neues Ausgabedokument mit sortierten Knoten erstellen müssen, erstellen Sie ein neues Dokument, importieren Sie das Stammelement, importieren Sie dann die Buchknoten in sortierter Reihenfolge und fügen Sie sie dem Dokument hinzu.

<code>$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();
</code>

Ein viel besserer Ansatz ist jedoch die Verwendung von XSLT:

<code><?xml version="1.0" encoding="UTF-8" ?>
<!-- file "sort_by_numeric_id.xsl" -->
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output encoding="UTF-8" method="xml" />

<xsl:template match="node()|@*">
    <xsl:copy><xsl:apply-templates select="node()|@*"/></xsl:copy>
</xsl:template>

<xsl:template match="/*">
    <xsl:copy>
        <xsl:apply-templates select="@*"/>
        <xsl:apply-templates select="*">
            <xsl:sort select="@id" data-type="number"/>
        </xsl:apply-templates>
    </xsl:copy>
</xsl:template>

</xsl:stylesheet>
</code>

Verwenden Sie dann XSLTProcessor (oderxsltproc von der Kommandozeile aus):

<code>$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
}
</code>
Wie Sie bereits sagten, wie könnte ich XML-Datei in eine Zeichenfolge konvertieren? user1066679
$dom->loadXML(file_load_contents('filename.xml'))  tutgenau das gleiche wie$dom->load('filename.xml'). Es spielt keine Rolle, welche Sie verwenden. Francis Avila
Vielen Dank für Ihre wertvolle Zeit und Antwort user1066679
Sie tun etwas sehr Grundlegendes falsch mit dem Laden Ihrer XML. Ihre XML ist möglicherweise keine Zeichenfolge, oder die Zeichenfolge ist möglicherweise ungültig.->load('filename.xml') lädt eine Datei,->loadXML('<root/>') Lädt einen String. Francis Avila

Verwandte Fragen