it-swarm.com.de

Wie konvertiere ich JSON in XML oder XML in JSON?

Ich fing an, Json.NET zu verwenden, um einen String im JSON-Format in object oder viceversa zu konvertieren. Ich bin mir nicht sicher, ob es im Json.NET-Framework möglich ist, eine Zeichenfolge in JSON in das XML-Format und umgekehrt zu konvertieren.

246
David.Chu.ca

Ja. Verwenden Sie für diesen genauen Zweck die JsonConvert-Klasse, die Hilfsmethoden enthält:

// To convert an XML node contained in string xml into a JSON string   
XmlDocument doc = new XmlDocument();
doc.LoadXml(xml);
string jsonText = JsonConvert.SerializeXmlNode(doc);

// To convert JSON text contained in string json into an XML node
XmlDocument doc = JsonConvert.DeserializeXmlNode(json);

Dokumentation hier: Konvertierung zwischen JSON und XML mit Json.NET

391
David Brown

Ja, Sie können es tun (ich tue es), aber seien Sie sich einiger Paradoxe bewusst, wenn Sie konvertieren, und gehen Sie angemessen damit um. Sie können nicht alle Schnittstellenmöglichkeiten automatisch anpassen, und die integrierte Unterstützung für die Steuerung der Konvertierung ist begrenzt. Viele JSON-Strukturen und -Werte können nicht automatisch in beide Richtungen konvertiert werden. Beachten Sie, dass ich die Standardeinstellungen für die Newtonsoft JSON-Bibliothek und die MS XML-Bibliothek verwende, sodass Ihre Laufleistung variieren kann:

XML -> JSON

  1. Alle Daten werden zu Zeichenfolgendaten (zum Beispiel erhalten Sie immer "false" nicht false oder "0" nicht 0 ) Offensichtlich behandelt JavaScript diese in bestimmten Fällen unterschiedlich.
  2. Untergeordnete Elemente können zu verschachtelten Objekten _{}_ OR verschachtelten Arrays _[ {} {} ...]_ werden, je nachdem, ob es nur ein oder mehrere untergeordnete XML-Elemente gibt. Sie würden diese beiden in JavaScript usw. unterschiedlich verwenden. Verschiedene XML-Beispiele, die demselben Schema entsprechen, können auf diese Weise tatsächlich unterschiedliche JSON-Strukturen erzeugen. Sie können das Attribut json: Array = 'true' zu Ihrem Element hinzufügen, um dies in einigen Fällen zu umgehen (aber nicht unbedingt alle) Fälle.
  3. Ihr XML muss ziemlich wohlgeformt sein. Ich habe bemerkt, dass es nicht perfekt dem W3C-Standard entsprechen muss, aber 1. Sie müssen eine Wurzel haben Element und 2. Sie können Elementnamen nicht mit Zahlen beginnen. Dies sind zwei der erzwungenen XML-Standards, die ich bei der Verwendung von Newtonsoft- und MS-Bibliotheken gefunden habe.
  4. In älteren Versionen werden leere Elemente nicht in JSON konvertiert. Sie werden ignoriert. Ein leeres Element wird nicht zu "Element": null

Ein neues Update ändert dies (Dank an Jon Story für den Hinweis): https://www.newtonsoft.com/json/help/html/T_Newtonsoft_Json_NullValueHandling.htm

JSON -> XML

  1. Sie benötigen ein Objekt der obersten Ebene, das in ein XML-Stammelement konvertiert wird. Andernfalls schlägt der Parser fehl.
  2. Ihre Objektnamen dürfen nicht mit einer Zahl beginnen, da sie nicht in Elemente konvertiert werden können (XML ist technisch noch strenger), aber ich kann mich damit abfinden, einige der anderen Benennungsregeln für Elemente zu brechen.

