我开始使用Json.NET将JSON格式的字符串转换为对象,反之亦然。我不确定在Json.NET框架中是否可以将JSON中的字符串转换为XML格式,反之亦然?

评论

请注意,如StaxMan所说,如果有的话。元素节点中的空格,它将被xml忽略。对于前。 “学生ID”:属性名称中空格的xml结果bcuz不会为11000。 xml不接受元素节点内有空格。

#1 楼

是。使用JsonConvert类(其中包含用于此精确目的的辅助方法):

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


此处的文档:使用Json.NET在JSON和XML之间进行转换

评论


我找不到这堂课。我使用NewtonSoft Json.net 3.5。

– David.Chu.ca
09年5月2日在18:51

似乎此功能已移至JSON.NET 3.5中的Newtonsoft.Json.Converters.XmlNodeConverter类:james.newtonking.com/projects/json/help/html/…

–大卫·布朗(David Brown)
09年5月2日在20:01

仅供参考,这里有潜在的问题。当我将xml节点数组转换为json时,它正在json中创建数组。但是,当我遍历一个计数为1的xml节点数组时,json转换不再格式化数组了。具有单个元素的xml数组在此处的翻译中丢失了。

– Levitikon
2012年3月22日21:11



惊喜惊喜-这是XML和JSON之间的阻抗,也是(IMO)在两者之间直接转换不是一个好主意的原因。但是,嘿,有很多开发人员强烈反对这里(根据我的回答不赞成),并且不介意这些意外的数据转换或潜在的数据丢失...

– StaxMan
2012年8月1日在1:41

@StaxMan:我想每个人都可以同意,没有标准化的方式来表示JSON格式的XML文档。您的答案可能被否决了,因为它实际上并未回答问题。 OP并没有询问他是否应该进行转换,而是询问他是否可以使用已经可以使用的工具进行转换。

–大卫·布朗(David Brown)
2012年8月1日,3:08

#2 楼

是的,您可以做到(我可以做到),但是在转换时要注意一些悖论,并进行适当的处​​理。您无法自动符合所有接口的可能性,并且控制转换的内置支持有限-许多JSON结构和值无法自动以两种方式转换。请记住,我在Newtonsoft JSON库和MS XML库中使用默认设置,因此您的使用情况可能会有所不同:
XML-> JSON

所有数据都变成字符串数据(例如,您将总是得到“ false”不为false或“ 0”不为0)显然,JavaScript在某些情况下会区别对待。
子元素可以成为嵌套对象{}或嵌套数组[ {} {} ...],具体取决于是否只有一个或多个XML子元素。您将在JavaScript等中以不同的方式使用这两种方式。遵循同一模式的XML的不同示例可以通过这种方式实际产生不同的JSON结构。您可以在元素中添加属性json:Array ='true',以在某些(但不一定是所有)情况下解决此问题。
您的XML必须格式正确,我注意到它不需要完全符合W3C标准,但是1.您必须具有根元素,并且2.您不能以数字开头的元素名称是我在使用Newtonsoft和MS库时发现的两个强制执行的XML标准。
在较旧的版本中,空白元素不会转换为JSON。他们被忽略。空白元素不会成为“元素”:null


新的更新更改了null的处理方式(感谢Jon Story指出了这一点):https://www.newtonsoft .com / json / help / html / T_Newtonsoft_Json_NullValueHandling.htm
XML

您需要一个顶级对象,该对象将转换为根XML元素,否则解析器将失败。
您的对象名称不能以数字开头,因为它们不能转换为元素(从技术上讲,XML的严格性甚至更高),但是我可以打破其他一些元素命名规则来“逃脱”。

请随时提及您注意到的任何其他问题,我开发了自己的自定义例程,用于在来回转换时准备和清理字符串。您的情况可能会也可能不会要求进行准备/清除。正如StaxMan所提到的,您的情况实际上可能要求您在对象之间进行转换...这可能需要适当的接口和一堆case语句/等来处理我在上面提到的警告。

评论


这个!我简短的回答(有时有点被否定)的答案很好地阐述了-如果您盲目直接转换,会有很多很多陷阱。它们可能不会阻止特定用途的问题,但对其他人也可能很讨厌。

– StaxMan
16年1月12日在21:46

关于XML-> JSON上的#4:您可以使用NullValueHandling属性指定应明确包含空值-newtonsoft.com/json/help/html/…

–乔恩的故事
19年1月10日在14:40

此注释中的问题描述非常适用于将JSON转换为XML或反向的所有算法实现。一旦人们接受了不可能同时实现完美的双向保真度,并且同时以太“当事人”或“受约束的”(预定的模式/格式)的输入和输出是不可能的。 -在一般情况下。

– DALDEI
19年4月27日在4:35



#3 楼

您也可以使用.NET Framework进行以下转换:

从JSON到XML:通过使用System.Runtime.Serialization.Json

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


XML到JSON:通过使用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 } };
}


评论


