C#中使用NewtonSoft将MyObject转为指定格式XML的问题
问题:NewtonSoft JSON转XML时集合节点格式不符合预期
自定义对象定义
public class MyObject { public string OrderId { get; set; } public string Installment { get; set; } public string Amount { get; set; } public List<Product> Products { get; set; } } public class Product { public string ProductCode { get; set; } public string ProductName { get; set; } public string Quantity { get; set; } public string Price { get; set; } }
当前转换方式及问题
通过先将对象序列化为JSON,再转换为XML的方式处理,但输出的XML中集合元素直接重复父节点名称(<products>),而非期望的<products>包裹多个<product>子节点。
辅助类代码
public static XNode XmlSerialize<T>(T ToXml, string root, JsonSerializerSettings settings) { var ToJson = JsonConvert.SerializeObject(ToXml, Newtonsoft.Json.Formatting.Indented, settings); return JsonConvert.DeserializeXNode(ToJson, root); } public static JsonSerializerSettings DefaultJsonSerializerSettings() { return new JsonSerializerSettings { ContractResolver = new CamelCasePropertyNamesContractResolver(), DefaultValueHandling = DefaultValueHandling.Ignore, NullValueHandling = NullValueHandling.Ignore }; }
测试代码
static void Main(string[] args) { XNode xml = Helper.XmlSerialize<MyObject>(new MyObject{ Amount = "100", OrderId = "123123123", Installment="1", Products = new List<Product> { new Product { ProductName = "Test", Price = "100" }, new Product { ProductName = "Test2", Price = "200" } } }, "auth", Helper.DefaultJsonSerializerSettings()); Console.WriteLine(xml.ToString()); Console.ReadKey(); }
当前输出XML
<auth> <orderId>123123123</orderId> <installment>1</installment> <amount>100</amount> <products> <productName>Test</productName> <price>100</price> </products> <products> <productName>Test2</productName> <price>200</price> </products> </auth>
期望输出XML
<auth> <orderId>123123123</orderId> <installment>1</installment> <amount>100</amount> <products> <product> <productName>Test</productName> <price>100</price> </product> <product> <productName>Test2</productName> <price>200</price> </product> </products> </auth>
解决方案
方案1:修改类的JSON序列化特性
给Product类添加[JsonObject("product")]特性,让JSON序列化时每个集合元素被标记为product,转换为XML时自动生成<product>节点:
[JsonObject("product")] public class Product { public string ProductCode { get; set; } public string ProductName { get; set; } public string Quantity { get; set; } public string Price { get; set; } }
修改后重新运行原测试代码,即可得到期望的XML格式。
方案2:直接使用XML序列化(跳过JSON转换)
放弃JSON中转步骤,直接用System.Xml.Serialization.XmlSerializer进行序列化,更直接且易控制格式:
- 修改
MyObject类,添加XmlArrayItem特性指定集合子节点名称:
public class MyObject { public string OrderId { get; set; } public string Installment { get; set; } public string Amount { get; set; } [XmlArrayItem("product")] public List<Product> Products { get; set; } }
- 新增直接序列化的辅助方法:
public static XNode XmlSerializeDirect<T>(T obj, string rootName) { var serializer = new XmlSerializer(typeof(T), new XmlRootAttribute(rootName)); using (var writer = new StringWriter()) { serializer.Serialize(writer, obj); return XDocument.Parse(writer.ToString()); } }
- 修改测试代码调用新方法:
static void Main(string[] args) { XNode xml = Helper.XmlSerializeDirect<MyObject>(new MyObject{ Amount = "100", OrderId = "123123123", Installment="1", Products = new List<Product> { new Product { ProductName = "Test", Price = "100" }, new Product { ProductName = "Test2", Price = "200" } } }, "auth"); Console.WriteLine(xml.ToString()); Console.ReadKey(); }
运行后即可生成符合预期的XML结构。
内容的提问来源于stack exchange,提问作者Fırat Kuas
相关产品推荐
相关产品推荐

