4 Stimmen

Extrahieren von Daten aus einer XML-Datei mit SimpleXML in PHP

Einleitung:

Ich möchte eine Schleife durch XML-Dateien mit flexibler Kategoriestruktur erstellen.

Problem:

Ich weiß nicht, wie ich eine Schleife durch eine theoretisch unendliche Anzahl von Unterkategorien durchlaufen kann, ohne x-mal "for each"-Anweisungen machen zu müssen (siehe Codierungsbeispiel unten). Wie kann ich die Struktur der Kategorien dynamisch durchlaufen?

<?xml version="1.0" encoding="utf-8"?>
<catalog>
    <category name="Category - level 1">
        <category name="Category - level 2" />
        <category name="Category - level 2">
            <category name="Category - level 3" />
        </category>
        <category name="Category - level 2">
            <category name="Category - level 3">
                <category name="Category - level 4" />
            </category>
        </category>
    </category>
</catalog>

Was ich jetzt habe:

Ich habe kein Problem damit, XML-Dateien mit einer bestimmten Struktur in einer Schleife zu durchlaufen:

<catalog>
    <category name="Category - level 1">
        <category name="Category - level 2">
            <category name="Category - level 3" />
        </category>
        <category name="Category - level 2">
            <category name="Category - level 3" />
        </category>
    </category>
</catalog>

Beispiel für die Codierung:

//$xml holds the XML file
foreach ( $xml AS $category_level1 )
{
    echo $category_level1['name'];

    foreach ( $category_level1->category AS $category_level2 )
    {
        echo $category_level2['name'];

        foreach ( $category_level2->category AS $category_level3 )
        {
           echo $category_level3['name'];
        }
    }
}

6voto

Gordon Punkte 304254

Die Namensattribute Ihrer Kategorien lassen sich wahrscheinlich am schnellsten über XPath ermitteln, z. B.

$categoryNames = $doc->xpath('//category/@name');

Wenn Sie jedoch rekursiv über eine beliebige verschachtelte XML-Struktur iterieren wollen, können Sie auch die SimpleXMLIterator z.B. mit $xml ist die von Ihnen angegebene Zeichenfolge:

$sxi = new RecursiveIteratorIterator(
           new SimpleXMLIterator($xml), 
           RecursiveIteratorIterator::SELF_FIRST);

foreach($sxi as $node) {
    echo str_repeat("\t", $sxi->getDepth()), // indenting
         $node['name'],                      // getting attribute name
         PHP_EOL;                            // line break
}

wird geben

Category - level 1
    Category - level 2
    Category - level 2
        Category - level 3
    Category - level 2
        Category - level 3
            Category - level 4

Wie eingangs erwähnt, sollten Sie XPath verwenden, wenn Sie nur alle Namensattribute abrufen wollen, da die Iteration über jeden einzelnen Knoten langsam ist. Verwenden Sie diesen Ansatz nur, wenn Sie komplexere Dinge mit den Knoten tun wollen, zum Beispiel etwas zu ihnen hinzufügen.

2voto

Amy B Punkte 17616
<?php
$xml= new SimpleXMLElement('.....');
foreach ($xml->xpath('//category') as $cat)
{
    echo $cat['name'];
}

1voto

VolkerK Punkte 93746

Verwendung von simplexml und xpath als gut
...aber nur als Nebenbemerkung, wenn Sie nur das Namensattribut von jedem einzelnen <category> Element im Dokument DOMDocument::getElementsByTagName() würde ausreichen.
Sie können zwischen DOM und simplexml umschalten über dom_import_simplexml() y simplexml_import_dom() . Beide verwenden die gleiche interne Darstellung der Daten, so dass keine kostspielige Konvertierung erforderlich ist.

$xml = '<?xml version="1.0" encoding="utf-8"?>
<catalog>
    <category name="Category - level 1">
        <category name="Category - level 2" />
        <category name="Category - level 2">
            <category name="Category - level 3" />
        </category>
        <category name="Category - level 2">
            <category name="Category - level 3">
                <category name="Category - level 4" />
            </category>
        </category>
    </category>
</catalog>';

$doc = new DOMDocument;
$doc->loadxml($xml);

foreach( $doc->getElementsByTagName('category') as $c) {
  echo $c->getAttribute('name'), "\n";
}

druckt

Category - level 1
Category - level 2
Category - level 2
Category - level 3
Category - level 2
Category - level 3
Category - level 4

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X