C# 将列表序列化为 XML,并自动生成序列属性
本文关键字:自动生成 属性 XML 列表 序列化 | 更新日期: 2023-09-27 18:35:08
我必须从具有(Order)元素数组的对象生成(序列化为)XML。从 XSD 生成的订单类具有序列属性:
[System.Xml.Serialization.XmlAttributeAttribute(DataType = "token")]
public string Sequence;
我使用的是.Net XMLSerializer,但它不会为每个订单元素序列属性自动生成。
具有:
Order[] Orders = new Order[2] {...}
我必须得到:
<Order Sequence="1">..</Order>
<Order Sequence="2">..</Order>
对于一个单一的元素,它应该呈现:
<Order Sequence="1">..</Order>
有谁知道如何使XMLSerialzier自动呈现此属性?还是我需要为每个订单元素手动设置序列?
干杯
AFAIK 没有办法用开箱即用的方法实现这一点。这为您提供了以下选项:
IXml可序列化
在包含订单数组的对象上实现 IXmlSerializable。这样,您可以手动序列化订单,也可以在使用 XmlSerializer 将对象序列化到XmlWriter
之前设置订单的序列号。序列化方法:
public class OrdersContainer : IXmlSerializable
{
public Order[] Orders;
public void WriteXml(XmlWriter writer)
{
// Serialize other properties
writer.WriteStartElement("Orders");
var ser = new XmlSerializer(typeof(Order));
for(var i = 0; i < Orders.Length; i++)
{
Orders[i].Sequence = (i + 1).ToString();
ser.Serialize(writer, Orders[i]);
}
writer.WriteEndElement(); // Orders
}
// ...
}
这将生成以下 XML:
<?xml version="1.0" encoding="utf-16"?>
<OrdersContainer>
<Orders>
<Order xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" Sequence="1">
<Name>Order 1</Name>
</Order>
<Order xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" Sequence="2">
<Name>Order 2</Name>
</Order>
</Orders>
</OrdersContainer>
XmlSerializer 将一些命名空间声明放在 Order
元素上,但这并没有什么坏处。我的示例类在Order
类上具有Name
属性。
此方法的缺点是必须手动实现 OrdersContainer 类的序列化,包括反序列化。
Linq to XML
第二个选项是将 Linq to XML 用于序列化部分。您还必须手动实现序列化,但您可以使用 otb XmlSerializer 进行反序列化(另一方面,您可能希望避免混合使用两个不同的框架)。您可以按如下方式序列化 OrdersContainer 类,也可以写入序列号:
var doc = new XDocument(new XElement("OrdersContainer",
new XElement("Orders",
cont.Orders.Select((x, i) => new XElement("Order",
new XAttribute("Sequence", (i + 1).ToString()),
new XElement("Name", x.Name))))));
doc.Save(writer);
这将创建以下 XML:
<?xml version="1.0" encoding="utf-16"?>
<OrdersContainer>
<Orders>
<Order Sequence="1">
<Name>Order 1</Name>
</Order>
<Order Sequence="2">
<Name>Order 2</Name>
</Order>
</Orders>
</OrdersContainer>
请注意,该示例使用 Select 方法的重载,该方法还接收项的索引,以便可以根据数组中的位置创建序列号。
如果 order 是你的类,你可以添加一个属性 [XmlAttributeAttribute]
class Order {
[XmlAttribute()]
public int Sequence { get; set; }
但是,您应该在列表的所有项中设置此 Sequence 属性。
这工作正常 -
var o = new XmlSerializerNamespaces();
o.Add("", "");
var ser = new XmlSerializer(typeof(List<Order>), "");
using (var sw = new StringWriter())
{
ser.Serialize(sw, new List<Order> {
new Order { sequence = "1", MyProperty = 1 },
new Order { sequence = "2", MyProperty = 2 } },
o);
var t = sw.ToString();
}
AND
[XmlAttribute(AttributeName = "sequence", DataType = "string")]
public string sequence { get; set; }