【问题标题】:From object to Json to Xml to object从对象到 Json 到 Xml 到对象
【发布时间】: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 命名空间。你为什么要这样做?

标签: c# json xml


【解决方案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 的稳健、通用的方法。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-04
  • 2012-02-20
  • 2012-03-22
  • 1970-01-01
相关资源
最近更新 更多