Frage

Ich begann Json.NET zu verwenden, eine Zeichenfolge im JSON-Format zu konvertieren oder umgekehrt zu widersprechen. Ich bin nicht sicher, ob in dem Json.NET Rahmen ist es möglich, eine Zeichenfolge in JSON zu XML-Format und umgekehrt zu konvertieren?

War es hilfreich?

Lösung

Ja. Mit Hilfe der JsonConvert Klasse, die Hilfsmethoden für diesen genauen Zweck 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: Konvertieren zwischen JSON und XML mit Json.NET

Andere Tipps

Ja, Sie können tun es (ich), aber beachten Sie einige Paradoxien bei der Konvertierung und behandeln entsprechend. Sie können nicht automatisch auf alle Schnittstellen Möglichkeiten entsprechen, und es beschränkt sich integrierte Unterstützung in der Konvertierungs- viele JSON Strukturen steuern und Werte können nicht automatisch in beide Richtungen umgerechnet werden. Denken Sie daran, ich bin mit den Standardeinstellungen mit Newtonsoft JSON Bibliothek und MS XML-Bibliothek, so die Leistung kann variieren:

XML -> JSON

  1. wird alle Datenstring-Daten (zum Beispiel werden Sie immer erhalten "false" nicht false oder "0" nicht 0 ) Offensichtlich JavaScript diese unterschiedlich in bestimmten Fällen behandelt.
  2. können Kinder Elemente werden verschachteltes Objekt {} oder verschachtelten Array [ {} {} ...] je nachdem, ob es nur eine oder mehr als eine XML-Kind-Element ist. Sie würden diese zwei unterschiedlich in JavaScript etc. Verschiedene Beispiele von XML verbrauchen zu demselben Schema entsprechen, auf diese Weise tatsächlich verschiedene JSON Strukturen erzeugen kann. Sie können das Attribut hinzufügen json: Array = 'true' zu Ihrem Element dies in einigen Umgehung (aber nicht notwendigerweise alle) Fälle.
  3. Ihre XML muss sein ziemlich wohlgeformt, ich habe es nicht bemerkt zu W3C-Standard perfekt entspricht nicht brauchen, aber 1. Sie müssen ein Root-Element haben und 2. Sie können nicht Element starten Namen mit Nummern werden zwei der erzwungenen XML-Standards habe ich gefunden, wenn Bibliotheken Newtonsoft und MS verwenden.
  4. In älteren Versionen, Blank Elemente nicht konvertieren zu JSON. Sie werden ignoriert. Ein leeres Element nicht worden "Element": null

Ein neues Update ändert diese (Danke an Jon Geschichte es für den Hinweis auf): https://www.newtonsoft.com/json/help/html/T_Newtonsoft_Json_NullValueHandling.htm

JSON -> XML

  1. Sie müssen ein Top-Level-Objekt, das in einem Stamm XML-Elemente oder den Parser konvertiert wird fehlschlagen.
  2. Ihre Objektnamen können nicht mit einer Zahl beginnen, da sie nicht auf Elemente umgewandelt werden können (XML ist technisch noch strenger als das), aber ich kann ‚weg‘ mit einigen anderen Element zu brechen Benennungsregeln.

Bitte fühlen Sie sich frei, alle andere Fragen zu erwähnen Sie vielleicht bemerkt haben, ich habe meine eigenen benutzerdefinierten Routinen zur Herstellung und Reinigung der Saiten, wie ich hin und her konvertieren entwickelt. Ihre Situation kann oder für prep / Bereinigung nicht nennen. Wie StaxMan erwähnt, kann Ihre Situation tatsächlich verlangt, dass Sie zwischen den Objekten zu konvertieren ... das entsprechende Schnittstellen und einer Reihe von Fall Aussagen zur Folge haben könnte / etc die Einsprüche zu handhaben ich oben erwähnt hat.

Sie können diese Konvertierungen auch mit dem .NET-Framework:

JSON zu XML: , indem Sie System.Runtime.Serialization.Json

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

XML zu JSON: , indem Sie 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 } };
}

Ich bin mir nicht sicher, dass es Punkt in einer solchen Umwandlung ist (ja, viele tun es, aber meist einen quadratischen Pflock durch rundes Loch zu zwingen) - es strukturelle Impedance Mismatch ist, und die Umwandlung ist verlustbehaftet. Deshalb würde ich empfehlen, solche Format zu Format-Transformationen.

Aber wenn Sie es tun, zuerst von Json Objekt umwandeln, dann von Objekt zu XML (und umgekehrt für die Rückwärtsrichtung). direkte Umwandlung zu tun führt zu hässlichen Ausgang, Verlust von Informationen oder möglicherweise beides.

Vielen Dank für David Brown Antwort. In meinem Fall von JSON.Net 3.5 sind die convert Methoden unter der JsonConvert statischen Klasse:

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);

ich für eine lange Zeit gesucht alternativen Code an die akzeptierten Lösung in der Hoffnung, nicht mit einem externen Montag / Projekt. Ich kam mit dem folgenden dank der Quellcode des DynamicJson Projektes auf:

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 ein XmlDocument anstatt eine XElement für xPath Zwecke wollte. Auch dieser Code offensichtlich geht nur von JSON zu XML, gibt es verschiedene Möglichkeiten, um das Gegenteil zu tun.

Hier ist die vollständige c # -Code zu XML zu JSON konvertieren

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 ein bestimmtes XML-String zu JSON konvertieren, rufen Sie einfach XmlToJSON () Funktion, wie unten.

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" }}

Versuchen Sie, diese Funktion. Ich schrieb es einfach und haben nicht viel von einer Chance hatte, es zu testen, aber meine Vorversuche 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;
}

Hier ist ein einfacher Schnipsel, die eine XmlNode (rekursiv) in eine Hash-Tabelle umwandelt und Gruppen mehr Instanzen des gleichen Kindes in eine Anordnung (als ein Arraylist). Die Hashtable ist in der Regel von den meisten der JSON-Bibliotheken zu konvertieren in JSON akzeptiert.

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;
}

Ich habe wie David Brown sagte, aber ich habe 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-Elemente zu ändern, aber das ist nicht immer notwendig, und für eine XML-Stream es entweder nicht möglich sein könnte. Meine Lösung unter:

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, die den Fehler erzeugt:

<parent>
    <child>
        Text
    </child>
</parent>
<parent>
    <child>
        <grandchild>
            Text
        </grandchild>
        <grandchild>
            Text
        </grandchild>
    </child>
    <child>
        Text
    </child>
</parent>

Cinchoo ETL - eine Open-Source-Bibliothek zur Verfügung, die Umwandlung von XML zu JSON zu tun leicht mit wenigen Zeilen Code

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);
    }
}

Zur Kasse Artikel Codeproject für einige zusätzliche Hilfe.

Disclaimer:. Ich bin der Autor dieser Bibliothek

Ich habe die unten Methoden verwendet, um die 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 Element verwendet, um die Elemente zu repräsentieren

    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 funktioniert ....

Für convert JSON Zeichenfolge dies zu XML versuchen:

    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();
    }

Für convert XML JSON dies versuchen:

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

       string jsonText = JsonConvert.SerializeXmlNode(doc);
       return jsonText;
     }
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top