Переименование элементов массива в плоском массиве xml с использованием XmlSerializer - PullRequest
2 голосов
/ 11 декабря 2010

У меня есть XML-файл в следующем формате:

<?xml version="1.0" encoding="UTF-8"?>
<Items>
    <Item Property1="A" Property2="B" />
    <Item Property1="C" Property2="D" />
</Items>

Мне нужно прочитать элементы <Item> как объекты класса MyClass, используя XmlSerializer.

public class MyCLass
{
    [XmlAttribute]
    public string Property1 { get; set; }

    [XmlAttribute]
    public string Property2 { get; set; }
}

В настоящее время у меня есть следующий код для чтения файла:

XmlSerializer serializer =
    new XmlSerializer(typeof(MyClass[]), new XmlRootAttribute(@"Items"));

MyClass[] list = (MyClass[])serializer.Deserialize(...);

Поскольку имя элемента <Item> отличается от имени класса MyCLass, элементы в массиве вообще не десериализованы. Приведенный выше код работает, если я переименую MyClass в Item, но, к сожалению, мне не разрешено изменять XML-файл или имена классов.

Как мне сопоставить их так, чтобы файл можно было правильно прочитать?

Заранее спасибо!

Ответы [ 2 ]

4 голосов
/ 12 декабря 2010

Используйте класс-оболочку, которая содержит массив, это позволит вам применить атрибут XmlElement:

public class MyClassList
{
    [XmlElement("Item")]
    public MyClass[] Items { get; set; }
}

var items = new[]
{
    new MyClass { Property1 = "A", Property2 = "B" },
    new MyClass { Property1 = "C", Property2 = "D" },
};
var list = new MyClassList { Items = items };

using (var writer = new StringWriter())
{
    var xs = new XmlSerializer(typeof(MyClassList), new XmlRootAttribute("Items"));
    xs.Serialize(writer, list);
    writer.ToString().Dump();
}
2 голосов
/ 11 декабря 2010

Лично я мог бы сериализовать и десериализовать вручную - я обнаружил, что проще получить любую гибкость, какую вы пожелаете, вместо того, чтобы тратить много времени на возня со встроенной сериализацией и жить с различными налагаемыми ею ограничениями. LINQ to XML делает это довольно просто. Например, в этом случае:

XDocument doc = XDocument.Load("test.xml");
// You could use an array if you really wanted, of course.
List<MyClass> list = doc.Root
                        .Elements("Item")
                        .Select(x => new MyClass {
                            Property1 = (string) x.Attribute("Property1"),
                            Property2 = (string) x.Attribute("Property2"),
                         })
                        .ToList();

По общему признанию, это станет волосатым, если вам нужно будет сериализовать объекты со сложными отношениями (два объекта, относящиеся к одному и тому же ребенку или что-то в этом роде), но в прошлом у меня был большой успех с этим.

...