如何使用多个 XmlReader

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

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

public XmlTextReader(String xmlFragment, XmlNodeType fragType, XmlParserContext context);
            public XmlTextReader(Stream xmlFragment, XmlNodeType fragType, XmlParserContext context);
            
Overloads Public Sub New(ByVal xmlFragment as String, ByVal fragType as XmlNodeType,
            ByVal context as XmlParserContext)
            Overloads Public Sub New(ByVal xmlFragment as Stream, ByVal fragType as XmlNodeType,
            ByVal context as XmlParserContext)
            
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。

  XML 读取器和编写器----使用多个XmlReader
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();
            
'Create a new file stream for the specified source file.
            Dim filestreamSource as FileStream  = new FileStream(args, FileMode.Open, FileAccess.Read)
            'Create a new reader with the file stream
            Dim reader as XmlTextReader  = new XmlTextReader(filestreamSource)
            'Read the first part of the XML document
            while(reader.Read())
            'Display the elements and stop reading on the part1 end element tag
            'then go to ReadPart2 to start another reader to read the rest of the file.
            Select (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)
            case XmlNodeType.EndElement
            'Stop reading at end element for element with localname equal to part1
            if ("part1" = reader.LocalName) then
            Console.WriteLine("End reading part 1...")
            Console.WriteLine()
            goto ReadPart2
            end if
            end Select
            end while
            'Read the rest of the XML document
            ReadPart2:
            Console.WriteLine("Begin reading part 2...")
            'Create an XmlNamespaceManager and add the namespaces for the document.
            Dim nsmanager as XmlNamespaceManager  = 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")
            Dim pc as XmlParserContext  = new XmlParserContext(reader.NameTable, nsmanager, reader.XmlLang, XmlSpace.Default)
            Dim reader2 as XmlTextReader = new XmlTextReader(filestreamSource, XmlNodeType.Element, pc)
            while(reader2.Read())
            Select (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)
            case XmlNodeType.EndElement
            'Stop reading at end element for element with localname equal to part2
            if ("part2" = reader2.LocalName) then
            Console.WriteLine("End reading part 2...")
            goto Done
            end if
            end Select
            end while
            Done:
            Console.WriteLine("Done.")
            reader.Close()
            
C# VB  

摘要

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

相关文章:

  • 2021-10-18
  • 2021-12-26
  • 2022-02-18
  • 2021-12-26
  • 2022-12-23
  • 2021-10-31
  • 2021-11-15
猜你喜欢
  • 2022-12-23
  • 2021-06-01
  • 2021-06-22
  • 2021-12-20
  • 2021-09-12
  • 2021-12-12
相关资源
相似解决方案