Bitte zögern Sie nicht, andere Probleme zu erwähnen, die Sie bemerkt haben. Ich habe meine eigenen benutzerdefinierten Routinen zum Vorbereiten und Reinigen der Zeichenfolgen beim Konvertieren hin und her entwickelt. Ihre Situation erfordert möglicherweise Vorbereitungen/Aufräumarbeiten. Wie StaxMan erwähnt, kann es in Ihrer Situation tatsächlich erforderlich sein, dass Sie zwischen Objekten konvertieren. Dies kann geeignete Schnittstellen und eine Reihe von case-Anweisungen/etc zur Folge haben, um die oben erwähnten Vorbehalte zu beseitigen.

42
DaFi4

Sie können diese Konvertierungen auch mit .NET Framework durchführen:

JSON nach XML: mit System.Runtime.Serialization.Json

var xml = XDocument.Load(JsonReaderWriterFactory.CreateJsonReader(
    Encoding.ASCII.GetBytes(jsonString), new XmlDictionaryReaderQuotas()));

XML zu JSON: mithilfe von System.Web.Script.Serialization

var json = new JavaScriptSerializer().Serialize(GetXmlData(XElement.Parse(xmlString)));

private static Dictionary<string, object> GetXmlData(XElement xml)
{
    var attr = xml.Attributes().ToDictionary(d => d.Name.LocalName, d => (object)d.Value);
    if (xml.HasElements) attr.Add("_value", xml.Elements().Select(e => GetXmlData(e)));
    else if (!xml.IsEmpty) attr.Add("_value", xml.Value);

    return new Dictionary<string, object> { { xml.Name.LocalName, attr } };
}
30
Termininja

Danke für die Antwort von David Brown. In meinem Fall von JSON.Net 3.5 befinden sich die Konvertierungsmethoden unter der statischen Klasse von JsonConvert:

XmlNode myXmlNode = JsonConvert.DeserializeXmlNode(myJsonString); // is node not note
// or .DeserilizeXmlNode(myJsonString, "root"); // if myJsonString does not have a root
string jsonString = JsonConvert.SerializeXmlNode(myXmlNode);
26
David.Chu.ca

Ich bin mir nicht sicher, ob es bei einer solchen Umwandlung einen Punkt gibt (ja, viele tun es, aber meistens, um einen quadratischen Stift durch ein rundes Loch zu zwingen) - es gibt eine strukturelle Impedanzinkongruenz und die Umwandlung ist verlustbehaftet. Ich würde also gegen solche Format-zu-Format-Transformationen empfehlen.

Wenn Sie dies tun, konvertieren Sie zuerst von Json zu Objekt, dann von Objekt in XML (und umgekehrt für die umgekehrte Richtung). Direkte Transformation führt zu hässlicher Ausgabe, Informationsverlust oder möglicherweise zu beidem.

25
StaxMan

Ich habe lange gesucht, um alternativen Code für die akzeptierte Lösung zu finden, in der Hoffnung, keine externen Assemblys/Projekte zu verwenden. Dank des Quellcodes des DynamicJson -Projekts habe ich Folgendes gefunden:

public XmlDocument JsonToXML(string json)
{
    XmlDocument doc = new XmlDocument();

    using (var reader = JsonReaderWriterFactory.CreateJsonReader(Encoding.UTF8.GetBytes(json), XmlDictionaryReaderQuotas.Max))
    {
        XElement xml = XElement.Load(reader);
        doc.LoadXml(xml.ToString());
    }

    return doc;
}

Hinweis: Ich wollte für XPath-Zwecke ein XmlDocument-Objekt anstelle eines XElement-Dokuments .. Dieser Code geht natürlich nur von JSON zu XML.

8
yourbuddypal

Hier ist der vollständige C # -Code zum Konvertieren von XML in Json

