XmlReader
已正确定位,您可以检查
reader.NodeType == XmlNodeType.Element
和
reader.Name == EntityElementName
。然后,如果读卡器已正确定位,请不要使用
ReadToNextSibling()
.
-
而不是检查正确的
reader.Name
LocalName
和
NamespaceURI
reader.ReadToNextSibling(string localName,string namespaceURI)
bug to be avoided
-
而不是
ReadOuterXml()
呼叫
reader.ReadSubtree()
并将返回的读取器直接传递给
deserializer.Deserialize()
ReadSubtree()
允许
XmlSerializer
直接从传入的
综上所述,您可以引入以下低级扩展方法:
public static class XmlReaderExtensions
{
public static IEnumerable<TElement> DeserializeSequence<TElement>(this XmlReader reader, string localEntityElementName, string namespaceURI)
{
if (reader == null)
throw new ArgumentNullException();
var deserializer = new XmlSerializer(typeof(TElement));
while ((reader.NodeType == XmlNodeType.Element && reader.LocalName == localEntityElementName && reader.NamespaceURI == namespaceURI)
|| reader.ReadToNextSibling(localEntityElementName, namespaceURI))
{
// Using ReadSubtree instead of ReadOuterXml() avoids having do parse, reformat, then parse the formatted XML a second time
// by reading directly from the current stream only once.
TElement element;
using (var subReader = reader.ReadSubtree())
{
element = (TElement)deserializer.Deserialize(subReader);
}
// Consume the EndElement also (or move past the current element if reader.IsEmptyElement).
reader.Read();
yield return element;
}
}
}
Deserialize()
方法如下:
private Task<List<TAxEntity>> Deserialize(XmlReader reader)
{
var entities = reader.DeserializeSequence<TAxEntity>(EntityElementName, "" /* Pass the correct namespace here */).ToList();
return Task.FromResult(entities);
}
.Net fiddle
.
请注意,任何手册
代码应该使用缩进和未缩进的XML进行单元测试,因为在解析缩进的XML时,涉及跳过节点的错误有时会被掩盖(因为会跳过空白节点)