Soru JSON XML veya XML'e JSON'a nasıl dönüştürülür?


JON.NET'i JSON biçimindeki bir dizeyi nesne veya viceversa dönüştürmek için kullanmaya başladım. Ben Json.NET çerçevesinde emin değilim, JSON bir dize XML formatına ve viceversa dönüştürmek mümkün mü?


232
2018-05-02 02:25


Menşei




Cevaplar:


Evet. Bu kesin amaç için yardımcı yöntemler içeren JsonConvert sınıfını kullanma:

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

Belgeler burada: Json.NET ile JSON ve XML arasında dönüştürme


359
2018-05-02 02:58



Bu sınıfı bulamadım. NewtonSoft Json.net 3.5 kullanıyorum. - David.Chu.ca
Görünüşe göre bu işlevsellik JSON.NET 3.5'deki Newtonsoft.Json.Converters.XmlNodeConverter sınıfına taşındı: james.newtonking.com/projects/json/help/html/... - David Brown
Oraya baktım ama örnek kodların orada değil. Dönüşümleri yapmak için yeni kütüphaneleri kullanacak örnek kodlar var mı? - David.Chu.ca
Sürpriz sürpriz - bu XML ve JSON arasındaki empedans ve neden (IMO) nedeni iyi bir fikir değil direkt olarak ikisi arasında dönüştürmek. Ancak, hey, burada kesinlikle katılmıyorum çok fazla dev var (cevabımdaki düşüşe göre) ve bu yanlışlıkla veri dönüşümleri veya potansiyel veri kaybı sakıncası yok ... - StaxMan
@StaxMan: Herkesin JSON formatında bir XML belgesini temsil etmenin standart bir yolu olmadığını kabul edebilirim. Cevabınız muhtemelen cevap vermiyordu çünkü bu soruya cevap vermedi. OP sormadı mı diye sormadı. meli dönüşüm yapmak, ama eğer o could Halihazırda elindeki araçları kullanarak yapın. - David Brown


Evet sen kutu Yaparım (Yaparım) ancak dönüştürürken ve param ele alındığında bazı paradokslardan haberdar olun. Tüm arayüz olanaklarına otomatik olarak uymazsınız ve dönüşümün kontrol edilmesinde sınırlı yerleşik destek vardır - birçok JSON yapısı ve değeri otomatik olarak iki yolla dönüştürülemez. Unutmayın ki varsayılan ayarları Newtonsoft JSON kütüphanesi ve MS XML kütüphanesi ile kullanıyorum, bu yüzden kilometreniz değişebilir:

XML -> JSON

  1. Tüm veriler string verisi olur (örneğin her zaman "yanlış" değil yanlış veya "0" değil 0Açıkçası JavaScript, bazı durumlarda bunları farklı şekilde ele alır.
  2. Çocuk elemanları yuvalanmış nesne olabilir {} VEYA yuvalanmış dizi [ {} {} ...] Sadece bir veya birden fazla XML alt öğe varlığına bağlı olarak. Bu ikisini JavaScript, vb. Farklı şekilde tüketirsiniz. Aynı şemaya uygun farklı XML örnekleri, bu şekilde aslında farklı JSON yapıları üretebilir. Özniteliği ekleyebilirsiniz json: Array = 'true' Bazı (ama mutlaka tüm) durumlarda bu geçici çözüm için öğenize.
  3. XML’iniz olmalıdır oldukça iyi biçimlendirilmiş, W3C standardına mükemmel uyum sağlamasının gerekmediğini fark ettim, ancak 1. bir kök öğeniz olmalı ve 2. öğe adlarını sayılarla başlatamazsınız. Kullanırken bulduğum zorla XML standartlarından ikisi Newtonsoft ve MS kütüphaneleri.
  4. Boş öğeler JSON'a dönüştürülmez. Onlar göz ardı edilir. Boş bir öğe olmaz "Eleman": null

JSON -> XML

  1. Bir kök XML öğesine dönüşecek veya ayrıştırıcı başarısız olacak bir üst düzey nesneye ihtiyacınız var.
  2. Nesne adlarınız, bir öğeyle dönüştürülemez, çünkü öğelere dönüştürülemezler (XML, teknik olarak bundan daha da katıdır), ancak diğer öğe adlandırma kurallarının bazılarını kırarak "kurtulabilirim".

Lütfen fark ettiğiniz diğer sorunları belirtmekten çekinmeyin, ileri geri dönerken dizeleri hazırlamak ve temizlemek için kendi özel rutinleri geliştirdim. Durumunuz hazırlık / temizleme için arayabilir veya aramayabilir. StaxMan'ın da belirttiği gibi, durumunuz aslında nesneler arasında dönüşüm yapmanızı gerektirebilir ... Bu, yukarıda bahsettiğim uyarıları ele almak için uygun arabirimler ve bir sürü vaka bildirimi / vb.


36
2017-08-13 15:26



Bu! Kısacası (ve bir noktada ağır bir şekilde düşürülmüş) cevabın ne olduğuna dayanan güzel bir ayrıntıya dayanıyordu - eğer doğrudan bir doğrudan dönüşüm yaparsanız, birçok tuzak var. Belirli kullanım için sorunları engelleyemeyebilirler, ancak başkaları için de çok kötü olabilirler. - StaxMan


David Brown'un cevabı için teşekkürler. JSON.Net 3.5 durumunda, dönüştürme yöntemleri JsonConvert statik sınıfının altında:

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
2018-05-03 02:01



Eğer verileriniz bir dizi ise o zaman şöyle bir şey yapmalısınız: JsonConvert.DeserializeXmlNode ("{\" Satır \ ":" + json + "}", "root") ToXmlString () aksi takdirde bir "XmlNodeConverter" alırsınız. sadece bir nesne ile başlayan JSON dönüştürebilirsiniz. " istisna. - Mitchell Skurnik
Evet, bir sayı ile başlayamazsın. JsonConvert.DeserializeXmlNode ("{\" 1Row \ ":" + json + "}", "root") ToXmlString () başarısız olur. - montewhizdoh
Yukarıdaki cevap ve @mitchell yorum bana yardımcı .. teşekkür - Ajay2707


Bu dönüşümleri ayrıca .NET Framework ile de yapabilirsiniz:

XML'e JSON: kullanarak System.Runtime.Serialization.Json

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

JSON'a XML: kullanarak 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 } };
}