public static class JSon
{
public static string XmlToJSON(string xml)
{
    XmlDocument doc = new XmlDocument();
    doc.LoadXml(xml);

    return XmlToJSON(doc);
}
public static string XmlToJSON(XmlDocument xmlDoc)
{
    StringBuilder sbJSON = new StringBuilder();
    sbJSON.Append("{ ");
    XmlToJSONnode(sbJSON, xmlDoc.DocumentElement, true);
    sbJSON.Append("}");
    return sbJSON.ToString();
}

//  XmlToJSONnode:  Output an XmlElement, possibly as part of a higher array
private static void XmlToJSONnode(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 = new SortedList<string, object>();

    //  Add in all node attributes
    if (node.Attributes != null)
        foreach (XmlAttribute attr in node.Attributes)
            StoreChildNode(childNodeNames, attr.Name, attr.InnerText);

    //  Add in all nodes
    foreach (XmlNode cnode in node.ChildNodes)
    {
        if (cnode is XmlText)
            StoreChildNode(childNodeNames, "value", cnode.InnerText);
        else if (cnode is XmlElement)
            StoreChildNode(childNodeNames, cnode.Name, cnode);
    }

    // Now output all stored info
    foreach (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 (object Child in 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.
private static void StoreChildNode(SortedList<string, object> childNodeNames, string nodeName, object nodeValue)
{
    // Pre-process contraction of XmlElement-s
    if (nodeValue is XmlElement)
    {
        // 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;
            else if (children.Count == 1 && (children[0] is XmlText))
                nodeValue = ((XmlText)(children[0])).InnerText;
        }
    }
    // Add nodeValue to ArrayList associated with each nodeName
    // If nodeName doesn't exist then add it
    List<object> ValuesAL;

    if (childNodeNames.ContainsKey(nodeName))
    {
        ValuesAL = (List<object>)childNodeNames[nodeName];
    }
    else
    {
        ValuesAL = new List<object>();
        childNodeNames[nodeName] = ValuesAL;
    }
    ValuesAL.Add(nodeValue);
}

private static void OutputNode(string childname, object alChild, StringBuilder sbJSON, bool showNodeName)
{
    if (alChild == null)
    {
        if (showNodeName)
            sbJSON.Append("\"" + SafeJSON(childname) + "\": ");
        sbJSON.Append("null");
    }
    else if (alChild is string)
    {
        if (showNodeName)
            sbJSON.Append("\"" + SafeJSON(childname) + "\": ");
        string sChild = (string)alChild;
        sChild = sChild.Trim();
        sbJSON.Append("\"" + SafeJSON(sChild) + "\"");
    }
    else
        XmlToJSONnode(sbJSON, (XmlElement)alChild, showNodeName);
    sbJSON.Append(", ");
}

// Make a string safe for JSON
private static string SafeJSON(string sIn)
{
    StringBuilder sbOut = new StringBuilder(sIn.Length);
    foreach (char ch in sIn)
    {
        if (Char.IsControl(ch) || ch == '\'')
        {
            int ich = (int)ch;
            sbOut.Append(@"\u" + ich.ToString("x4"));
            continue;
        }
        else if (ch == '\"' || ch == '\\' || ch == '/')
        {
            sbOut.Append('\\');
        }
        sbOut.Append(ch);
    }
    return sbOut.ToString();
 }
}

Um eine bestimmte XML-Zeichenfolge in JSON zu konvertieren, rufen Sie einfach die XmlToJSON () - Funktion wie folgt auf.

string xml = "<menu id=\"file\" value=\"File\"> " +
              "<popup>" +
                "<menuitem value=\"New\" onclick=\"CreateNewDoc()\" />" +
                "<menuitem value=\"Open\" onclick=\"OpenDoc()\" />" +
                "<menuitem value=\"Close\" onclick=\"CloseDoc()\" />" +
              "</popup>" +
            "</menu>";

string json = JSON.XmlToJSON(xml);
// json = { "menu": {"id": "file", "popup": { "menuitem": [ {"onclick": "CreateNewDoc()", "value": "New" }, {"onclick": "OpenDoc()", "value": "Open" }, {"onclick": "CloseDoc()", "value": "Close" } ] }, "value": "File" }}
5
Nimesh khatri

Versuchen Sie diese Funktion. Ich habe es gerade geschrieben und hatte keine große Chance, es zu testen, aber meine vorläufigen Tests sind vielversprechend.

public static XmlDocument JsonToXml(string json)
{
    XmlNode newNode = null;
    XmlNode appendToNode = null;
    XmlDocument returnXmlDoc = new XmlDocument();
    returnXmlDoc.LoadXml("<Document />");
    XmlNode rootNode = returnXmlDoc.SelectSingleNode("Document");
    appendToNode = rootNode;

    string[] arrElementData;
    string[] arrElements = json.Split('\r');
    foreach (string element in arrElements)
    {
        string processElement = element.Replace("\r", "").Replace("\n", "").Replace("\t", "").Trim();
        if ((processElement.IndexOf("}") > -1 || processElement.IndexOf("]") > -1) && appendToNode != rootNode)
        {
            appendToNode = appendToNode.ParentNode;
        }
        else if (processElement.IndexOf("[") > -1)
        {
            processElement = processElement.Replace(":", "").Replace("[", "").Replace("\"", "").Trim();
            newNode = returnXmlDoc.CreateElement(processElement);
            appendToNode.AppendChild(newNode);
            appendToNode = newNode;
        }
        else if (processElement.IndexOf("{") > -1 && processElement.IndexOf(":") > -1)
        {
            processElement = processElement.Replace(":", "").Replace("{", "").Replace("\"", "").Trim();
            newNode = returnXmlDoc.CreateElement(processElement);
            appendToNode.AppendChild(newNode);
            appendToNode = newNode;
        }
        else
        {
            if (processElement.IndexOf(":") > -1)
            {
                arrElementData = processElement.Replace(": \"", ":").Replace("\",", "").Replace("\"", "").Split(':');
                newNode = returnXmlDoc.CreateElement(arrElementData[0]);
                for (int i = 1; i < arrElementData.Length; i++)
                {
                    newNode.InnerText += arrElementData[i];
                }

                appendToNode.AppendChild(newNode);
            }
        }
    }

    return returnXmlDoc;
}
4
Jamon Crockom

Hier ist ein einfacher Ausschnitt, der einen XmlNode (rekursiv) in eine Hashtabelle konvertiert und mehrere Instanzen desselben untergeordneten Objekts in einem Array (als ArrayList) gruppiert. Die Hashtable wird normalerweise von den meisten JSONs in JSON konvertiert Bibliotheken.

protected object convert(XmlNode root){
    Hashtable obj = new Hashtable();
    for(int i=0,n=root.ChildNodes.Count;i<n;i++){
        object result = null;
        XmlNode current = root.ChildNodes.Item(i);

        if(current.NodeType != XmlNodeType.Text)
            result = convert(current);
        else{
            int resultInt;
            double resultFloat;
            bool resultBoolean;
            if(Int32.TryParse(current.Value, out resultInt)) return resultInt;
            if(Double.TryParse(current.Value, out resultFloat)) return resultFloat;
            if(Boolean.TryParse(current.Value, out resultBoolean)) return resultBoolean;
            return current.Value;
        }

        if(obj[current.Name] == null)
            obj[current.Name] = result;
        else if(obj[current.Name].GetType().Equals(typeof(ArrayList)))
            ((ArrayList)obj[current.Name]).Add(result);
        else{
            ArrayList collision = new ArrayList();
            collision.Add(obj[current.Name]);
            collision.Add(result);
            obj[current.Name] = collision;
        }
    }

    return obj;
}
2
kronenthaler

Um JSON in XML zu konvertieren, versuchen Sie Folgendes:

    public string JsonToXML(string json)
    {
        XDocument xmlDoc = new XDocument(new XDeclaration("1.0", "utf-8", ""));
        XElement root = new XElement("Root");
        root.Name = "Result";

        var dataTable = JsonConvert.DeserializeObject<DataTable>(json);
        root.Add(
                 from row in dataTable.AsEnumerable()
                 select new XElement("Record",
                                     from column in dataTable.Columns.Cast<DataColumn>()
                                     select new XElement(column.ColumnName, row[column])
                                    )
               );


        xmlDoc.Add(root);
        return xmlDoc.ToString();
    }

Zum Konvertieren von XML in JSON versuchen Sie Folgendes:

    public string XmlToJson(string xml)
    {
       XmlDocument doc = new XmlDocument();
       doc.LoadXml(xml);

       string jsonText = JsonConvert.SerializeXmlNode(doc);
       return jsonText;
     }
0
Hasan Fathi

Ich habe es wie David Brown gesagt, aber ich bekam die folgende Ausnahme. 

$exception {"There are multiple root elements. Line , position ."} System.Xml.XmlException

Eine Lösung wäre, die XML-Datei mit einem Root-Element zu ändern. Dies ist jedoch nicht immer erforderlich und für einen XML-Stream möglicherweise auch nicht möglich. Meine Lösung unten:

var path = Path.GetFullPath(Path.Combine(Environment.CurrentDirectory, @"..\..\App_Data"));
var directoryInfo = new DirectoryInfo(path);
var fileInfos = directoryInfo.GetFiles("*.xml");

foreach (var fileInfo in fileInfos)
{
    XmlDocument doc = new XmlDocument();
    XmlReaderSettings settings = new XmlReaderSettings();
    settings.ConformanceLevel = ConformanceLevel.Fragment;

    using (XmlReader reader = XmlReader.Create(fileInfo.FullName, settings))
    {
        while (reader.Read())
        {
            if (reader.NodeType == XmlNodeType.Element)
            {
                var node = doc.ReadNode(reader);
                string json = JsonConvert.SerializeXmlNode(node);
            }
        }
    }
}

Beispiel-XML, das den Fehler generiert:

<parent>
    <child>
        Text
    </child>
</parent>
<parent>
    <child>
        <grandchild>
            Text
        </grandchild>
        <grandchild>
            Text
        </grandchild>
    </child>
    <child>
        Text
    </child>
</parent>
0
Ogglas

Cinchoo ETL - eine Open-Source-Bibliothek, die für die einfache Konvertierung von XML in JSON mit wenigen Codezeilen verfügbar ist

Xml -> JSON:

using (var p = new ChoXmlReader("sample.xml"))
{
    using (var w = new ChoJSONWriter("sample.json"))
    {
        w.Write(p);
    }
}

JSON -> Xml:

using (var p = new ChoJsonReader("sample.json"))
{
    using (var w = new ChoXmlWriter("sample.xml"))
    {
        w.Write(p);
    }
}

Checkout CodeProject-Artikel für zusätzliche Hilfe.

Haftungsausschluss: Ich bin der Autor dieser Bibliothek.

0
RajN

Ich habe die folgenden Methoden verwendet, um JSON in XML zu konvertieren

        List<Item> items;
        public void LoadJsonAndReadToXML()
        {
            using (StreamReader r = new StreamReader(@"E:\Json\overiddenhotelranks.json"))
            {
                string json = r.ReadToEnd();
                items = JsonConvert.DeserializeObject<List<Item>>(json);
                ReadToXML();
            }
        }

und 

        public void ReadToXML()
        {    
            try
            {
                var xEle = new XElement("Items",
                            from item in items
                            select new XElement("Item",
                                           new XElement("mhid", item.mhid),
                                           new XElement("hotelName", item.hotelName),
                                           new XElement("destination", item.destination),
                                           new XElement("destinationID", item.destinationID),
                                           new XElement("rank", item.rank),
                                           new XElement("toDisplayOnFod", item.toDisplayOnFod),
                                           new XElement("comment", item.comment),
                                           new XElement("Destinationcode", item.Destinationcode),
                                           new XElement("LoadDate", item.LoadDate)
                                       ));

                xEle.Save("E:\\employees.xml");
                Console.WriteLine("Converted to XML");
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
            Console.ReadLine();
        }

Ich habe die Klasse mit dem Namen Item verwendet, um die Elemente darzustellen

    public class Item
    {
        public int mhid { get; set; }
        public string hotelName { get; set; }
        public string destination { get; set; }
        public int destinationID { get; set; }
        public int rank { get; set; }
        public int toDisplayOnFod { get; set; }
        public string comment { get; set; }
        public string Destinationcode { get; set; }
        public string LoadDate { get; set; }

    }

Es klappt....

0
Sai Ram Sagar