【问题标题】:XmlReader failed to read all the nodesXmlReader 未能读取所有节点
【发布时间】:2015-05-21 04:46:07
【问题描述】:

我正在为我的一个需求编写自定义 XML 解析。该程序的目的是解析与主节点匹配的任何类型的 XML 文件。 我已经复制了如下问题。 ReadXml()、ParseData() 方法的主要目的是在找到匹配项时读取 XML 元素的数据,否则应该前进到下一个节点。 但是输入的 XML 有一个额外的节点 'title1' ,因为这个节点,解析程序在没有读取 'author' 节点的情况下就中断了。

   class Program
{
    static void Main()
    {
        StringBuilder output = new StringBuilder();

        String xmlString =
            @"<bookstore>
                    <book genre='autobiography' publicationdate='1981-03-22' ISBN='1-861003-11-0'>
                        <title>The Autobiography of Benjamin Franklin</title> 
                       <title1>The Autobiography of Benjamin Franklin</title1>                           
                        <author>                           
                            <first-name>Benjamin</first-name>
                            <last-name>Franklin</last-name>                          
                        </author>
                        <author2>
                            <first-name>Benjamin</first-name>
                            <last-name>Franklin</last-name>
                        </author2>
                        <price>8.99</price>
                    </book>
               </bookstore>";

        // Create an XmlReader
        using (XmlReader reader = XmlReader.Create(new StringReader(xmlString)))
        {
            ReadXml(reader);
        }
    }



    public static void ReadXml(System.Xml.XmlReader reader)
    {
        if (reader.MoveToContent() == XmlNodeType.Element &&
            reader.LocalName == "bookstore")
        {
            reader.Read();
            // Parse the file and display each of the nodes.
            do
            {
                switch (reader.NodeType)
                {
                    case XmlNodeType.Element:
                        ParseData(reader);
                        break;
                    case XmlNodeType.Text:
                    case XmlNodeType.CDATA:
                    case XmlNodeType.ProcessingInstruction:
                    case XmlNodeType.Comment:
                    case XmlNodeType.XmlDeclaration:
                    case XmlNodeType.Document:
                    case XmlNodeType.EntityReference:
                    case XmlNodeType.EndElement:
                        break;
                }

                if (reader.ReadState == ReadState.Interactive)
                    reader.Read();

            } while (!reader.EOF && reader.NodeType != XmlNodeType.EndElement);

        }
    }


    protected static bool ParseData(System.Xml.XmlReader reader)
    {
        string output = string.Empty;
        bool parsed = true;
        switch (reader.LocalName)
        {
            case "title":
                output = reader.ReadString();
                break;               
            case "author":
                XmlReader reagentListReader = reader.ReadSubtree();     // This case never reached              
                break;             
            default:
               // output = reader.ReadString(); //uncomment will work,But                             //not sure to read subtree or string.
                parsed = false;
                break;
        }
        return parsed;
    }
}

通过添加'输出 = reader.ReadString();'默认情况下:switch case 解决了我的问题,但我不知道它是读取子树还是字符串。

【问题讨论】:

  • 你这样解析有什么原因吗? “真实”文件是否非常大?
  • 是的,真实文件更大,可以增长到任意大小。真实文件可以由不同的用户更新并发送给客户。该软件应在任何特定情况下处理新的 XML。
  • 当您想忽略某些标签时,您应该阅读整个子树。
  • 另外,将 WhiteSpace 添加到您的忽略列表中。

标签: c# xml


【解决方案1】:

问题在于您的循环条件 - 当它到达 EndElement 时,您将退出。如果您单步执行,您可以验证这一点 - 当调用 reader.Read 时,您将忽略那些您忽略的元素。

只需将条件更改为:

while (!reader.EOF);

【讨论】:

  • 这是可行的,但文件的大小和程序的性能是一个问题。
  • 你能解释一下为什么 reader.Read() 没有移动到下一个节点而是迭代文本 endelement..
  • 这就是它的工作原理,它按顺序读取所有部分,例如元素、属性、内容(可能包括更多元素),然后是结束元素。
猜你喜欢
  • 1970-01-01
  • 2013-07-08
  • 1970-01-01
  • 1970-01-01
  • 2014-01-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多