异步读取可能格式错误的Xml

时间:2010-08-06 12:32:55

标签: .net xml

这是星期五,我的思绪似乎已经转移到了周末思考。

鉴于此xml结构 -

<?xml version="1.0" encoding="utf-8"?>
<results requiredAttribute="somedatahere">
  <entry>
    <!-- Xml structure in here -->
  </entry>
  <entry>
    <!-- Xml structure in here -->
  </entry>
  <entry>
    <!-- Xml structure in here -->
  </entry>
</results>

此代码(缩减为核心代码)使用xmlreader读取数据并异步返回数据 -

            response = (HttpWebResponse)request.GetResponse();

            using (var reader = XmlReader.Create(response.GetResponseStream()))
            {
                Logger.Info("Collector: Before attempt to read data for {0}", url);

                while (reader.Read())
                {
                    if (reader.NodeType == XmlNodeType.Element && reader.Name == "entry")
                    {
                        var el = XElement.ReadFrom(reader) as XElement;
                        if (el != null)
                            yield return el;
                    }
                }
            }

从属性requiredAttribute?

中检索值的最简单方法是什么?

需要考虑的关键点是我在任何时候都不想读取完整的xml文件,因为文件可能非常大。此外,数据来自HttpStream,因此您无法始终保证数据完整,并且随后外部结果元素的格式正确。这似乎排除了读取结果元素然后遍历它的孩子。

2 个答案:

答案 0 :(得分:1)

坚持使用基于XmlReader的纯粹方法,直到遇到错误信息,它会为您提供已解析的内容。

任何其他方法(XPathDocumentXElementXmlDocument)都会尝试首先解析整个文档,因此您只会获得适用的异常。

答案 1 :(得分:0)

if (reader.NodeType == XmlNodeType.Element)
{
    if (reader.Name == "results")
    {
        if (reader.MoveToAttribute("requiredAttribute") && reader.ReadAttributeValue())
            yield return reader.Value;
    }
    if (reader.Name == "entry")
    {
        ...
    }
}

测试计划

using System;
using System.Collections.Generic;
using System.IO;
using System.Xml;

class Program
{
    static void Main(string[] args)
    {
        try
        {
            foreach (object value in Read())
                Console.WriteLine(value);
        }
        catch (XmlException ex)
        {
            Console.WriteLine(ex.Message);
        }
    }

    static IEnumerable<object> Read()
    {
        using (var file = File.OpenRead("Test.xml"))
        {
            var reader = XmlReader.Create(file, new XmlReaderSettings { IgnoreComments = true });
            while (reader.Read())
            {
                if (reader.NodeType == XmlNodeType.Element)
                {
                    yield return reader.Name;

                    if (reader.Name == "results")
                    {
                        if (reader.MoveToAttribute("requiredAttribute") && reader.ReadAttributeValue())
                            yield return reader.Value;
                    }
                }
            }
        }
    }
}
相关问题