25
2017-09-05 11:02



GetXmlData üzerinde bir hata alıyorum. "GetXmlData" adı geçerli bağlamda mevcut değil "Eksik olduğumu kullanma yönergesi var mı? - TimSmith-Aardwolf
@ TimSmith-yer kurdu, İşte ihtiyacınız olan tüm kod. İçin System.Web.Script.Serialization kullanarak eklemen gerek System.Web.Extensions Referanslarda derleme. - Termininja
@Termininja, JSON bana XML veren türü de, nasıl kaldırılır? - cracker
@cracker, bir varyant yazdım İşte. - Termininja
@ Termininja, Mükemmel, Teşekkürler. - cracker


Ben böyle bir dönüşümün noktası olduğundan emin değilim (evet, çoğu, ama çoğunlukla yuvarlak delikten bir kare pimi zorlamak için) - yapısal empedans uyuşmazlığı var ve dönüşüm zararlıdır. Bu yüzden format formatındaki dönüşümlere karşı tavsiye ederim.

Ama eğer bunu yaparsanız, önce jsondan nesneye, sonra nesneden xml'ye (ve ters yönde tersi) dönüştürün. Doğrudan dönüşüm yapmak çirkin çıktılara, bilgi kaybına veya muhtemelen her ikisine yol açar.


20
2018-05-02 03:29



Cevabınız parçalanmış olsa da, burada olduğuna sevindim. Dönüştürmeyi yapmak istiyorum ve c # orta nesnelerini atlamayı düşünüyordum, ama şimdi çok emin değilim. Aksi halde XSD'ye dayanan c # nesneleri üretmem gerekecek ve sadece dönüşüm amaçlı olduğu için boşa harcanan bir katman (ve çaba) gibi görünüyordu. Görmek için harika olacak nasıl kayıplı bir örnek veya daha fazla ayrıntı varsa. - CRice
Bunun neden düştüğünü bilmiyorum. Şu anda sahip olduğumuz bir üründe birkaç XML <-> JSON dönüşüm adımı ile ilgili bir sürü hatayı düzelttim. Çoğu, JSON'dan XML'e dönüştürülürken sayısal türlerin kaybına uğrar. - rikkit
Zor gerçek, yararlı bir cevap. - FailedUnitTest


Dış meclis / proje kullanmama umuduyla, kabul edilen çözüme alternatif bir kod bulmak için uzun bir süre aradım. Ben kaynak kodu sayesinde aşağıdaki ile geldi DynamicJson proje:

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

Not: xPath amaçları için bir XElement yerine bir XmlDocument istedim. Ayrıca, bu kod açıkça sadece JSON'dan XML'e gider, tam tersini yapmak için çeşitli yollar vardır.


8
2018-05-03 14:44



Bunu son zamanlarda bir SQLCLR'de yapmam gerekiyordu ve bağımlılığı alamadım bu yüzden mermiyi ısırdım ve bunu yazdım. json-xml dönüştürme rutiniŞaşırtıcı derecede basit ve sadece 20 satırlık kod vardı. - gordy
xml'den typr nasıl kaldırılır? - cracker


İşte xml json dönüştürmek için tam c # kodu

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

Belirli bir XML dizgisini JSON'a dönüştürmek için, aşağıdaki gibi XmlToJSON () işlevini çağırmanız yeterlidir.

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
2018-04-11 06:47





Bu işlevi deneyin. Sadece yazdım ve test etme şansı çok fazla olmadı, ama ön testlerim umut verici.

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
2018-03-03 15:29