Próbuję przekonwertować xml na json w php. Jeśli wykonam prostą konwersję przy użyciu prostego kodu XML i json_encode, żaden z atrybutów w pokazie XML.
$xml = simplexml_load_file("states.xml");
echo json_encode($xml);
Więc próbuję ręcznie przeanalizować to w ten sposób.
foreach($xml->children() as $state)
{
$states[]= array('state' => $state->name);
}
echo json_encode($states);
a wyjście dla stanu to {"state":{"0":"Alabama"}}
raczej niż{"state":"Alabama"}
Co ja robię źle?
XML:
<?xml version="1.0" ?>
<states>
<state id="AL">
<name>Alabama</name>
</state>
<state id="AK">
<name>Alaska</name>
</state>
</states>
Wynik:
[{"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"
}
}
}
var_dump
działa dobrze.)Odpowiedzi:
Json & Array z XML w 3 liniach:
źródło
<person my-attribute='name'>John</person>
jest interpretowane jako<person>John</person>
.@attributes
kluczem, więc działa absolutnie bezbłędnie i pięknie. 3 krótkie linijki kodu pięknie rozwiązują mój problem.<list><item><a>123</a><a>456</a></item><item><a>123</a></item></list>
->{"item":[{"a":["123","456"]},{"a":"123"}]}
. Rozwiązanie na php.net autorstwa ratfactor rozwiązuje ten problem, zawsze przechowując elementy w tablicy.Przepraszamy, że odpowiadam na stary post, ale ten artykuł przedstawia podejście, które jest stosunkowo krótkie, zwięzłe i łatwe w utrzymaniu. Sam to przetestowałem i działa całkiem nieźle.
http://lostechies.com/seanbiefeld/2011/10/21/simple-xml-to-json-with-php/
źródło
Rozgryzłem to. json_encode obsługuje obiekty inaczej niż ciągi. Rzuciłem obiekt na strunę i teraz działa.
źródło
Chyba trochę się spóźniłem na przyjęcie, ale napisałem małą funkcję, aby wykonać to zadanie. Dba również o atrybuty, zawartość tekstową, a nawet jeśli wiele węzłów o tej samej nazwie węzła jest rodzeństwem.
Zastrzeżenie: nie jestem natywnym językiem PHP, więc proszę, znoszę proste błędy.
Przykład użycia:
Przykładowe dane wejściowe (myfile.xml):
Przykładowe dane wyjściowe:
Całkiem wydrukowane:
Dziwactwa, o których należy pamiętać: kilka tagów z tą samą zmienną może być rodzeństwem. Inne rozwiązania najprawdopodobniej odrzucą wszystko oprócz ostatniego rodzeństwa. Aby tego uniknąć, każdy węzeł, nawet jeśli ma tylko jedno dziecko, jest tablicą przechowującą obiekt dla każdej instancji zmiennej. (Zobacz przykład wielu elementów „”)
Nawet element główny, z którego tylko jeden powinien istnieć w ważnym dokumencie XML, jest przechowywany jako tablica z obiektem instancji, aby mieć spójną strukturę danych.
Aby móc odróżnić zawartość węzła XML od atrybutów XML, każdy atrybut obiektu jest przechowywany w „$”, a zawartość w podrzędnym „_”.
Edycja: zapomniałem pokazać dane wyjściowe dla przykładowych danych wejściowych
źródło
$xml = simplexml_load_file("myfile.xml",'SimpleXMLElement',LIBXML_NOCDATA);
.Fatal error: Uncaught Error: Call to a member function getName() on bool
... myślę, że wersja php nie powiodła się :-( .. proszę o pomoc!Częstym błędem jest zapomnienie, że
json_encode()
nie uwzględnia elementów z wartością tekstową i atrybutami. Wybierze jeden z nich, czyli dataloss. Poniższa funkcja rozwiązuje ten problem. Jeśli zdecydujesz się wybrać drogęjson_encode
/decode
, zaleca się następującą funkcję.w ten sposób
<foo bar="3">Lorem</foo>
nie skończy się tak, jak{"foo":"Lorem"}
w Twoim JSON.źródło
$dom
? Skąd to pochodzi?Spróbuj tego użyć
Lub
Możesz skorzystać z tej biblioteki: https://github.com/rentpost/xml2array
źródło
W tym celu użyłem TypeConvertera Milesa Johnsona . Można go zainstalować za pomocą Composera .
Możesz napisać coś takiego, używając go:
źródło
Optymalizacja odpowiedzi Antonio Maxa:
źródło
Jeśli chcesz przekonwertować tylko określoną część XML na JSON, możesz użyć XPath, aby to pobrać i przekonwertować na JSON.
Pamiętaj, że jeśli Xpath jest niepoprawny, to zniknie z błędem. Więc jeśli debugujesz to za pomocą wywołań AJAX, zalecamy również rejestrowanie treści odpowiedzi.
źródło
źródło
Najlepsze rozwiązanie, które działa jak urok
Źródło
źródło
Jest to ulepszenie najpopularniejszego rozwiązania Antonio Maxa, które działa również z XML, który ma przestrzenie nazw (zastępując dwukropek podkreśleniem). Ma również kilka dodatkowych opcji (i
<person my-attribute='name'>John</person>
poprawnie analizuje ).źródło
<element/>
, nie adresuje elementów, które zaczynają się od lub zawierają podkreślenia, co jest dozwolone w XML. Nie można wykryć CDATA. I jak powiedziałem, jest WOLNY. Jest to złożoność O (n ^ 2) z powodu wewnętrznego parsowania.Wszystkie rozwiązania mają tutaj problemy!
... Gdy reprezentacja wymaga doskonałej interpretacji XML (bez problemów z atrybutami) i odtworzenia całego tekstu-znacznika-tekstu-znacznika-tekstu -... i kolejności znaczników. Warto też pamiętać, że obiekt JSON „jest nieuporządkowanym zestawem” (nie powtarzają się klucze, a klucze nie mogą mieć predefiniowanej kolejności) ... Nawet xml2json ZF jest zły (!), Ponieważ nie zachowuje dokładnie struktury XML.
Wszystkie tutaj rozwiązania mają problemy z tym prostym kodem XML,
... Rozwiązanie @FTav wydaje się lepsze niż rozwiązanie 3-liniowe, ale ma również mały błąd podczas testowania z tym XML.
Stare rozwiązanie jest najlepsze (dla reprezentacji bez strat)
Rozwiązanie, dziś dobrze znane jako jsonML , jest używane przez projekt Zorba i inne, a po raz pierwszy zostało zaprezentowane w ~ 2006 lub ~ 2007 roku przez (osobno) Stephena McKameya i Johna Snelsona .
Produkować
Zobacz http://jsonML.org lub github.com/mckamey/jsonml . Reguły produkcji tego JSON są oparte na elemencie JSON-analog,
Ta składnia jest definicją elementu i powtarzaniem, z
element-list ::= element ',' element-list | element
.źródło
Po przeanalizowaniu wszystkich odpowiedzi, wymyśliłem rozwiązanie, które działało dobrze z moimi funkcjami JavaScript w różnych przeglądarkach (w tym na konsolach / narzędziach deweloperskich):
Zasadniczo tworzy nowy DOMDocument, ładuje i plik XML do niego i przechodzi przez każdy z węzłów i elementów potomnych, pobierając dane / parametry i eksportując je do JSON bez irytujących znaków „@”.
Link do pliku XML .
źródło
To rozwiązanie obsługuje przestrzenie nazw, atrybuty i daje spójne wyniki z powtarzającymi się elementami (zawsze w tablicy, nawet jeśli występuje tylko jedno wystąpienie). Zainspirowany sxiToArray () ratfactor .
Przykład:
źródło
Okazało się, że odpowiedź FTav jest najbardziej użyteczna, ponieważ jest bardzo konfigurowalna, ale jego funkcja xml2js ma kilka wad. Na przykład, jeśli elementy potomne mają takie same zmienne, wszystkie będą przechowywane w jednym obiekcie, oznacza to, że kolejność elementów nie zostanie zachowana. W niektórych przypadkach naprawdę zależy nam na zachowaniu porządku, dlatego lepiej przechowujemy dane każdego elementu w osobnym obiekcie:
Oto jak to działa. Początkowa struktura xml:
Wynik JSON:
źródło
Wygląda na to, że
$state->name
zmienna zawiera tablicę. Możesz użyćwewnątrz,
foreach
aby to sprawdzić.W takim przypadku możesz zmienić linię wewnątrz
foreach
naaby to poprawić.
źródło
źródło
Jeśli jesteś użytkownikiem Ubuntu zainstaluj czytnik XML (mam php 5.6. Jeśli masz inny, znajdź pakiet i zainstaluj)
źródło