Ich möchte unten XML in ein PHP-Array konvertieren. Irgendwelche Vorschläge, wie ich das machen kann?
<aaaa Version="1.0">
<bbb>
<cccc>
<dddd Id="id:pass" />
<eeee name="hearaman" age="24" />
</cccc>
</bbb>
</aaaa>
Hörmann
Ich möchte unten XML in ein PHP-Array konvertieren. Irgendwelche Vorschläge, wie ich das machen kann?
<aaaa Version="1.0">
<bbb>
<cccc>
<dddd Id="id:pass" />
<eeee name="hearaman" age="24" />
</cccc>
</bbb>
</aaaa>
Benutzer1398287
leicht!
$xml = simplexml_load_string($xmlstring, "SimpleXMLElement", LIBXML_NOCDATA);
$json = json_encode($xml);
$array = json_decode($json,TRUE);
Sie könnten in CDATA-Abschnitten auf Probleme stoßen (es wird immer null zurückgegeben). Versuchen Sie als Lösung $xml = simplexml_load_string( $xmlstring , null , LIBXML_NOCDATA ); $json = json_encode($xml); $array = json_decode($json,TRUE); (siehe stackoverflow.com/a/2970701/413531) //e verdammt… gibt es eine Möglichkeit, neue Zeilen in einem Kommentar hinzuzufügen?
– Hirnhamster
26. Mai 2014 um 9:57 Uhr
Wir machen genau dasselbe, aber mit simplexml_load_file und es funktioniert gut. Danke
– Thermech
3. September 2014 um 13:46 Uhr
Wofür ist der zweite Parameter (TRUE)?
– Mansur Fahad
19. September 2014 um 18:50 Uhr
@MansourFahad In json_decode Sie können den optionalen zweiten Parameter als verwenden TRUE
(normalerweise standardmäßig auf FALSE
), um die JSON-Eingabe in ein assoziatives Array zu konvertieren.
– Jake Bathman
26. September 2014 um 19:20 Uhr
@Ismael Miguel zu viel Code? Nur weil Sie all diese Funktionen in eine Zeile schreiben, bedeutet das nicht, dass Sie weniger Code verwenden. Es sieht zwar kompakter aus, geht aber auf Kosten der Lesbarkeit.
– Jage
5. März 2015 um 21:44 Uhr
Sam Dufel
Eine weitere Option ist die SimpleXML-Erweiterung (ich glaube, sie ist bei den meisten PHP-Installationen Standard.)
http://php.net/manual/en/book.simplexml.php
Die Syntax sieht für dein Beispiel etwa so aus
$xml = new SimpleXMLElement($xmlString);
echo $xml->bbb->cccc->dddd['Id'];
echo $xml->bbb->cccc->eeee['name'];
// or...........
foreach ($xml->bbb->cccc as $element) {
foreach($element as $key => $val) {
echo "{$key}: {$val}";
}
}
Um fair zu sein, beantwortet dies nicht genau die Frage, wie man ein Array erhält.
– Sieppl
5. November 2013 um 8:03 Uhr
SimpleXML saugt beim Analysieren dieses XML: amazon.in/rss/bestseller/shoes?tag=dealslama-21 Sogar print_r sagt nicht, dass das Objekt tatsächlich enthält.
– Ravi Soni
24. Januar 2015 um 7:39 Uhr
Verwenden Sie var_dump, sehen Sie die XML-Struktur als Schlüssel innerhalb des Objekts.
– Magus
3. Oktober 2016 um 16:49 Uhr
Ich habe welche [CDATA[TEXT]]
innerhalb einiger Elemente und sie werden damit nicht analysiert. Es analysiert es als SimpleXMLElement Object
. Irgendeine Problemumgehung dafür?
– masterFly
26. Oktober 2016 um 4:20 Uhr
Dies beantwortet die Frage nicht
– Bilala Raschid
14. April 2019 um 16:11 Uhr
hakre
Konvertieren eines XML-Strings ($buffer
) in ein vereinfachtes Array, das Attribute ignoriert und untergeordnete Elemente mit denselben Namen gruppiert:
function XML2Array(SimpleXMLElement $parent)
{
$array = array();
foreach ($parent as $name => $element) {
($node = & $array[$name])
&& (1 === count($node) ? $node = array($node) : 1)
&& $node = & $node[];
$node = $element->count() ? XML2Array($element) : trim($element);
}
return $array;
}
$xml = simplexml_load_string($buffer);
$array = XML2Array($xml);
$array = array($xml->getName() => $array);
Ergebnis:
Array
(
[aaaa] => Array
(
[bbb] => Array
(
[cccc] => Array
(
[dddd] =>
[eeee] =>
)
)
)
)
Wenn Sie auch die Attribute haben möchten, sind sie über die JSON-Codierung/Decodierung von SimpleXMLElement verfügbar. Das ist oft die einfachste Quick’n’Dirty-Lösung:
$xml = simplexml_load_string($buffer);
$array = json_decode(json_encode((array) $xml), true);
$array = array($xml->getName() => $array);
Ergebnis:
Array
(
[aaaa] => Array
(
[@attributes] => Array
(
[Version] => 1.0
)
[bbb] => Array
(
[cccc] => Array
(
[dddd] => Array
(
[@attributes] => Array
(
[Id] => id:pass
)
)
[eeee] => Array
(
[@attributes] => Array
(
[name] => hearaman
[age] => 24
)
)
)
)
)
)
Beachten Sie, dass alle diese Methoden nur im Namensraum des XML-Dokuments funktionieren.
Verwandt: Json Encode oder Serialize an XML
– hakre
6. September 2013 um 10:20 Uhr
In PHP 7 musste ich das hinzufügen: && (is_countable($node) && 1 === count($node) ? $node = array($node) : 1)
aber ich habe einen Fehler in der nächsten Zeile: [] operator not supported for strings
.
– andreschg112
16. Dezember 2019 um 21:48 Uhr
@andreshg112: Ich kann es nicht reproduzieren (funktioniert stabil PHP 5.3.0 – 7.4.0), das Verhalten hat sich seit Ewigkeiten nicht geändert, bitte vergleichen Sie mit Hunderten verschiedener PHP-Versionen: 3v4l.org/l4nQN
– hakre
16. Dezember 2019 um 23:58 Uhr
vielleicht liegt es an meiner KML-Datei (es ist eine XML). Ich kann es nicht teilen. Ich habe es bereits importiert, aber ich musste es anders machen.
– andreschg112
26. Dezember 2019 um 13:12 Uhr
wahrscheinlich sind Sie besorgt über XML-Namespaces. Das Beispiel gilt nur für die Teile ohne Namensraum (oder den Standard, ich mische das manchmal).
– hakre
28. Dezember 2019 um 18:38 Uhr
Fawad Ghafoor
$array = json_decode(json_encode((array)simplexml_load_string($xml)),true);
Die Methode, die in den akzeptierten Antwort-Drop-Attributen verwendet wird, wenn auf untergeordnete Elemente mit nur einem Textknoten gestoßen wird. Zum Beispiel:
$xml="<container><element attribute="123">abcd</element></container>";
print_r(json_decode(json_encode(simplexml_load_string($xml, "SimpleXMLElement", LIBXML_NOCDATA)),1));
Array
(
[element] => abcd
)
Meine Lösung (und ich wünschte, ich könnte hier Kredit geben, weil ich sicher bin, dass ich das von etwas angepasst habe):
function XMLtoArray($xml) {
$previous_value = libxml_use_internal_errors(true);
$dom = new DOMDocument('1.0', 'UTF-8');
$dom->preserveWhiteSpace = false;
$dom->loadXml($xml);
libxml_use_internal_errors($previous_value);
if (libxml_get_errors()) {
return [];
}
return DOMtoArray($dom);
}
function DOMtoArray($root) {
$result = array();
if ($root->hasAttributes()) {
$attrs = $root->attributes;
foreach ($attrs as $attr) {
$result['@attributes'][$attr->name] = $attr->value;
}
}
if ($root->hasChildNodes()) {
$children = $root->childNodes;
if ($children->length == 1) {
$child = $children->item(0);
if (in_array($child->nodeType,[XML_TEXT_NODE,XML_CDATA_SECTION_NODE])) {
$result['_value'] = $child->nodeValue;
return count($result) == 1
? $result['_value']
: $result;
}
}
$groups = array();
foreach ($children as $child) {
if (!isset($result[$child->nodeName])) {
$result[$child->nodeName] = DOMtoArray($child);
} else {
if (!isset($groups[$child->nodeName])) {
$result[$child->nodeName] = array($result[$child->nodeName]);
$groups[$child->nodeName] = 1;
}
$result[$child->nodeName][] = DOMtoArray($child);
}
}
}
return $result;
}
$xml="
<aaaa Version="1.0">
<bbb>
<cccc>
<dddd id="123" />
<eeee name="john" age="24" />
<ffff type="employee">Supervisor</ffff>
</cccc>
</bbb>
</aaaa>
";
print_r(XMLtoArray($xml));
Array
(
[aaaa] => Array
(
[@attributes] => Array
(
[Version] => 1.0
)
[bbb] => Array
(
[cccc] => Array
(
[dddd] => Array
(
[@attributes] => Array
(
[id] => 123
)
)
[eeee] => Array
(
[@attributes] => Array
(
[name] => john
[age] => 24
)
)
[ffff] => Array
(
[@attributes] => Array
(
[type] => employee
)
[_value] => Supervisor
)
)
)
)
)
Dies ist die einzige Antwort, die ich gefunden habe, die sowohl Knotenattribute als auch Arrays behandelt. Auch sehr leicht verständlich.
– Brainware
19. August 2020 um 2:36 Uhr
Wunderbar. Sie haben mir mindestens 18 Jahre Debugging erspart!
– Verrückter Marvin
28. Januar 2021 um 20:15 Uhr
Diese Antwort berücksichtigt auch keine Knoten, die sowohl Text als auch untergeordnete XML-Elemente enthalten. Ich habe jetzt Stunden damit verbracht zu suchen. Ich fange an zu glauben, dass es nirgendwo eine XML-Lösung gibt, die alle XML-Daten richtig parsen und alles behalten kann!
– Verknüpft
25. November 2021 um 1:43 Uhr
Francesco Casula
Sehen https://github.com/gaarf/XML-string-to-PHP-array/blob/master/xmlstr_to_array.php
<?php
/**
* convert xml string to php array - useful to get a serializable value
*
* @param string $xmlstr
* @return array
*
* @author Adrien aka Gaarf & contributors
* @see http://gaarf.info/2009/08/13/xml-string-to-php-array/
*/
function xmlstr_to_array($xmlstr) {
$doc = new DOMDocument();
$doc->loadXML($xmlstr);
$root = $doc->documentElement;
$output = domnode_to_array($root);
$output['@root'] = $root->tagName;
return $output;
}
function domnode_to_array($node) {
$output = array();
switch ($node->nodeType) {
case XML_CDATA_SECTION_NODE:
case XML_TEXT_NODE:
$output = trim($node->textContent);
break;
case XML_ELEMENT_NODE:
for ($i=0, $m=$node->childNodes->length; $i<$m; $i++) {
$child = $node->childNodes->item($i);
$v = domnode_to_array($child);
if(isset($child->tagName)) {
$t = $child->tagName;
if(!isset($output[$t])) {
$output[$t] = array();
}
$output[$t][] = $v;
}
elseif($v || $v === '0') {
$output = (string) $v;
}
}
if($node->attributes->length && !is_array($output)) { //Has attributes but isn't an array
$output = array('@content'=>$output); //Change output into an array.
}
if(is_array($output)) {
if($node->attributes->length) {
$a = array();
foreach($node->attributes as $attrName => $attrNode) {
$a[$attrName] = (string) $attrNode->value;
}
$output['@attributes'] = $a;
}
foreach ($output as $t => $v) {
if(is_array($v) && count($v)==1 && $t!='@attributes') {
$output[$t] = $v[0];
}
}
}
break;
}
return $output;
}
Dies ist die einzige Antwort, die ich gefunden habe, die sowohl Knotenattribute als auch Arrays behandelt. Auch sehr leicht verständlich.
– Brainware
19. August 2020 um 2:36 Uhr
Wunderbar. Sie haben mir mindestens 18 Jahre Debugging erspart!
– Verrückter Marvin
28. Januar 2021 um 20:15 Uhr
Diese Antwort berücksichtigt auch keine Knoten, die sowohl Text als auch untergeordnete XML-Elemente enthalten. Ich habe jetzt Stunden damit verbracht zu suchen. Ich fange an zu glauben, dass es nirgendwo eine XML-Lösung gibt, die alle XML-Daten richtig parsen und alles behalten kann!
– Verknüpft
25. November 2021 um 1:43 Uhr
eozzy
Überrascht niemand erwähnt xml_parse_into_struct
:
$simple = "<para><note>simple note</note></para>";
$p = xml_parser_create();
xml_parse_into_struct($p, $simple, $vals, $index);
xml_parser_free($p);
echo "Index array\n";
print_r($index);
echo "\nVals array\n";
print_r($vals);
Manchmal frage ich mich, was der Entwickler, der die PHP-XML-Implementierung erstellt hat, gedacht hat, als xml_parse_into_struct entworfen wurde …
– Anibal Sánchez
8. Januar 2020 um 10:28 Uhr
auch, wie unterscheidet sich diese Frage von Ihrer anderen Frage? stackoverflow.com/questions/6578084/…
– Gordon
5. Juli 2011 um 7:04 Uhr
Wenige Dinge sind so unausstehlich wie ein OP, der die falsche Antwort auf seine eigene Frage akzeptiert.
– John
20. Oktober 2017 um 9:42 Uhr