我正在尝试使用 XmlReader 处理大型 XML 文档,并使用 XmlSerializer 只反序列化其中的某些元素。以下是一些代码和一个小的模拟 XML 文档,展示了我如何尝试实现这一目标。
使用 XmlReader 的原因如下: 1. 我处理的是非常大的 XML 文档(10-250 MB),因此不想将其加载到内存中。因此,XmlDocument 不可行。 2. 我只想提取特定的元素。通常情况下,我可以忽略大部分其他内容。XmlReader 看起来为跳过无关内容提供了有效的方法。 3. 我事先不知道我能够处理的所有元素是否都存在;因此,我不使用一堆基于 XPath/XQuery 或 LINQ to XML 的查询,因为我只想在 XML 文件上进行一次遍历(由于它们的大小)。
代码的最后一行会抛出以下内部异常:
InvalidOperationException: "命名空间前缀ex未定义。"
显然,XmlSerializer无法识别xsi:type属性值中的ex命名空间前缀。
这只是我遇到的一个错误,但说实话,更大的问题是我不知道如何处理整个命名空间问题。我只是想方便地反序列化XML文档中的单个节点,但似乎必须手动注册/管理命名空间,并将其从XmlReader转发到XmlSerializer。
有人能演示如何从使用XmlReader读取的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
的示例。这里有一个可以作为起点。 - kennyzxXmlNamespaceManager
、XmlNameTable
和XmlParserContext
等内容,但是在我的情况下,我根本不知道它们应该如何配合使用。你能否为我演示一下它们的用法? - stakx - no longer contributing