
Bryan Hadlock
Ich versuche, XML in PHP in JSON zu konvertieren. Wenn ich eine einfache Konvertierung mit einfachem XML und json_encode durchführe, werden keine der Attribute in der XML-Anzeige angezeigt.
$xml = simplexml_load_file("states.xml");
echo json_encode($xml);
Also versuche ich, es manuell so zu analysieren.
foreach($xml->children() as $state)
{
$states[]= array('state' => $state->name);
}
echo json_encode($states);
und die Ausgabe für Zustand ist {"state":{"0":"Alabama"}}
eher, als {"state":"Alabama"}
Was mache ich falsch?
XML:
<?xml version="1.0" ?>
<states>
<state id="AL">
<name>Alabama</name>
</state>
<state id="AK">
<name>Alaska</name>
</state>
</states>
Ausgabe:
[{"state":{"0":"Alabama"}},{"state":{"0":"Alaska"}
Var-Dump:
object(SimpleXMLElement)#1 (1) {
["state"]=>
array(2) {
[0]=>
object(SimpleXMLElement)#3 (2) {
["@attributes"]=>
array(1) {
["id"]=>
string(2) "AL"
}
["name"]=>
string(7) "Alabama"
}
[1]=>
object(SimpleXMLElement)#2 (2) {
["@attributes"]=>
array(1) {
["id"]=>
string(2) "AK"
}
["name"]=>
string(6) "Alaska"
}
}
}

Anton Max
Json & Array aus XML in 3 Zeilen:
$xml = simplexml_load_string($xml_string);
$json = json_encode($xml);
$array = json_decode($json,TRUE);
Entschuldigen Sie die Beantwortung eines alten Beitrags, aber dieser Artikel skizziert einen Ansatz, der relativ kurz, prägnant und einfach zu pflegen ist. Ich habe es selbst getestet und funktioniert ziemlich gut.
http://lostechies.com/seanbiefeld/2011/10/21/simple-xml-to-json-with-php/
<?php
class XmlToJson {
public function Parse ($url) {
$fileContents= file_get_contents($url);
$fileContents = str_replace(array("\n", "\r", "\t"), '', $fileContents);
$fileContents = trim(str_replace('"', "'", $fileContents));
$simpleXml = simplexml_load_string($fileContents);
$json = json_encode($simpleXml);
return $json;
}
}
?>
Ich habe es herausgefunden. json_encode behandelt Objekte anders als Strings. Ich habe das Objekt in eine Zeichenfolge umgewandelt und es funktioniert jetzt.
foreach($xml->children() as $state)
{
$states[]= array('state' => (string)$state->name);
}
echo json_encode($states);
Ich schätze, ich bin etwas spät dran, aber ich habe eine kleine Funktion geschrieben, um diese Aufgabe zu erfüllen. Es kümmert sich auch um Attribute, Textinhalte und selbst wenn mehrere Knoten mit demselben Knotennamen Geschwister sind.
Haftungsausschluss:
Ich bin kein PHP-Native, also ertragen Sie bitte einfache Fehler.
function xml2js($xmlnode) {
$root = (func_num_args() > 1 ? false : true);
$jsnode = array();
if (!$root) {
if (count($xmlnode->attributes()) > 0){
$jsnode["$"] = array();
foreach($xmlnode->attributes() as $key => $value)
$jsnode["$"][$key] = (string)$value;
}
$textcontent = trim((string)$xmlnode);
if (count($textcontent) > 0)
$jsnode["_"] = $textcontent;
foreach ($xmlnode->children() as $childxmlnode) {
$childname = $childxmlnode->getName();
if (!array_key_exists($childname, $jsnode))
$jsnode[$childname] = array();
array_push($jsnode[$childname], xml2js($childxmlnode, true));
}
return $jsnode;
} else {
$nodename = $xmlnode->getName();
$jsnode[$nodename] = array();
array_push($jsnode[$nodename], xml2js($xmlnode, true));
return json_encode($jsnode);
}
}
Anwendungsbeispiel:
$xml = simplexml_load_file("myfile.xml");
echo xml2js($xml);
Beispieleingabe (myfile.xml):
<family name="Johnson">
<child name="John" age="5">
<toy status="old">Trooper</toy>
<toy status="old">Ultrablock</toy>
<toy status="new">Bike</toy>
</child>
</family>
Beispielausgabe:
{"family":[{"$":{"name":"Johnson"},"child":[{"$":{"name":"John","age":"5"},"toy":[{"$":{"status":"old"},"_":"Trooper"},{"$":{"status":"old"},"_":"Ultrablock"},{"$":{"status":"new"},"_":"Bike"}]}]}]}
Schön gedruckt:
{
"family" : [{
"$" : {
"name" : "Johnson"
},
"child" : [{
"$" : {
"name" : "John",
"age" : "5"
},
"toy" : [{
"$" : {
"status" : "old"
},
"_" : "Trooper"
}, {
"$" : {
"status" : "old"
},
"_" : "Ultrablock"
}, {
"$" : {
"status" : "new"
},
"_" : "Bike"
}
]
}
]
}
]
}
Macken zu beachten:
Mehrere Tags mit demselben Tagnamen können Geschwister sein. Andere Lösungen werden höchstwahrscheinlich alle bis auf das letzte Geschwisterelement fallen lassen. Um dies zu vermeiden, ist jeder einzelne Knoten, selbst wenn er nur ein untergeordnetes Element hat, ein Array, das ein Objekt für jede Instanz des Tagnamens enthält. (Siehe mehrere “”-Elemente im Beispiel)
Sogar das Wurzelelement, von dem in einem gültigen XML-Dokument nur eines existieren sollte, wird als Array mit einem Objekt der Instanz gespeichert, nur um eine konsistente Datenstruktur zu haben.
Um zwischen XML-Knoteninhalt und XML-Attributen unterscheiden zu können, werden die Attribute jedes Objekts im “$” und der Inhalt im untergeordneten “_” gespeichert.
Bearbeiten:
Ich habe vergessen, die Ausgabe für Ihre Beispieleingabedaten anzuzeigen
{
"states" : [{
"state" : [{
"$" : {
"id" : "AL"
},
"name" : [{
"_" : "Alabama"
}
]
}, {
"$" : {
"id" : "AK"
},
"name" : [{
"_" : "Alaska"
}
]
}
]
}
]
}

