1

我正在尝试使用 XmlTextReader 类读取 xml 文件,我的 xml 文件是

<?xml version='1.0' encoding='utf-8' standalone='yes'?>
<AppXmlLogWritter>
<LogData><LogID>999992013021213232800001</LogID><LogDateTime>20130212132328</LogDateTime><LogType>Message</LogType><LogFlag>Flag</LogFlag><LogApplication>Application</LogApplication><LogModule>Module</LogModule><LogLocation>Location</LogLocation><LogText>Text</LogText><LogStackTrace>Stacktrace</LogStackTrace></LogData>
</AppXmlLogWritter>

使用以下代码

FileStream fileStream = File.Open(txtBrowseFilePath.Text, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.ReadWrite);
             using (XmlTextReader objXmlReader = new XmlTextReader(fileStream))
{
                IEnumerable<LogData> data = LogData.GetLogData(objXmlReader);

                using(var item = data.GetEnumerator())
                {
                    while (item.MoveNext())
                    {
                        DataRow dataRow;
                        dataRow = dataTable.NewRow();

                        dataRow[0] = item.Current.LogID;
                        dataRow[1] = item.Current.LogDateTime;
                        dataRow[2] = item.Current.LogType;
                        dataRow[3] = item.Current.LogFlag;
                        dataRow[4] = item.Current.LogApplication;
                        dataRow[5] = item.Current.LogModule;
                        dataRow[6] = item.Current.LogLocation;
                        dataRow[7] = item.Current.LogText;
                        dataRow[8] = item.Current.LogStackTrace;

                        dataTable.Rows.Add(dataRow);
                    }
                }}
public static IEnumerable<LogData> GetLogData(XmlTextReader objXmlReader)
        {
            LogData objLogData = null;
            IXmlLineInfo xmlInfo = (IXmlLineInfo)objXmlReader;
            while(objXmlReader.Read())
            {


                if(objXmlReader.IsStartElement("LogData"))
                {
                    objLogData = new LogData();
                }
                if(objXmlReader.Name == "LogData" && objXmlReader.NodeType == XmlNodeType.EndElement)
                {
                    yield return objLogData;
                }
                if(objXmlReader.Name == "LogID")
                {
                    objLogData.LogID = objXmlReader.ReadElementContentAsString();
                }
                else if (objXmlReader.Name == "LogDateTime")
                {          
                    objLogData.LogDateTime = objXmlReader.ReadElementContentAsString();                   
                }
                else if(objXmlReader.Name == "LogType")
                {
                    objLogData.LogType = objXmlReader.ReadElementContentAsString();
                }
                else if(objXmlReader.Name == "LogFlag")
                {
                    objLogData.LogFlag = objXmlReader.ReadElementContentAsString();
                }
                else if(objXmlReader.Name == "LogApplication")
                {
                    objLogData.LogApplication = objXmlReader.ReadElementContentAsString();
                }
                else if(objXmlReader.Name == "LogModule")
                {
                    objLogData.LogModule = objXmlReader.ReadElementContentAsString();
                }
                else if(objXmlReader.Name == "LogLocation")
                {
                    objLogData.LogLocation = objXmlReader.ReadElementContentAsString();
                }
                else if(objXmlReader.Name == "LogText")
                {
                    objLogData.LogText = objXmlReader.ReadElementContentAsString();
                }
                else if(objXmlReader.Name == "LogStackTrace")
                {
                    objLogData.LogStackTrace = objXmlReader.ReadElementContentAsString();
                }
            }
        }

但它给了我一个错误“节点类型 EndElement 不支持 ReadElementContentAsString 方法” 但是当我的 xml 文件为

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<AppXmlLogWritter>
<LogData>
<LogID>999992013021110381000001</LogID>
<LogDateTime>20130211103810</LogDateTime>
<LogType>Message</LogType>
<LogFlag>Flag</LogFlag>
<LogApplication>Application</LogApplication>
<LogModule>Module</LogModule>
<LogLocation>Location</LogLocation>
<LogText>Text</LogText>
<LogStackTrace>Stacktrace</LogStackTrace>
</LogData>
</AppXmlLogWritter>

它工作正常,但我还没有得到关于 xml 文件的实际问题,为什么它在我提到时给我一个错误。此行发生错误

 objLogData.LogDateTime = objXmlReader.ReadElementContentAsString();  

谢谢你的回复

4

2 回答 2

2

Well, the main cause of the problem is that you're using ReadElementContentAsString which moves the "cursor" to after the element you're reading - but you're then calling Read() again.

So when the XML data is like this:

<first>Foo</first><second>Bar</second>

... if you're positioned on the first element opening, then ReadElementContentAsString will move the reader onto the start of the second element. You then call Read() which moves into the text node ("Bar"). When you then call ReadElementContentAsString a second time, that will fail - because you're not on an element start node. However, I'd expect to get an exception of:

Unhandled Exception: System.InvalidOperationException:
The ReadElementContentAsString method is not supported on node type Text.

... whereas you've got a node type of EndElement, for some reason.

You should dig into exactly why that's happening (did you call Read manually while debugging, for example?) but the underlying problem you need to fix is calling Read() when you don't need to.

于 2013-02-12T14:07:04.053 回答
0

您正在使用IXmlLineInfo并来自msdn 页面

提供一个接口以使类能够返回行和位置信息。

这可能是导致此错误的原因。我猜使用yield return(因为它从未被调用)并使用item.MoveNext()结果不会返回任何内容,从而objXmlReader移动到导致异常的 xml 的最后一个元素。

请注意,这只是基于您提供的数据的猜测。

于 2013-02-12T13:46:20.113 回答