【发布时间】:2015-01-27 23:40:38
【问题描述】:
我正在尝试一次性处理一个大型 XML 文档(使用 XmlReader),并使用 XmlSerializer 仅反序列化其中的某些元素。
下面是一些代码和一个小的模拟 XML 文档,展示了我是如何尝试这样做的。
使用
XmlReader的理由: 1. 我正在处理非常大的 XML 文档(10-250 MB),因此我这样做不想加载到内存中。所以XmlDocument是不可能的。 2. 我只想提取某些元素。通常我将能够忽略大多数其他内容。XmlReader似乎给了我一种跳过不相关内容的有效方法。 3. 我事先不知道我可以处理的任何和所有元素是否会出现;因此我没有使用一堆Xpath/XQuery或基于 LINQ to XML 的查询,因为我只想对 XML 文件进行一次传递(由于它们的大小)。
public class ElementOfInterest { }
…
var xml = @"<?xml version='1.0' encoding='utf-8' ?>
<Root xmlns:ex='urn:stakx:example'
xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'>
<ElementOfInterest xsi:type='ex:ElementOfInterest' />
</Root>";
var reader = System.Xml.XmlReader.Create(new System.IO.StringReader(xml));
reader.ReadToFollowing("ElementOfInterest");
var serializer = new System.Xml.Serialization.XmlSerializer(typeof(ElementOfInterest));
serializer.Deserialize(reader.ReadSubtree());
最后一行代码抛出如下内部异常:
InvalidOperationException: "命名空间前缀ex未定义。"
显然,XmlSerializer 无法识别 xsi:type 属性值中的 ex 命名空间前缀。
这只是我遇到的一个错误,但坦率地说,更大的问题是我不知道如何解决整个命名空间问题。我只是在寻找一种方便的方法来反序列化 XML 文档中的单个节点,但这似乎需要手动注册/管理命名空间,并以某种方式将它们从 XmlReader 转发到 XmlSerializer .
有人可以通过指出我的代码中的错误或通过显示替代方法来演示如何从使用XmlReader 读取的 XML 文档中反序列化单个节点吗?
【问题讨论】:
-
在
XmlNamespaceManager上查找示例。从one 开始。 -
@kennyzx:我看过
XmlNamespaceManager、XmlNameTable、XmlParserContext,等等。我根本不知道它应该如何在我的场景中组合在一起。你能帮我演示一下它的用途吗?
标签: c# xml xml-namespaces xmlreader xmlserializer