С# Xml Сериализующий список <T> потомок с атрибутом Xml
Утренние парни,
У меня есть коллекция, которая спускается из списка и имеет общедоступное свойство. Серийный анализатор Xml не подбирает мою программу. Элементы списка упорядочиваются в порядке. Я пробовал атрибут XmlAttribute безрезультатно. Ребята, у вас есть решение?
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void button1_Click(object sender, RoutedEventArgs e)
{
var people = new PersonCollection
{
new Person { FirstName="Sue", Age=17 },
new Person { FirstName="Joe", Age=21 }
};
people.FavoritePerson = "Sue";
var x = new XmlSerializer(people.GetType());
var b = new StringBuilder();
var w = XmlTextWriter.Create(b, new XmlWriterSettings { NewLineChars = "\r\n", Indent = true });
x.Serialize(w, people);
var s = b.ToString();
}
}
[XmlRoot(ElementName="People")]
public class PersonCollection : List<Person>
{
//DOES NOT WORK! ARGHHH
[XmlAttribute]
public string FavoritePerson { get; set; }
}
public class Person
{
[XmlAttribute]
public string FirstName { get; set; }
[XmlAttribute]
public int Age { get; set; }
}
Я получаю следующий xml
<?xml version="1.0" encoding="utf-16"?>
<People xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Person FirstName="Sue" Age="17" />
<Person FirstName="Joe" Age="21" />
</People>
Я хотел бы получить это
<?xml version="1.0" encoding="utf-16"?>
<People FavoritePerson="Sue" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Person FirstName="Sue" Age="17" />
<Person FirstName="Joe" Age="21" />
</People>
Ответы
Ответ 1
Я пошел дальше и решил проблему, выполнив IXmlSerializable. Если существует более простое решение, отправьте его!
[XmlRoot(ElementName="People")]
public class PersonCollection : List<Person>, IXmlSerializable
{
//IT WORKS NOW!!! Too bad we have to implement IXmlSerializable
[XmlAttribute]
public string FavoritePerson { get; set; }
public System.Xml.Schema.XmlSchema GetSchema()
{
return null;
}
public void ReadXml(XmlReader reader)
{
FavoritePerson = reader[0];
while (reader.Read())
{
if (reader.Name == "Person")
{
var p = new Person();
p.FirstName = reader[0];
p.Age = int.Parse( reader[1] );
Add(p);
}
}
}
public void WriteXml(XmlWriter writer)
{
writer.WriteAttributeString("FavoritePerson", FavoritePerson);
foreach (var p in this)
{
writer.WriteStartElement("Person");
writer.WriteAttributeString("FirstName", p.FirstName);
writer.WriteAttributeString("Age", p.Age.ToString());
writer.WriteEndElement();
}
}
}
Ответ 2
Это не ответ на вопрос, но я думал, что сделаю предложение облегчить разработку кода.
Добавить новый Add
метод в класс PersonCollection
как таковой:
public class PersonCollection : List<Person>, IXmlSerializable
{
...
public void Add(string firstName, int age)
{
this.Add(new Person(firstName, age));
}
...
}
Затем, сделав это, вы можете упростить синтаксис инициализатора коллекции:
var people = new PersonCollection
{
{ "Sue", 17 },
{ "Joe", 21 }
};
people.FavoritePerson = "Sue";
Ответ 3
Если вы не против обернуть все функции списка, тогда вы можете вставлять этот список как свойство класса, а не извлекать его из него.
Затем вы использовали атрибут XmlElement, чтобы заставить элементы xml быть выписаны как плоский список (а не быть вложенным).