我在GetXmlData上收到错误消息“当前上下文中不存在名称'GetXmlData'”是否缺少我使用的指令?

– TimSmith-Aardwolf
16年7月21日在14:09

@ TimSmith-Aardwolf,这是您需要的所有代码。要使用System.Web.Script.Serialization,需要在“引用”中添加System.Web.Extensions程序集。

–Termininja
16年7月21日在15:12

@Termininja,完美,谢谢。

–饼干
16年8月30日在4:34

#4 楼

我不确定这种转换是否有意义(是的,很多人都这样做,但主要是迫使方钉穿过圆孔)-结构阻抗不匹配,转换是有损耗的。因此,我建议您不要进行这种格式到格式的转换。但是,如果执行此操作,请先从json转换为对象,然后再从object转换为xml(反之亦然)。直接进行转换会导致输出丑陋,信息丢失或可能同时发生。

评论


即使您的答案被粉碎,我也很高兴它在这里。我想进行转换,正在考虑跳过c#中间对象,但现在还不确定。否则,我将需要基于XSD生成c#对象,因为它仅用于转换目的,因此看起来像是浪费的层(和精力)。如果您有示例或更多有关如何有损的详细信息,那将很高兴看到。

– CRice
2014年8月1日上午9:50

不知道为什么这被否决了。我目前正在修复与我们产品中的几个XML <-> JSON转换步骤有关的错误。从JSON转换为XML时,大多数归因于数字类型的丢失。

–rikkit
2014年11月3日,11:44

硬道理,有用的答案。

–FailedUnitTest
16年1月11日在16:14

@CRice Years为时已晚,但是拥有传输对象可以在某种程度上保留XML模式。例如,正如Levitikon提出的那样,如果您尝试转换具有单个元素数组的XML文档,则JSON转换无法知道它是一个数组,除非它来自具有数组类型的传输对象。

– jpaugh
19年7月5日在18:38

Newtonsoft.JSON的XmlNodeConverter具有配置选项,可避免从JSON转换为XML并转换回JSON时出现此问题,但无法捕获原始格式为XML的情况

– jpaugh
19年7月5日在18:38



#5 楼

感谢大卫·布朗的回答。以JSON.Net 3.5为例,convert方法在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);


评论


如果您的数据是数组,那么您需要执行以下操作:JsonConvert.DeserializeXmlNode(“ {\” Row \“:” + json +“}”,“ root”)。ToXmlString()否则,您将得到一个“ XmlNodeConverter只能转换以对象开头的JSON。”例外。

– Mitchell Skurnik
2015年2月17日,1:11

是的,您不能以数字开头。 JsonConvert.DeserializeXmlNode(“ {\” 1Row \“:” + json +“}”,“ root”)。ToXmlString()将失败

– DaFi4
16年1月18日在15:26

上面的答案和@mitchell评论对我有帮助..谢谢

– Ajay2707
17-10-5在11:18

#6 楼

我搜索了很长时间,以找到可接受的解决方案的替代代码,希望不使用外部程序集/项目。感谢DynamicJson项目的源代码,提出了以下内容:

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


注意:出于xPath的目的,我需要XmlDocument而不是XElement。 >此外,此代码显然仅从JSON到XML,有多种相反的方法。

评论


我最近需要在SQLCLR中执行此操作,并且无法获取依赖关系,因此我只是硬着头皮写了这个json-to-xml转换例程,它非常简单,仅约20行代码。

–哎呀
16年5月24日在21:42

如何从xml中删除类型?

–饼干
16年8月29日在9:34

#7 楼

这是将xml转换为json的完整c#代码。要将一个给定的XML字符串转换为JSON,只需调用XmlToJSON()函数,如下所示。

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


#8 楼

试试这个功能。我只是写了它,还没有太多的机会对其进行测试,但是我的初步测试很有希望。

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


#9 楼

这是一个简单的代码段,该代码段将XmlNode(递归地)转换为哈希表,并将同一子项的多个实例分组为一个数组(作为ArrayList)。
大多数情况下,通常都接受Hashtable转换为JSON。 JSON库。

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


#10 楼

Cinchoo ETL-一个开源库,可使用几行代码轻松地将Xml转换为JSON

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


签出CodeProject文章以获得更多帮助。

免责声明:我是该库的作者。

#11 楼

我确实像大卫·布朗说的那样,但是我得到了以下例外。

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


一种解决方案是使用根元素修改XML文件,但这并不总是必须的,对于XML流,也可能不可能。我在下面的解决方案:

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


生成错误的示例XML:

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


评论


您的示例XML不是XML文档,因为它没有单个根节点。但是,那可能是一个XML片段。

–罗伯特·麦基(Robert McKee)
19年2月12日在18:43

#12 楼

我已使用以下方法将JSON转换为XML

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




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


名为Item的类表示元素

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


它的工作原理....

#13 楼

要将JSON字符串转换为XML,请尝试以下操作:

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


要将XML转换为JSON请尝试以下操作:

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

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