XmlArray Serialization - How can I make the serializer ignore the class name of items in a list?

一曲冷凌霜 提交于 2019-12-24 12:22:48

问题


I have a class that, among other properties, has a list of MyObject.

public class MyClass
{
    ...

    [XmlArray("OBJECT")]
    public List<MyObject> Objects { get; set; }

    ...
}

Each MyObject has two properties, PropA and PropB.

public class MyObject
{
    public string PropA {get;set;}
    public string PropB {get;set;}
}

The XML Serializer returns this XML:

<OBJECT>
    <MyObject>
        <PropA>A1</PropA>
        <PropB>B1</PropB>
    </MyObject>
    <MyObject>
        <PropA>A2</PropA>
        <PropB>B2</PropB>
    </MyObject>
    <MyObject>
        <PropA>A3</PropA>
        <PropB>B3</PropB>
    </MyObject>
</OBJECT>

My given requirements are for it to look like this (I swear, it looks much less wrong given the real object names and property values, but regardless, this is my task):

<OBJECT>
    <PropA>A1</PropA>
    <PropB>B1</PropB>
    <PropA>A2</PropA>
    <PropB>B2</PropB>
    <PropA>A3</PropA>
    <PropB>B3</PropB>
</OBJECT>

What is the best way to make this happen? I tried messing around with various Xml attributes (e.g. XmlArrayItem, XmlElement), but I can't seem to get rid of the class name wrapper.

I have considered custom xml serialization, but I hate to throw away all the (working) default Xml serialization that happens on the other properties with only an XmlElement attribute on each of them.

Any thoughts?

Thank you.

EDIT: This is not a duplicate if you are referring to the link that xDaevax kindly posted. (XML Serialization - Disable rendering root element of array). This question/answer isn't asking/solving how to get rid of the item class names (the tags around each item in the list), it shows how to get rid of the overall list tag that encompasses the entire list of items. I want precisely the reverse. If there is another link to a similar, answered question, I would love to know. Thank you.


回答1:


If you have a collection of MyObject, you can do that easily using LINQ to XML:

var xDoc = new XDocument("OBJECT",
        myObjects
        .SelectMany(x => new[]
        {
            new XElement("PropA", x.PropA),
            new XElement("PropB", x.PropB)
        }));

xDoc.Save("path")



回答2:


So, I did something pretty hacky, but it works and I suppose that's all that matters. I changed PropA to be an int, since it was always a number, and used the following tags to set up the special property I wanted the XML serializer to use. I used some of Selman22's suggestion to make that easier. (Thank you!)

This solution will not work if your properties are all the same type, unfortunately, but it meets my needs at present and we do not foresee any potential for change (rare as that is).

[XmlIgnore]
public List<MyObject> Objects{ get; set; }

[XmlArray(ElementName = "OBJECT")]
[XmlArrayItem(Type = typeof(int), ElementName = "PROPA")]
[XmlArrayItem(Type = typeof(string), ElementName = "PROPB")]
public List<object> XmlObjects
{
    get
    {
        var xmlObjects = new List<object>();

        if (Objects != null)
        {
            xmlObjects.AddRange(Objects.SelectMany(x => new List<object>
            {
                x.PropA,
                x.PropB
            }));
        }

        return xmlObjects;
    }
    set { }
}


来源:https://stackoverflow.com/questions/23919151/xmlarray-serialization-how-can-i-make-the-serializer-ignore-the-class-name-of

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!