C#将列表序列化为XML,并自动生成Sequence属性?

时间:2016-02-18 13:00:15

标签: c# xml

我必须从具有(Order)元素数组的对象生成(序列化)XML。 从XSD生成的订单类具有序列属性:

    [System.Xml.Serialization.XmlAttributeAttribute(DataType = "token")]
    public string Sequence;

我正在使用.Net XMLSerializer,但它不会为每个Order元素Sequence属性自动生成。

有:

 Order[] Orders = new Order[2] {...}

我必须得到:

<Order Sequence="1">..</Order>
<Order Sequence="2">..</Order>

只有一个,它应该呈现的单个元素:

    <Order Sequence="1">..</Order>

有谁知道如何使XMLSerialzier自动呈现此属性?或者我是否需要为每个Order元素手动设置Sequence?

干杯

3 个答案:

答案 0 :(得分:1)

AFAIK无法通过开箱即用的方法实现这一目标。这将为您提供以下选项:

IXmlSerializable的

在包含Orders数组的对象上实现IXmlSerializable。这样,您可以手动序列化订单或设置订单的序号,然后使用XmlSerializer.Serialize方法将对象序列化为├── bower@1.7.7 ├── cordova@6.0.0 ├── grunt-cli@0.1.13 ├── grunt-sass@1.1.0 ├── ionic@1.7.14 ├── ios-deploy@1.8.5 ├── ios-sim@5.0.6 ├── n@2.1.0 ├── to@0.2.9 └── update@0.4.2

XmlWriter

这生成了以下XML:

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
    }

    // ...
}

XmlSerializer在<?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> 元素上放置了一些名称空间声明,但这并没有伤害。我的示例类在Order类上有Name属性。

这种方法的缺点是你必须手动实现OrdersContainer类的序列化,包括反序列化。

Linq to XML

第二个选项是使用Linq to XML作为序列化部分。您还必须手动实现序列化,但您可以使用otb XmlSerializer进行反序列化(另一方面,您可能希望避免混合使用两个不同的框架)。您可以按如下方式序列化OrdersContainer类,并编写序列号:

Order

这创建了以下XML:

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

请注意,该示例使用Select方法的重载,该方法还接收项目的索引,以便可以根据数组中的位置创建序列号。

答案 1 :(得分:1)

如果order是你的类,你可以使用[XmlAttributeAttribute]

添加一个属性
class Order {
    [XmlAttribute()]
    public int Sequence { get; set; }

但是你应该在列表的所有项目中设置这个Sequence属性。

答案 2 :(得分:0)

这很好用 -

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; }
相关问题