Это возможно, если мы сами выполняем процесс десериализации (по крайней мере, для класса root)
. Напомню, что предоставленный вами контент XML недостаточен для запуска модульных тестов. , так что это очень базовая c реализация, которая, однако, должна работать на вас напрямую или просто немного подправить кое-где.
Прежде всего, мы изменим наш класс Item XML атрибут сериализации в root. В ближайшее время будет дан ответ «Почему».
[XmlRoot("item")]
public class Item
{
[XmlAttribute("type")]
public string Type { get; set; }
[XmlElement("prop1")]
public int Prop1 { get; set; }
}
Я также добавил простое целочисленное свойство, чтобы доказать, что десериализация работает, как и ожидалось.
Я также изменил содержимое XML для соответствия новому типу, для тестирования.
<root>
<item type="b">
<prop1>5</prop1>
</item>
<item type="a">
<prop1>5</prop1>
</item>
<item type="a">
<prop1>5</prop1>
</item>
<item type="b">
<prop1>5</prop1>
</item>
<item type="c">
<prop1>5</prop1>
</item>
</root>
А теперь появился класс Root, который прямо сейчас реализует IXmlSerializable:
[XmlRoot("root")]
public class Root : IXmlSerializable
{
[XmlElement("item")]
public Item[] Items { get; set; }
// These two methods are not implemented for you need to deserialize only,
// and because you haven't provided the schema for your XML content
System.Xml.Schema.XmlSchema IXmlSerializable.GetSchema() { throw new NotImplementedException(); }
void IXmlSerializable.WriteXml(System.Xml.XmlWriter writer) { throw new NotImplementedException(); }
void IXmlSerializable.ReadXml(System.Xml.XmlReader reader)
{
// The element is <root> when here for the first time.
// Maintain a list to keep items with type "a"
List<Item> typeAItems = new List<Item>();
// Create a serializer for the type Item
XmlSerializer deserializer = new XmlSerializer(typeof(Item));
while (reader.Read())
{
// The code is self explanatory.
// Skip() will help omitting unnecessary reads
// if we are not interested in the Item
if (reader.IsStartElement() && reader.Name == "item")
{
if (reader.GetAttribute("type") == "a")
{
// This works, and deserializes the current node
// into an Item object. When the deserialization
// is completed, the reader is at the beginning
// of the next <Item> element
typeAItems.Add((Item)deserializer.Deserialize(reader));
}
else
{
// skip element with all its children
reader.Skip();
}
}
else
{
// skip element with all its children
reader.Skip();
}
}
Items = typeAItems.ToArray();
}
}
Лог десериализации c сохранен то же самое, как новый XmlSerializer (typeof (Root)). Deserialize ().
Остальное .. для проверки.