从对象到 Json 到 Xml 到对象

Posted

技术标签:

【中文标题】从对象到 Json 到 Xml 到对象【英文标题】:From object to Json to Xml to object 【发布时间】:2021-12-24 00:27:23 【问题描述】:

我有这些课程:

public class House

    public MyObject[] Objects  get; set; 


public class MyObject

    public string Name  get; set; 

我这样实例化:

var house1 = new House

     Objects = new MyObject[]
     
          new MyObject()  Name = "Name1" ,
          new MyObject()  Name = "Name2" 
     
 ;

然后我得到它的 json 表示:

var jsonSerializerSettings = new JsonSerializerSettings()

    TypeNameHandling = TypeNameHandling.Objects
;
string json = JsonConvert.SerializeObject(house1, jsonSerializerSettings);

从后者我得到相关的 XML:

XmlDocument doc = (XmlDocument)Newtonsoft.Json.JsonConvert.DeserializeXmlNode(json, "House", true);
string xmlString = doc.OuterXml;

最后我把xml转换成初始类型的对象:

XmlSerializer serializer = new XmlSerializer(typeof(House));
TextReader reader = new StringReader(xmlString);
House house2 = (House)serializer.Deserialize(reader)

问题是:

为什么 house1 与 house2 不同? (house2.Objects 是空的!) 我做错了什么?

Here你可以找到一个dotnetfiddle的例子

【问题讨论】:

可能是因为您的 XML 元素上的 JSON 命名空间。你为什么要这样做? 【参考方案1】:

由 JSON 序列化器生成的 XML:

<House xmlns:json="http://james.newtonking.com/projects/json" json:type="Program+House, ayusorzt">
    <Objects json:type="Program+MyObject, ayusorzt">
       <Name>
           Name1
       </Name>
    </Objects> 
    <Objects json:type="Program+MyObject, ayusorzt">
       <Name>
           Name2
       </Name>
    </Objects>
</House>

XMLSerializer 无法解除此 XML 对象的脱轨。正确的 XML 对象应如下所示:

<House>
    <Objects>
       <MyObject>
           <Name>
               Name1
           </Name>
       </MyObject>       
       <MyObject>
           <Name>
               Name2
           </Name>
       </MyObject>
    </Objects> 
</House>

您可以通过以下代码修复它:

var xmlSerializer = new XmlSerializer<House>();
var obj = JsonConvert.DeserializeObject<House>();

using(StringWriter textWriter = new StringWriter())

    xmlSerializer.Serialize(textWriter, obj);
    string yourXml = textWriter.ToString();

【讨论】:

“正确的 XML 对象应该如下所示” - 两者都是正确的 XML,前者更正确。 感谢您的建议。在您看来,是否可以为 MyObject 类型的对象添加 xsi:type 属性?如果是,我该怎么办?【参考方案2】:

JsonConvert.DeserializeXmlNode 方法生成的 XML 不能与 XmlSerializer 互操作。

为了反序列化 XML,你需要使用 Newtonsoft.Json 本身

string json2 = JsonConvert.SerializeXmlNode(doc, Newtonsoft.Json.Formatting.None, true);
House house2 = JsonConvert.DeserializeObject<House>(json2);

编辑

要从与XmlSerializer 一起使用的json 生成XML,请将JSON 反序列化为一个对象,然后使用XmlSerializer 生成XML。

const string json = "\"Objects\":[\"Name\":\"Name1\",\"Name\":\"Name2\"]";
        
House house = JsonConvert.DeserializeObject<House>(json);
XmlSerializer serializer = new XmlSerializer(typeof(House));
        
StringBuilder sb = new StringBuilder();
using (XmlWriter writer = XmlWriter.Create(sb))

    serializer.Serialize(writer, house);


//Console.WriteLine(sb.ToString());

【讨论】:

对不起,我不明白你的回答;我的起点是 Json 字符串,在您的示例代码中,您假设已经有一个 XML“doc”字符串。从开始 Json 到最终的 XML 我应该执行哪些转换步骤? @DanieleMereu,我应该指定得更好。我的回复解决了您在代码中使用XmlSerializer 反序列化Newtonsoft.Json.JsonConvert.DeserializeXmlNode 生成的XML 时遇到的问题。您不能从 Newtonsoft.Json 获取 XML 输出并使用 XmlSerializer 对其进行操作。如果您希望将 JSON 转换为与 XmlSerializer 兼容的 XML,则将 JSON 反序列化为对象并使用 XmlSerializer 生成 XML 谢谢你,我明白了。在您看来,还有一件事是,在序列化过程中是否可以包含对象的 xsi:type 属性? (例如: 您的解决方案的不利方面是我需要实例化 House 对象以执行随后的 XML 转换。没有就不行吗? @DanieleMereu,我不知道直接从 JSON 到 XML 的稳健、通用的方法。

以上是关于从对象到 Json 到 Xml 到对象的主要内容,如果未能解决你的问题,请参考以下文章

Postman 从控制台导出 JSON 对象

Node JS的最佳JSON或JS对象到XML转换器模块是啥[关闭]

rest-assured的对象映射(序列化和反序列化)

POST JSON 数据到特定对象 iOS

保存数据到文件的模块(configparser,json,pickle,shelve,xml)_python

XML 到 JSON 有序列表