Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/335.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 解析XML时处理速记结束标记_C#_Xml_Xml Parsing - Fatal编程技术网

C# 解析XML时处理速记结束标记

C# 解析XML时处理速记结束标记,c#,xml,xml-parsing,C#,Xml,Xml Parsing,为了简单起见,我将大幅降低项目的复杂性,并给出一个简单但同样准确的例子,说明我正在努力解决的问题。我有两个XML文件,我们将它们称为Read.XML和Write.XML。目标是让我的项目读取read.xml的内容,将xml解析为一个类,然后将其重建为Write.xml XML生成为Read.XML的方式是,当一个元素没有值时,它使用速记结束标记(),当它确实有值时,它使用速记结束标记(元素值)。我无法控制Read.XML中XML的生成 下面的代码非常适合解析XML,只要它使用了长柄结束标记。但是

为了简单起见,我将大幅降低项目的复杂性,并给出一个简单但同样准确的例子,说明我正在努力解决的问题。我有两个XML文件,我们将它们称为
Read.XML
Write.XML
。目标是让我的项目读取read.xml的内容,将xml解析为一个类,然后将其重建为Write.xml

XML生成为Read.XML的方式是,当一个元素没有值时,它使用速记结束标记(
),当它确实有值时,它使用速记结束标记(
元素值
)。我无法控制Read.XML中XML的生成

下面的代码非常适合解析XML,只要它使用了长柄结束标记。但是,如果下面说的
ReportId
有一个速记结束标记,那么现在的代码将读取下一行(对于长记结束标记,它将是XML元素的值),但下一行是一个值为“\n”的空白元素。然后在Write.XML中为XML添加了一行新行,这使得XML格式很奇怪。下面是我用来从read.XML读取和解析XML的代码:

        while(xmlReader.Read())
        {
            switch(xmlReader.NodeType)
            {
                case XmlNodeType.Element:
                    if(xmlReader.Name.Equals("ReportSummary") && xmlReader.IsStartElement())
                    {
                        currentReport = new Entities.Report();
                    }
                    else if(xmlReader.Name.Equals("ReportName"))
                    {
                        xmlReader.Read();
                        currentReport.ReportName = xmlReader.Value;
                    }
                    else if(xmlReader.Name.Equals("ReportId"))
                    {
                        xmlReader.Read();
                        currentReport.ReportId = xmlReader.Value;
                    }
                    break;
                case XmlNodeType.EndElement: //Reached the end of the element.
                    if(xmlReader.Name.Equals("ReportSummary"))
                    {
                        if(currentReport!= null)
                        {
                            reportList.Add(currentReport);
                            currentReport = null;
                        }
                    }
                    break;
                default:
                    break;
            }
        }
我的问题是,是否有一种正确的方法来处理速记结束标记和长记结束标记。或者,有没有更好的方法一起解析XML文件


提前感谢您提供的任何帮助。

我将使用XmlDocument的SelectSingleNode函数,它将更有效地解析文件

如果有多个节点,可以使用SelectNodes功能


正如spender指出的,您还可以使用XDocument/XElement解析它。如果您至少在使用framework 3.5,那么这种方法可能更可取。您可以使用
XmlReader。IsEmptyElement
来确定读取器是否位于空元素:

如果可能,您可以使用LINQ to XML

我想这会让你的生活更简单

希望它能帮助…


如果你倾向于选择一种性能稍差但管理能力更强的方式, 我建议一个类似于以下内容的解决方案:

    XmlDocument xmlDoc = new XmlDocument();
    List<Entities.Report> reports = new List<Entities.Report>();
    xmlDoc.Load("Read.xml");
    foreach (XmlNode reportNode in xmlDoc.SelectNodes("//ReportSummary"))
    {
        Entities.Report report = new Entities.Report();
        report.ReportName = reportNode["ReportName"].InnerText;
        report.ReportId = reportNode["ReportId"].InnerText;
        reports.Add(report);
    }
XmlDocument xmlDoc=new XmlDocument();
列表报告=新列表();
Load(“Read.xml”);
foreach(xmlDoc.SelectNodes(“//ReportSummary”)中的XmlNode reportNode)
{
Entities.Report=新的Entities.Report();
report.ReportName=reportNode[“ReportName”].InnerText;
report.ReportId=reportNode[“ReportId”].InnerText;
报告。添加(报告);
}
可读性、可维护性更强,性能更低。

祝你好运

任何合适的XML解析器都应该能够顺利地处理自动关闭标记。我认为SAX没有任何问题。您的XML有多大?它是否值得使用阅读器,或者您可以使用更高级别的api进行解析?如果您处理的是巨大的Xml文档,我建议您阅读一下我使用的这项有趣的技术,它对数据库转储有很好的效果:关于为工作选择正确的api的注意事项:哪种方式更有效?现在解析XML的首选方法是使用Linq和XDocument/XElement。相比之下,XmlDocument似乎很笨拙。XDocument/XElement也不错,我将其与问题中所示的使用switch和if语句进行比较。感谢Wayne,这是一个足够简单的修复方法。谢谢大家的意见。当我有更多的时间来加强这一部分时,我将回到这里来获得一些想法。非常感谢。