Lesen von Kind-Knoten mit XMLReader
Ich versuche zu schreiben, XMLReader/SimpleXML hybrid-Funktion zu Lesen, eine sehr große (700MB) XML-Datei. Die XML-Datei in diesem format:
<Items>
<Item>
<ItemKey>ABCDEF123</ItemKey>
<Name>
<English>An Item Name</English>
<German>An Item Name In German</German>
<French>An Item Name In French</French>
</Name>
<Description>
<English>An Item Description</English>
<German>An Item Description In German</German>
<French>An Item Description In French</French>
</Description>
</Item>
<Item>
<ItemKey>GHIJKL456</ItemKey>
<Name>
<English>Another Item Name</English>
<German>Another Item Name In German</German>
<French>Another Item Name In French</French>
</Name>
<Description>
<English>Another Item Description</English>
<German>Another Item Description In German</German>
<French>Another Item Description In French</French>
</Description>
</Item>
</Items>
Den code, den ich bisher geschrieben haben, um dies zu tun:
$xml = new XMLReader();
if(!$xml->open('testitems.xml')){
die('Failed to open file!');
} else {
echo 'File opened';
}
$items = array();
while ($xml->read()){
if($xml->nodeType == XMLReader::ELEMENT){
if ($xml->name == 'Item'){
$item = array();
}
if ($xml->name == 'ItemKey'){
$xml->read();
$item['itemKey'] = $xml->value;
}
if ($xml->name == 'Name'){
$sxml = new SimpleXMLElement($xml->readOuterXml());
$englishName = $sxml->English;
$item['englishName'] = $englishName;
}
}
if($xml->nodeType == XMLReader::END_ELEMENT){
if ($xml->name == 'Item'){
$items[] = $item;
}
}
}
var_dump($items);
$xml->close();
Jedoch während der ItemKey Knoten-Wert wird in das array eingefügt, der englische Name ist nicht, ich kann nicht scheinen, um Zugriff auf diese Knoten richtig. Ich würde nur mit XMLReader für alles, da es aber wiederholt vorkommen der Englisch-Knoten (einen für den Namen, eine für die Beschreibung) von mein Googeln bisher SimpleXML schien der Weg nach vorne, aber keine Freude noch.
Irgendwelche Vorschläge? Jeder gute Führer? XMLReader-Dokumentation auf php.net ist beklagenswert fehlt in Vergleich zu vielen anderen PHP-Funktionen, und im Allgemeinen scheint es schwer zu finden, detaillierte Anleitungen, die sind klar und übersichtlich.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Gut, wenn man noch bauen kann, dass array, XML Datei ist wahrscheinlich nicht so groß :). Versuchen zu laden, die ganze Datei mit simplexml zum Beispiel, Sie könnten überrascht sein, dass es nicht verbrauchen viel Speicher.
Sowieso, wenn Sie immer noch wollen, um mit XMLReader, habe ich oft schlagen Sie mein XMLReader-Iterator-library, die in der Lage ist, Durchlaufen Sie eine
XMLReader
Zugriff auf Elemente, die Kinder und machen Sachen wie das einschalten Fragmente inSimpleXMLElement
s.Folgende ist ein Beispiel, das ist nahezu identisch zu deinem Beispiel oben:
Wenn Sie führen Sie es auf Ihrem demo-Daten, die daraus resultierende
$items
array ist:Technisch brauchen Sie nicht zu verwenden, die Bibliothek, es funktioniert nur auf eine
XMLReader
so dass es nicht ändern, wieXMLReader
funktioniert. Es ist ein add-on.Warum es nicht funktioniert in Ihrem speziellen Fall schwer zu sagen, deinen code habe laufen einwandfrei auf meinem computer:
Als diese
print_r
Ausgabe von$items
(code) zeigt, die englishName Schlüssel, um die simplexml-Elementen. Sie könnte werfen wollte diese zu einem string, wie ich es Tat in meinem Beispiel (diese beiden(string)
Teile), um strings gibt es statt SimpleXMLElements, das war wohl Ihr Problem. Wenn nicht, überprüfen Sie die libxml version:Und melden Sie es zurück (das ist die Bibliothek
XMLReader
basiert auf). Auch Debuggen SimpleXMLElement (var_dump($sxml->asXML());
), so können Sie überprüfen den erwarteten XML geladen wurde.Die Bibliothek empfehle ich btw. kommt auch mit eine einzelne include-Datei wenn Sie möchten, um zu versuchen, es schnell.
Letzte mal, dass ich vorgeschlagen, dass die Bibliothek wurde in:
Edit: Eine zusätzliche hybrid-version w/o die Bibliothek zeigt die Verwendung von
next()
was nützlich ist, wie man iteriert immer über den gleichen Namen Geschwister:<Item>
:Nevermind, es herausgefunden. Für alle anderen, die hängen bleibt, die auf dieser:
$item->asSimpleXML();
die return - raten 🙂 - ja. Es ist einfach zu implementieren, darin, so dass ich nicht darum kümmern, nicht mehr. Es ist auch kompatibel mit mehreren Systemen, die keine UnterstützungreadOuterXML()
aufgrund der libxml-version. Als der iterator ist ein add-on nur Sie können sagen, das ist im Grunde das gleiche. In Ihrem Fall gibt es einen weiteren trick, den Sie tun können, ich werde es zu hacken und zu erweitern meine Antwort nur für die Lesbarkeit.next()
hier sollten Sie überlegen, in Ihrem Fall wenn Sie nicht wollen, verwenden Sie den iterator.