Я использую метод ReadXml() для IXmlSerializable, и я полагаю, что использование XPath, вероятно, самый приятный способ сделать это.
Однако ReadXml() должен правильно обрабатывать позицию читателя.
Итак, учитывая, что мой WriteXml() создает что-то вроде этого:
<ObjectName>
<SubNode>2</SubNode>
<SubNode>2</SubNode>
</ObjectName>
Есть ли лучший способ, чем (этот ужасный способ) ниже, чтобы обеспечить правильное позиционирование Reader?
public override void ReadXml(System.Xml.XmlReader reader)
{
reader.Read(); /* Read Opening tag */
/* Using reader.ReadStartElement("ObjectName") reads forward a node,
i.e. current node becomes the first <SubNode>
whereas Read() doesn't even when the documentation says they both do
*/
XPathNavigator n = MakeXPathNavigator(reader.ReadSubtree());
XPathNodeIterator nodes = n.Select(".//SubNode");
while (nodes.MoveNext())
{
/* Do stuff with nodes */
_values.Add(nodes.Current.ValueAsInt);
}
reader.Skip(); /* Skip reader forward */
}
public static XPathNavigator MakeXPathNavigator(XmlReader reader)
{
try
{
return new XPathDocument(reader).CreateNavigator();
}
catch(XmlException e)
{
throw e; /* Maybe hide/deal with exception */
}
}
Я подозреваю, что вы можете столкнуться с некоторыми проблемами производительности при регулярном использовании этого подхода. Поскольку ваш xml относительно прост, я сильно подозреваю, что вам лучше просто использовать XmlReader
напрямую...
... но делать это непросто; IMO, лучше попытаться избежать необходимости реализации IXmlSerializable
(juts с использованием обычных свойств коллекции и т.д.) - это общая причина ошибок и разочарований.