XML 读取器和编写器使用多个XmlReader

如何使用多个 XmlReader

某些情况下,您可能使用一个读取器读取 XML 文档的一部分,使用一个或更多其他读取器读取该文档的其余部分。例如,一个电子商务订购系统可能有作为 XML 文档提交的订单。在处理这些订单时,一个读取器可处理文件开头部分的信息,然后将该文档的其余部分传送到另一个读取器,以处理剩余的订单细节。

为使读取器能够接受从其他读取器传来的文档,要使用两个 XmlTextReader 构造函数中的一个。一个构造函数获取字符串,另一个获取流。传递到该构造函数的字符串或流可以包含 XML 文档片段。这样,您就可以使一个读取器将已读取了部分信息的 XML 文档传递给另一个读取器。下列代码显示使用字符串或流的 XmlTextReader 构造函数的语法。

public XmlTextReader(String xmlFragment, XmlNodeType fragType, XmlParserContext context);
            public XmlTextReader(Stream xmlFragment, XmlNodeType fragType, XmlParserContext context);
            
C# VB  

XmlParserContext 对象为 XmlTextReader 提供适当的文档类型定义 (DTD)、外部资源的基本 URI、xml:lang、xml:space 以及命名空间信息。XmlParserContext 构造函数使用 8 个参数。如果第二个 XmlTextReader 仅要求命名空间/前缀查找,则可以指定 XmlNamespaceManager 和 XmlNameTable 参数并将空值传递给其他参数。

传递给构造函数的 XmlNamespaceManager 指定用于查找命名空间信息的命名空间管理器。例如,某文档片段可能包含在该文档前面部分定义的前缀。XmlNamespaceManager 使 XmlTextReader 可以正确解析文档中的任何前缀。当创建由 XmlTextReader 使用的 XmlNamespaceManager 时,必须使用 AddNamespace 方法将每个前缀和命名空间添加到集合中,XmlTextReader 将它们读到 XmlNamespaceManager 中。默认命名空间(如果存在)具有前缀 String.Empty。如果 XML 文档包含在 XmlNamespaceManager 中没有任何项的前缀,则 XmlTextReader 将引发 XmlException。

以编程方式从 XmlReader(及其派生类)中的节点检索前缀和命名空间时,只考虑读到 XML 文档中读取器的当前位置的节点。如果要将已读取了部分信息的流/字符串传递给另一个 XmlReader(使用 XmlParserContext),则不能考虑在流/字符串未读部分中定义的命名空间。较好的方法是在您预先知道命名空间的情况下使用 XmlNamespaceManager。

 
VB MultipleXmlReader.aspx

[运行示例] | [查看源代码]

下列示例代码使用两个 XmlTextReader 读取 XML 文档并显示元素信息。第一个读取器读取该文档的第一部分,第二个读取器读取文档的剩余部分。此代码首先创建 XmlNamespaceManager,然后将在 XML 文档中使用的前缀和命名空间(包括默认命名空间)添加到 XmlNamespaceManager。接着,用于构造第二个 XmlTextReader 的 XmlParserContext 将此 XmlNamespaceManager 用作命名空间管理器,以用于查找命名空间信息。

//Create a new file stream for the specified source file.
            FileStream filestreamSource = new FileStream(args, FileMode.Open, FileAccess.Read);
            //Create a new reader with the file stream
            XmlTextReader reader = new XmlTextReader(filestreamSource);
            //Read the first part of the XML document
            while(reader.Read())
            {
            //Display the elements and stop reading on the part1 endelement tag
            //then go to ReadPart2 to start another reader to read the rest of the file.
            switch(reader.NodeType)
            {
            case XmlNodeType.Element:
            Console.WriteLine("Name: {0}", reader.Name);
            Console.WriteLine("  Prefix: {0}", reader.Prefix);
            Console.WriteLine("  LocalName: {0}", reader.LocalName);
            Console.WriteLine("  Namespace: {0}", reader.NamespaceURI);
            break;
            case XmlNodeType.EndElement:
            //Stop reading at end element for element with localname equal to part1
            if ("part1"==reader.LocalName)
            {
            Console.WriteLine("End reading part 1...");
            Console.WriteLine();
            goto ReadPart2;
            }
            break;
            }
            }
            //Read the rest of the XML document
            ReadPart2:
            Console.WriteLine("Begin reading part 2...");
            //Create an XmlNamespaceManager and add the namespaces for the document.
            XmlNamespaceManager nsmanager = new XmlNamespaceManager(reader.NameTable);
            //Set default namespace--first param is null.
            nsmanager.AddNamespace(String.Empty, "http://tempuri.org/mydefaultnamespace");
            nsmanager.AddNamespace("myns", "http://tempuri.org/mynamespace");
            nsmanager.AddNamespace("yourns", "http://tempuri.org/yournamespace");
            XmlParserContext pc = new XmlParserContext(reader.NameTable, nsmanager, reader.XmlLang, XmlSpace.Default);
            XmlTextReader reader2 = new XmlTextReader(filestreamSource, XmlNodeType.Element, pc);
            while(reader2.Read())
            {
            switch (reader2.NodeType)
            {
            case XmlNodeType.Element:
            Console.WriteLine("Element Name: {0}", reader2.Name);
            Console.WriteLine("  Prefix: {0}", reader2.Prefix);
            Console.WriteLine("  LocalName: {0}", reader2.LocalName);
            Console.WriteLine("  Namespace: {0}", reader2.NamespaceURI);
            break;
            case XmlNodeType.EndElement:
            //Stop reading at end element for element with localname equal to part2
            if ("part2"==reader2.LocalName)
            {
            Console.WriteLine("End reading part 2...");
            goto Done;
            }
            break;
            }
            }
            Done:
            Console.WriteLine("Done.");
            reader.Close();
            
C# VB  

摘要

  1. XmlTextReader 类派生自 XmlReader,可使用包含 XML 文档片段(如已由另一个 XmlReader 读取了部分信息的字符串或流)的字符串或流构造。
  2. XmlParserContext 类提供启动 XML 分析器所需的所有上下文信息,以在 XML 文档内的任何随机点启动它。这使 XmlTextReader 得以读取 XML 片段。
原文地址:https://www.cnblogs.com/chorrysky/p/584478.html