Zacząłem używać Json.NET do konwersji łańcucha w formacie JSON na obiekt lub odwrotnie. Nie jestem pewien w środowisku Json.NET, czy można przekonwertować ciąg znaków w formacie JSON na format XML i odwrotnie?
Uwaga, jak powiedział StaxMan, jeśli jest ex. spacja w węźle elementu zostanie zignorowana przez xml. Np. „Identyfikator studenta”: 11000 nie będzie w xml wyniku bcuz miejsca w nazwie właściwości. XML nie akceptuje spacji w węźle elementu.
Daniel B,
Odpowiedzi:
424
Tak. Korzystanie z klasy JsonConvert, która zawiera metody pomocnicze do tego właśnie celu:
// To convert an XML node contained in string xml into a JSON string XmlDocument doc =newXmlDocument();
doc.LoadXml(xml);string jsonText =JsonConvert.SerializeXmlNode(doc);// To convert JSON text contained in string json into an XML nodeXmlDocument doc =JsonConvert.DeserializeXmlNode(json);
Tylko do Twojej wiadomości, tutaj jest potencjalny problem. Kiedy zmieniałem tablicę węzłów xml w json, tworzyłem tablicę w json. Ale kiedy przeglądam tablicę węzłów xml, które mają liczbę 1, konwersja json nie formatuje już tablicy. Tablica xml z jednym elementem gubi się w tłumaczeniu tutaj.
Levitikon
3
Niespodzianka niespodzianka - taka jest impedancja między XML a JSON i powód, dla którego (IMO) nie jest dobrym pomysłem na bezpośrednią konwersję między nimi. Ale, hej, jest wielu deweloperów, którzy zdecydowanie się z tym nie zgadzają (zgodnie z moją opinią) i nie mają nic przeciwko tym przypadkowym konwersjom danych lub potencjalnej utracie danych ...
StaxMan
7
@StaxMan: Myślę, że każdy może się zgodzić, że nie ma standardowego sposobu reprezentowania dokumentu XML w formacie JSON. Twoja odpowiedź została prawdopodobnie odrzucona, ponieważ tak naprawdę nie odpowiedziała na pytanie. OP nie pytał, czy powinien dokonać konwersji, ale czy mógł to zrobić za pomocą narzędzi, które już miał do dyspozycji.
David Brown
46
Tak, możesz to zrobić (ja to robię), ale miej na uwadze pewne paradoksy podczas konwersji i odpowiednio się z nimi obchodź. Nie można automatycznie dostosować się do wszystkich możliwości interfejsu, a kontrolowanie konwersji ma ograniczoną wbudowaną obsługę - wiele struktur JSON i wartości nie może być automatycznie konwertowanych w obie strony. Pamiętaj, że korzystam z ustawień domyślnych z biblioteką Newtonsoft JSON i biblioteką MS XML, więc twój przebieg może się różnić:
XML -> JSON
Wszystkie dane stają się ciągami danych (na przykład zawsze otrzymujesz „fałsz” nie fałsz lub „0” nie 0 ) Oczywiście JavaScript w niektórych przypadkach traktuje je inaczej.
Elementy potomne mogą stać się zagnieżdżonymi obiektami {}LUB zagnieżdżonymi tablicami, w [ {} {} ...]zależności od tego, czy jest tylko jeden, czy więcej niż jeden element potomny XML. Zużyłbyś je w różny sposób w JavaScript itp. Różne przykłady XML zgodnego z tym samym schematem mogą w ten sposób wytwarzać różne struktury JSON. Możesz dodać atrybut json: Array = 'true' do swojego elementu, aby obejść to w niektórych (ale niekoniecznie wszystkich) przypadkach.
Twój XML musi być dość dobrze sformułowany, zauważyłem, że nie musi on być całkowicie zgodny ze standardem W3C, ale 1. musisz mieć element główny i 2. nie możesz zacząć nazw elementów od liczb, to dwa z wymuszonych standardów XML Znalazłem podczas korzystania z bibliotek Newtonsoft i MS.
W starszych wersjach puste elementy nie są konwertowane na JSON. Są ignorowane. Pusty element nie staje się „elementem”: null
Potrzebujesz obiektu najwyższego poziomu, który przekonwertuje na główny element XML, inaczej parser zawiedzie.
Nazwy twoich obiektów nie mogą zaczynać się od liczby, ponieważ nie można ich przekonwertować na elementy (XML jest technicznie nawet bardziej rygorystyczny niż ten), ale mogę „uciec” od złamania niektórych innych zasad nazewnictwa elementów.
Możesz wspomnieć o wszelkich innych zauważonych problemach. Opracowałem własne niestandardowe procedury przygotowywania i czyszczenia ciągów podczas konwersji w tę iz powrotem. Twoja sytuacja może, ale nie musi wymagać przygotowania / czyszczenia. Jak wspomina StaxMan, twoja sytuacja może wymagać konwersji między obiektami ... może to pociągać za sobą odpowiednie interfejsy i kilka instrukcji case / etc do obsługi ostrzeżeń, o których wspomniałem powyżej.
To! Ładne opracowanie tego, na czym polegała moja krótka (iw pewnym momencie mocno odrzucona) odpowiedź - istnieje wiele, wiele pułapek, jeśli wykonasz bezpośrednią konwersję w ciemno. Mogą nie blokować problemów dla określonego zastosowania, ale mogą być również bardzo nieprzyjemne dla innych.
StaxMan
1
Odnośnie # 4 w XML -> JSON: możesz użyć właściwości NullValueHandling, aby określić, że wartości null powinny być jawnie dołączone - newtonsoft.com/json/help/html/…
Jon Story
Opis problemu w tym komentarzu dotyczy dobrze WSZYSTKICH implementacji algorytmów konwertujących JSON na XML lub odwrotnie. Gdy zaakceptuje się, że nie jest możliwe jednoczesne osiągnięcie doskonałej dwukierunkowej wierności, a jednocześnie wejście i wyjście eterowe „imprezowe” lub „ograniczone” (z góry ustalony schemat / format). - w ogólnym przypadku.
DALDEI
33
Możesz wykonać te konwersje również w .NET Framework:
Otrzymuję błąd w GetXmlData „Nazwa„ GetXmlData ”nie istnieje w bieżącym kontekście” Czy brakuje mi dyrektywy dotyczącej używania, której mi brakuje?
TimSmith-Aardwolf
4
@ TimSmith-Aardwolf, Oto cały potrzebny kod. Aby korzystać z System.Web.Script.Serialization, należy dodać zestaw System.Web.Extensions w odnośnikach.
Termininja
@Termininja, JSON na XML daje mi także typ, jak to usunąć?
cracker
@Termininja, Perfect, Thanks.
cracker
30
Nie jestem pewien, czy taka konwersja ma sens (tak, wielu to robi, ale głównie, aby przeforsować kwadratowy kołek przez okrągły otwór) - występuje niedopasowanie impedancji strukturalnej, a konwersja jest stratna. Odradzam więc takie transformacje między formatami.
Ale jeśli to zrobisz, najpierw przekonwertuj z json na obiekt, a następnie z obiektu na xml (i odwrotnie dla odwrotnego kierunku). Wykonanie bezpośredniej transformacji prowadzi do brzydkich wyników, utraty informacji lub być może obu naraz.
Mimo że twoja odpowiedź została rozbita, cieszę się, że już tu jest. Chcę wykonać konwersję i rozważałem pominięcie środkowych obiektów c #, ale teraz nie jestem tego taki pewien. W przeciwnym razie musiałbym wygenerować obiekty c # na podstawie XSD, a ponieważ byłoby to wyłącznie do celów konwersji, wydawało się to zmarnowaną warstwą (i wysiłkiem). Jeśli masz przykłady lub więcej szczegółów na temat strat, byłoby wspaniale to zobaczyć.
CRice
Nie wiem, dlaczego to zostało odrzucone. Obecnie naprawiam kilka błędów związanych z kilkoma krokami transformacji JSON XML <-> w produkcie, który mamy. Większość jest spowodowana utratą typów numerycznych podczas konwersji z JSON na XML.
rikkit
Twarda prawda, przydatna odpowiedź.
FailedUnitTest
@CRice Lata za późno, ale posiadanie obiektów transferu do pewnego stopnia zachowuje schemat XML. Na przykład, jak przywołał Levitikon , jeśli spróbujesz przekonwertować dokument XML za pomocą tablicy z jednym elementem, konwersja JSON nie będzie wiedziała, że jest to tablica, chyba że pochodzi ona z obiektu przesyłania z typem tablicy.
jpaugh
1
Newtonsoft.JSON za XmlNodeConverter ma opcji konfiguracyjnych , aby uniknąć tego problemu podczas przenoszenia z JSON na XML, JSON do tyłu, ale nie może złapać przypadki oryginalny format XML
jpaugh
27
Dzięki dla Davida Browna odpowiedź . W moim przypadku JSON.Net 3.5 metody konwersji znajdują się w klasie statycznej JsonConvert:
XmlNode myXmlNode =JsonConvert.DeserializeXmlNode(myJsonString);// is node not note// or .DeserilizeXmlNode(myJsonString, "root"); // if myJsonString does not have a rootstring jsonString =JsonConvert.SerializeXmlNode(myXmlNode);
Jeśli twoje dane są tablicą, musisz zrobić coś takiego: JsonConvert.DeserializeXmlNode ("{\" Row \ ":" + json + "}", "root"). ToXmlString () w przeciwnym razie otrzymasz "XmlNodeConverter może konwertować tylko JSON, który zaczyna się od obiektu. ” wyjątek.
Mitchell Skurnik
Tak i nie możesz zacząć od cyfry. JsonConvert.DeserializeXmlNode ("{\" 1Row \ ":" + json + "}", "root"). ToXmlString () nie powiedzie się
DaFi4
powyższa odpowiedź i komentarz @mitchell pomogą mi .. dziękuję
Ajay2707
8
Długo szukałem alternatywnego kodu do zaakceptowanego rozwiązania w nadziei, że nie użyję zewnętrznego zespołu / projektu. Wymyśliłem następujące dzięki kodowi źródłowemu projektu DynamicJson :
publicXmlDocumentJsonToXML(string json){XmlDocument doc =newXmlDocument();using(var reader =JsonReaderWriterFactory.CreateJsonReader(Encoding.UTF8.GetBytes(json),XmlDictionaryReaderQuotas.Max)){XElement xml =XElement.Load(reader);
doc.LoadXml(xml.ToString());}return doc;}
Uwaga: Chciałem XmlDocument zamiast XElement dla celów xPath. Ponadto, ten kod oczywiście przechodzi tylko z JSON na XML, istnieją różne sposoby, aby zrobić odwrotnie.
Musiałem to zrobić niedawno w SQLCLR i nie mogłem wziąć zależności, więc po prostu ugryzłem punktor i napisałem ten program konwersji json-na-xml , było to zaskakująco proste i tylko około 20 linii kodu.
gordy
jak usunąć typr z xml?
cracker
6
Oto pełny kod c # do konwersji xml do json
publicstaticclassJSon{publicstaticstringXmlToJSON(string xml){XmlDocument doc =newXmlDocument();
doc.LoadXml(xml);returnXmlToJSON(doc);}publicstaticstringXmlToJSON(XmlDocument xmlDoc){StringBuilder sbJSON =newStringBuilder();
sbJSON.Append("{ ");XmlToJSONnode(sbJSON, xmlDoc.DocumentElement,true);
sbJSON.Append("}");return sbJSON.ToString();}// XmlToJSONnode: Output an XmlElement, possibly as part of a higher arrayprivatestaticvoidXmlToJSONnode(StringBuilder sbJSON,XmlElement node,bool showNodeName){if(showNodeName)
sbJSON.Append("\""+SafeJSON(node.Name)+"\": ");
sbJSON.Append("{");// Build a sorted list of key-value pairs// where key is case-sensitive nodeName// value is an ArrayList of string or XmlElement// so that we know whether the nodeName is an array or not.SortedList<string,object> childNodeNames =newSortedList<string,object>();// Add in all node attributesif(node.Attributes!=null)foreach(XmlAttribute attr in node.Attributes)StoreChildNode(childNodeNames, attr.Name, attr.InnerText);// Add in all nodesforeach(XmlNode cnode in node.ChildNodes){if(cnode isXmlText)StoreChildNode(childNodeNames,"value", cnode.InnerText);elseif(cnode isXmlElement)StoreChildNode(childNodeNames, cnode.Name, cnode);}// Now output all stored infoforeach(string childname in childNodeNames.Keys){List<object> alChild =(List<object>)childNodeNames[childname];if(alChild.Count==1)OutputNode(childname, alChild[0], sbJSON,true);else{
sbJSON.Append(" \""+SafeJSON(childname)+"\": [ ");foreach(objectChildin alChild)OutputNode(childname,Child, sbJSON,false);
sbJSON.Remove(sbJSON.Length-2,2);
sbJSON.Append(" ], ");}}
sbJSON.Remove(sbJSON.Length-2,2);
sbJSON.Append(" }");}// StoreChildNode: Store data associated with each nodeName// so that we know whether the nodeName is an array or not.privatestaticvoidStoreChildNode(SortedList<string,object> childNodeNames,string nodeName,object nodeValue){// Pre-process contraction of XmlElement-sif(nodeValue isXmlElement){// Convert <aa></aa> into "aa":null// <aa>xx</aa> into "aa":"xx"XmlNode cnode =(XmlNode)nodeValue;if(cnode.Attributes.Count==0){XmlNodeList children = cnode.ChildNodes;if(children.Count==0)
nodeValue =null;elseif(children.Count==1&&(children[0]isXmlText))
nodeValue =((XmlText)(children[0])).InnerText;}}// Add nodeValue to ArrayList associated with each nodeName// If nodeName doesn't exist then add itList<object>ValuesAL;if(childNodeNames.ContainsKey(nodeName)){ValuesAL=(List<object>)childNodeNames[nodeName];}else{ValuesAL=newList<object>();
childNodeNames[nodeName]=ValuesAL;}ValuesAL.Add(nodeValue);}privatestaticvoidOutputNode(string childname,object alChild,StringBuilder sbJSON,bool showNodeName){if(alChild ==null){if(showNodeName)
sbJSON.Append("\""+SafeJSON(childname)+"\": ");
sbJSON.Append("null");}elseif(alChild isstring){if(showNodeName)
sbJSON.Append("\""+SafeJSON(childname)+"\": ");string sChild =(string)alChild;
sChild = sChild.Trim();
sbJSON.Append("\""+SafeJSON(sChild)+"\"");}elseXmlToJSONnode(sbJSON,(XmlElement)alChild, showNodeName);
sbJSON.Append(", ");}// Make a string safe for JSONprivatestaticstringSafeJSON(string sIn){StringBuilder sbOut =newStringBuilder(sIn.Length);foreach(char ch in sIn){if(Char.IsControl(ch)|| ch =='\''){int ich =(int)ch;
sbOut.Append(@"\u"+ ich.ToString("x4"));continue;}elseif(ch =='\"'|| ch =='\\'|| ch =='/'){
sbOut.Append('\\');}
sbOut.Append(ch);}return sbOut.ToString();}}
Aby przekonwertować dany ciąg XML na JSON, wystarczy wywołać funkcję XmlToJSON () jak poniżej.
Oto prosty fragment kodu, który konwertuje XmlNode (rekurencyjnie) na tablicę mieszającą i grupuje wiele instancji tego samego dziecka w tablicy (jako ArrayList). Hashtable jest zwykle akceptowany do konwersji na JSON przez większość bibliotek JSON.
Tak jak powiedział David Brown, ale dostałem następujący wyjątek.
$exception {"There are multiple root elements. Line , position ."}System.Xml.XmlException
Jednym rozwiązaniem byłoby zmodyfikowanie pliku XML za pomocą elementu głównego, ale nie zawsze jest to konieczne, a dla strumienia XML może to również nie być możliwe. Moje rozwiązanie poniżej:
<parent><child>
Text
</child></parent><parent><child><grandchild>
Text
</grandchild><grandchild>
Text
</grandchild></child><child>
Text
</child></parent>
Odpowiedzi:
Tak. Korzystanie z klasy JsonConvert, która zawiera metody pomocnicze do tego właśnie celu:
Dokumentacja tutaj: Konwersja między JSON i XML za pomocą Json.NET
źródło
Tak, możesz to zrobić (ja to robię), ale miej na uwadze pewne paradoksy podczas konwersji i odpowiednio się z nimi obchodź. Nie można automatycznie dostosować się do wszystkich możliwości interfejsu, a kontrolowanie konwersji ma ograniczoną wbudowaną obsługę - wiele struktur JSON i wartości nie może być automatycznie konwertowanych w obie strony. Pamiętaj, że korzystam z ustawień domyślnych z biblioteką Newtonsoft JSON i biblioteką MS XML, więc twój przebieg może się różnić:
XML -> JSON
{}
LUB zagnieżdżonymi tablicami, w[ {} {} ...]
zależności od tego, czy jest tylko jeden, czy więcej niż jeden element potomny XML. Zużyłbyś je w różny sposób w JavaScript itp. Różne przykłady XML zgodnego z tym samym schematem mogą w ten sposób wytwarzać różne struktury JSON. Możesz dodać atrybut json: Array = 'true' do swojego elementu, aby obejść to w niektórych (ale niekoniecznie wszystkich) przypadkach.Nowa aktualizacja to zmienia (dzięki Jon Story za zwrócenie na to uwagi): https://www.newtonsoft.com/json/help/html/T_Newtonsoft_Json_NullValueHandling.htm
JSON -> XML
Możesz wspomnieć o wszelkich innych zauważonych problemach. Opracowałem własne niestandardowe procedury przygotowywania i czyszczenia ciągów podczas konwersji w tę iz powrotem. Twoja sytuacja może, ale nie musi wymagać przygotowania / czyszczenia. Jak wspomina StaxMan, twoja sytuacja może wymagać konwersji między obiektami ... może to pociągać za sobą odpowiednie interfejsy i kilka instrukcji case / etc do obsługi ostrzeżeń, o których wspomniałem powyżej.
źródło
Możesz wykonać te konwersje również w .NET Framework:
JSON na XML: przy użyciu System.Runtime.Serialization.Json
XML do JSON: przy użyciu System.Web.Script.Serialization
źródło
Nie jestem pewien, czy taka konwersja ma sens (tak, wielu to robi, ale głównie, aby przeforsować kwadratowy kołek przez okrągły otwór) - występuje niedopasowanie impedancji strukturalnej, a konwersja jest stratna. Odradzam więc takie transformacje między formatami.
Ale jeśli to zrobisz, najpierw przekonwertuj z json na obiekt, a następnie z obiektu na xml (i odwrotnie dla odwrotnego kierunku). Wykonanie bezpośredniej transformacji prowadzi do brzydkich wyników, utraty informacji lub być może obu naraz.
źródło
Dzięki dla Davida Browna odpowiedź . W moim przypadku JSON.Net 3.5 metody konwersji znajdują się w klasie statycznej JsonConvert:
źródło
Długo szukałem alternatywnego kodu do zaakceptowanego rozwiązania w nadziei, że nie użyję zewnętrznego zespołu / projektu. Wymyśliłem następujące dzięki kodowi źródłowemu projektu DynamicJson :
Uwaga: Chciałem XmlDocument zamiast XElement dla celów xPath. Ponadto, ten kod oczywiście przechodzi tylko z JSON na XML, istnieją różne sposoby, aby zrobić odwrotnie.
źródło
Oto pełny kod c # do konwersji xml do json
Aby przekonwertować dany ciąg XML na JSON, wystarczy wywołać funkcję XmlToJSON () jak poniżej.
źródło
Wypróbuj tę funkcję. Właśnie to napisałem i nie miałem wiele okazji do przetestowania, ale moje wstępne testy są obiecujące.
źródło
Oto prosty fragment kodu, który konwertuje XmlNode (rekurencyjnie) na tablicę mieszającą i grupuje wiele instancji tego samego dziecka w tablicy (jako ArrayList). Hashtable jest zwykle akceptowany do konwersji na JSON przez większość bibliotek JSON.
źródło
Cinchoo ETL - biblioteka open source dostępna do łatwej konwersji Xml na JSON z kilkoma liniami kodu
Xml -> JSON:
JSON -> Xml:
Zapoznaj się z artykułem CodeProject, aby uzyskać dodatkową pomoc.
Oświadczenie: Jestem autorem tej biblioteki.
źródło
Tak jak powiedział David Brown, ale dostałem następujący wyjątek.
Jednym rozwiązaniem byłoby zmodyfikowanie pliku XML za pomocą elementu głównego, ale nie zawsze jest to konieczne, a dla strumienia XML może to również nie być możliwe. Moje rozwiązanie poniżej:
Przykładowy XML, który generuje błąd:
źródło
Użyłem poniższych metod do konwersji JSON na XML
I
Użyłem klasy o nazwie Przedmiot do przedstawienia elementów
To działa....
źródło
Aby przekonwertować
JSON
ciąg,XML
spróbuj tego:Do konwersji
XML
doJSON
spróbuj tego:źródło
użyj biblioteki innej firmy, zamiast pisać własny kod do parsowania JSON lub XML String. Jeśli jest to jednorazowe użycie, spróbuj przekonwertować go online. Json do Xml https://www.easycodeforall.com/Json2Xml.jsp Xml do Json https://www.easycodeforall.com/Xml2Json.jsp
źródło