繁体   English   中英

反序列化大型XML文档中的单个元素:由于名称空间问题,xmlSerializer.Deserialize(xmlReader.ReadSubtree())失败

[英]Deserializing a single element in a large XML document: xmlSerializer.Deserialize(xmlReader.ReadSubtree()) fails due to namespace issues

我试图在一次传递中处理一个大型XML文档(使用XmlReader ),并使用XmlSerializer仅反序列化其中的某些元素。

下面是一些代码和一个微小的模拟XML文档,显示了我是如何尝试这样做的。

使用XmlReader原理: 1。我正在处理非常大的XML文档(10-250 MB),因此我不想加载到内存中。 所以XmlDocumentXmlDocument的。 2.我想只提取某些元素。 通常,我将能够忽略大多数其他内容。 XmlReader似乎为我提供了一种跳过不相关内容的有效方法。 3.我不提前知道是否有任何我能应付将出现的所有元素; 因此,我没有使用一堆Xpath / XQuery或LINQ到基于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文档反序列化单个节点,或者通过指出代码中的错误,或者通过显示替代方法?

以下作品:

using System.IO;
using System.Xml;
using System.Xml.Serialization;

static void Main()
{
    var xml = @"<?xml version='1.0' encoding='utf-8' ?>
                <Root
                  xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
                  xmlns:ex='urn:stakx:example'
                >
                  <ex:ElementOfInterest xsi:type='ex:ElementOfInterest' />
                </Root>";

    var nt = new NameTable();
    var mgr = new XmlNamespaceManager(nt);
    mgr.AddNamespace("ex", "urn:stakx:example");
    var ctxt = new XmlParserContext(nt, mgr, "", XmlSpace.Default);
    var reader = XmlReader.Create(new StringReader(xml), null, ctxt);
    var serializer = new XmlSerializer(typeof(ElementOfInterest));

    reader.ReadToFollowing("ElementOfInterest", "urn:stakx:example");
    var eoi = (ElementOfInterest)serializer.Deserialize(reader.ReadSubtree());
}

[XmlRoot(Namespace = "urn:stakx:example")]
public class ElementOfInterest { }

请注意输入中的命名空间: <ex:ElementOfInterest>

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM