Start · Sprachen · PHP · Referenz · xml_parse_into_struct

xml_parse_into_struct

Funktion

Parst einen XML-String und speichert die Elementdaten in zwei Arrays: <code>$values</code> für die Inhalte und <code>$index</code> für die Indizes.

seit PHP 4.0.0 Kategorie: xml

Signatur

xml_parse_into_struct(XMLParser $parser, string $data, array &$values, array &$index = []): int|false

Beschreibung

xml_parse_into_struct() parst einen XML-String mithilfe eines zuvor mit xml_parser_create() erzeugten Parsers und füllt zwei Arrays: $values enthält für jedes XML-Ereignis (Tag-Öffnung, Tag-Schließung, Inhalt) einen assoziativen Eintrag mit den Schlüsseln tag, type, level, value und ggf. attributes. Das optionale $index-Array ordnet jedem Tag-Namen ein Array von Positionen in $values zu.

Der Typ eines Eintrags in $values kann folgende Werte annehmen: open (öffnendes Tag), close (schließendes Tag), complete (ein in sich geschlossenes Element wie <tag/> oder <tag>Text</tag>) und cdata (reiner Textinhalt zwischen Tags, der keinem einzelnen Element zuzuordnen ist).

Die Funktion eignet sich besonders dann, wenn das gesamte XML-Dokument überschaubar klein ist und man schnell auf strukturierte Daten zugreifen möchte, ohne ein DOM oder SimpleXML-Objektmodell aufbauen zu müssen. Für sehr große XML-Dateien empfiehlt sich ein ereignisbasierter Ansatz mit den Expat-Handler-Funktionen, da xml_parse_into_struct() das gesamte Dokument auf einmal verarbeitet.

Nach der Verwendung sollte der Parser mit xml_parser_free() freigegeben werden, um Ressourcen zu schonen.

Parameter

Name Typ Default Beschreibung
$parser Pflicht XMLParser Eine gültige XML-Parser-Ressource/Instanz, die zuvor mit xml_parser_create() oder xml_parser_create_ns() erzeugt wurde.
$data Pflicht string Der zu parsende XML-String. Muss wohlgeformtes XML enthalten.
$values Pflicht array Wird per Referenz übergeben und nach dem Aufruf mit den geparsten XML-Ereignissen gefüllt. Jeder Eintrag ist ein assoziatives Array mit den Schlüsseln tag, type, level, sowie optional value und attributes.
$index array [] Wird per Referenz übergeben und nach dem Aufruf mit einer Zuordnung von Tag-Namen (in Großbuchstaben) zu Arrays von Positionen in $values gefüllt. Erleichtert das gezielte Auffinden aller Vorkommen eines bestimmten Tags.

Rückgabewert

Typ
int|false
Beschreibung
Gibt 1 bei Erfolg zurück, 0 bei einem Fehler (z. B. ungültiges XML). Im Fehlerfall können xml_get_error_code() und xml_error_string() zur Diagnose genutzt werden. Gibt false zurück, wenn $parser ungültig ist.

Beispiele

Einfaches XML-Dokument parsen und Struktur ausgeben

<?php
$xml = <<<XML
<?xml version="1.0" encoding="UTF-8"?>
<buecher>
  <buch id="1">
    <titel>PHP Praxis</titel>
    <autor>Max Mustermann</autor>
  </buch>
  <buch id="2">
    <titel>XML verstehen</titel>
    <autor>Erika Musterfrau</autor>
  </buch>
</buecher>
XML;

$parser = xml_parser_create('UTF-8');
xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, 0);

$values = [];
$index  = [];

$result = xml_parse_into_struct($parser, $xml, $values, $index);
xml_parser_free($parser);

if ($result === 0) {
    echo 'Fehler beim Parsen des XML.';
    exit;
}

echo 'Alle Einträge in \$values:' . PHP_EOL;
foreach ($values as $pos => $entry) {
    printf(
        "[%d] Tag: %-10s | Type: %-8s | Level: %d | Value: %s\n",
        $pos,
        $entry['tag'],
        $entry['type'],
        $entry['level'],
        $entry['value'] ?? ''
    );
}

echo PHP_EOL . 'Index für "titel":' . PHP_EOL;
print_r($index['titel']);
[0] Tag: buecher | Type: open | Level: 1 | Value: [1] Tag: buch | Type: open | Level: 2 | Value: [2] Tag: titel | Type: complete | Level: 3 | Value: PHP Praxis [3] Tag: autor | Type: complete | Level: 3 | Value: Max Mustermann [4] Tag: buch | Type: close | Level: 2 | Value: [5] Tag: buch | Type: open | Level: 2 | Value: [6] Tag: titel | Type: complete | Level: 3 | Value: XML verstehen [7] Tag: autor | Type: complete | Level: 3 | Value: Erika Musterfrau [8] Tag: buch | Type: close | Level: 2 | Value: [9] Tag: buecher | Type: close | Level: 1 | Value: Index für "titel": Array ( [0] => 2 [1] => 6 )

Attribute aus geparsten Elementen auslesen

<?php
$xml = <<<XML
<?xml version="1.0"?>
<produkte>
  <produkt sku="A001" verfuegbar="ja">Tastatur</produkt>
  <produkt sku="B002" verfuegbar="nein">Monitor</produkt>
</produkte>
XML;

$parser = xml_parser_create();
xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, 0);

$values = [];
$index  = [];

xml_parse_into_struct($parser, $xml, $values, $index);
xml_parser_free($parser);

foreach ($index['produkt'] as $pos) {
    $entry = $values[$pos];
    if ($entry['type'] === 'complete') {
        $sku   = $entry['attributes']['sku']        ?? '-';
        $verf  = $entry['attributes']['verfuegbar'] ?? '-';
        $name  = $entry['value']                    ?? '-';
        echo "SKU: $sku | Verfügbar: $verf | Name: $name\n";
    }
}
SKU: A001 | Verfügbar: ja | Name: Tastatur SKU: B002 | Verfügbar: nein | Name: Monitor

// Wichtig · Fallstricke

Zeichenkodierung: Standardmäßig arbeitet der Parser mit ISO-8859-1. Soll UTF-8 verarbeitet werden, muss beim Erzeugen des Parsers xml_parser_create('UTF-8') angegeben werden. Ein falsch gesetztes Encoding führt zu korrumpierten Sonderzeichen.

Groß-/Kleinschreibung: Standardmäßig werden alle Tag-Namen in Großbuchstaben umgewandelt (XML_OPTION_CASE_FOLDING ist aktiv). Soll die originale Schreibweise erhalten bleiben, muss die Option explizit deaktiviert werden: xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, 0). Dies betrifft auch die Schlüssel im $index-Array.

Speicherverbrauch: Da die gesamte XML-Struktur in Arrays im Arbeitsspeicher gehalten wird, ist die Funktion für sehr große XML-Dokumente (mehrere MB) nicht optimal. In solchen Fällen sollte ein SAX-basierter Ansatz mit xml_set_element_handler() bevorzugt werden.

Namespace-Unterstützung: Bei Verwendung von xml_parser_create_ns() werden Namespace-URIs in die Tag-Namen eingebettet. Das muss bei der Auswertung der Arrays berücksichtigt werden.