Kodierer der Erlösung
Eine häufige Falle ist, das zu vergessen json_encode()
berücksichtigt keine Elemente mit einem Textwert und Attribut(e). Es wird eine davon auswählen, was Datenverlust bedeutet. Die folgende Funktion löst dieses Problem. Entscheidet man sich für die json_encode
/decode
Weise wird die folgende Funktion empfohlen.
function json_prepare_xml($domNode) {
foreach($domNode->childNodes as $node) {
if($node->hasChildNodes()) {
json_prepare_xml($node);
} else {
if($domNode->hasAttributes() && strlen($domNode->nodeValue)){
$domNode->setAttribute("nodeValue", $node->textContent);
$node->nodeValue = "";
}
}
}
}
$dom = new DOMDocument();
$dom->loadXML( file_get_contents($xmlfile) );
json_prepare_xml($dom);
$sxml = simplexml_load_string( $dom->saveXML() );
$json = json_decode( json_encode( $sxml ) );
dadurch, <foo bar="3">Lorem</foo>
wird nicht so enden {"foo":"Lorem"}
in Ihrem JSON.
Versuchen Sie, dies zu verwenden
$xml = ... // Xml file data
// first approach
$Json = json_encode(simplexml_load_string($xml));
---------------- OR -----------------------
// second approach
$Json = json_encode(simplexml_load_string($xml, "SimpleXMLElement", LIBXML_NOCDATA));
echo $Json;
Oder
Sie können diese Bibliothek verwenden: https://github.com/rentpost/xml2array

Klesun
Diese Lösung verarbeitet Namensräume, Attribute und erzeugt konsistente Ergebnisse mit sich wiederholenden Elementen (immer im Array, auch wenn es nur ein Vorkommen gibt). Inspiriert von sxiToArray() von ratfactor.
/**
* <root><a>5</a><b>6</b><b>8</b></root> -> {"root":[{"a":["5"],"b":["6","8"]}]}
* <root a="5"><b>6</b><b>8</b></root> -> {"root":[{"a":"5","b":["6","8"]}]}
* <root xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy"><a>123</a><wsp:b>456</wsp:b></root>
* -> {"root":[{"xmlns:wsp":"http://schemas.xmlsoap.org/ws/2004/09/policy","a":["123"],"wsp:b":["456"]}]}
*/
function domNodesToArray(array $tags, \DOMXPath $xpath)
{
$tagNameToArr = [];
foreach ($tags as $tag) {
$tagData = [];
$attrs = $tag->attributes ? iterator_to_array($tag->attributes) : [];
$subTags = $tag->childNodes ? iterator_to_array($tag->childNodes) : [];
foreach ($xpath->query('namespace::*', $tag) as $nsNode) {
// the only way to get xmlns:*, see https://stackoverflow.com/a/2470433/2750743
if ($tag->hasAttribute($nsNode->nodeName)) {
$attrs[] = $nsNode;
}
}
foreach ($attrs as $attr) {
$tagData[$attr->nodeName] = $attr->nodeValue;
}
if (count($subTags) === 1 && $subTags[0] instanceof \DOMText) {
$text = $subTags[0]->nodeValue;
} elseif (count($subTags) === 0) {
$text="";
} else {
// ignore whitespace (and any other text if any) between nodes
$isNotDomText = function($node){return !($node instanceof \DOMText);};
$realNodes = array_filter($subTags, $isNotDomText);
$subTagNameToArr = domNodesToArray($realNodes, $xpath);
$tagData = array_merge($tagData, $subTagNameToArr);
$text = null;
}
if (!is_null($text)) {
if ($attrs) {
if ($text) {
$tagData['_'] = $text;
}
} else {
$tagData = $text;
}
}
$keyName = $tag->nodeName;
$tagNameToArr[$keyName][] = $tagData;
}
return $tagNameToArr;
}
function xmlToArr(string $xml)
{
$doc = new \DOMDocument();
$doc->loadXML($xml);
$xpath = new \DOMXPath($doc);
$tags = $doc->childNodes ? iterator_to_array($doc->childNodes) : [];
return domNodesToArray($tags, $xpath);
}
Beispiel:
php > print(json_encode(xmlToArr('<root a="5"><b>6</b></root>')));
{"root":[{"a":"5","b":["6"]}]}
9863300cookie-checkPHP konvertiert XML in JSONyes
Bitte fügen Sie einen Ausschnitt des XML-Codes und die endgültige Array-Struktur hinzu, die Sie nach dem Parsen haben. (EIN
var_dump
funktioniert gut.)– nikc.org
12. Januar 2012 um 5:39 Uhr
Eingabe, Ausgabe und var_dump hinzugefügt
– Bryan Hadlock
12. Januar 2012 um 6:15 Uhr
Einige Anwendungen benötigen “Perfekte XML-zu-JSON-Zuordnung”das ist jsonMLsiehe Lösung hier.
– Peter Krauß
6. Oktober 2016 um 14:19 Uhr