使用XMLReader C#检索第一个元素值

时间:2015-03-19 13:50:54

标签: c# xml-parsing xmlreader

我目前正在开发一个解析多个XML文件的应用程序。我使用了XmlDocumentXmlReader。这是其中一个部分。

 private void button5_Click(object sender, EventArgs e)
        {
            var filenames = System.IO.Directory
                       .EnumerateFiles(textBox1.Text, "*.xml", SearchOption.AllDirectories)
                       .Select(System.IO.Path.GetFullPath);

        foreach (var f in filenames)
        {
            var sr = new MyStreamReader(f);
            var resolver = new XmlUrlOverrideResolver();
            resolver.DtdFileMap[@"XSEIF_R6.DTD"] = @"\\loc\XSEIF_R6.DTD";
            resolver.DtdFileMap[@"XSEIF_R5.DTD"] = @"\\loc\XSEIF_R5.DTD";
            resolver.DtdFileMap[@"XSEIF R5.DTD"] = @"\\loc\XSEIF_R5.DTD";

            XmlReaderSettings settings = new XmlReaderSettings();
            settings.DtdProcessing = DtdProcessing.Parse;
            settings.XmlResolver = resolver;
            XmlReader doc = XmlReader.Create(sr, settings);

            while (doc.Read())
            {
                if ((doc.NodeType == XmlNodeType.Element) && (doc.Name == "var"))
                {
                    if (newdoc.HasAttributes)
                    {
                        String vname = newdoc.GetAttribute("name");
                        String vno = newdoc.GetAttribute("number");
                        String pname = newdoc.GetAttribute("p-names");

                        File.AppendAllText(@"loca\Var.txt", vname + pname + Environment.NewLine);
                    }
                }
            }
        } 
        MessageBox.Show("Done");
    }

代码没有问题。现在我想添加另一个输出。我需要添加名为" title"的另一个标签的值。标签有多次出现。但我只需要第一次出现。我知道如何在XmlDocument中执行此操作,但正如我之前使用XmlReader所做的那样,我想继续这样做。

如何获取第一个标题标签的值?

1 个答案:

答案 0 :(得分:1)

由于您熟悉XmlDocument,因此您应该使用XmlReaderloadXmlDocument

这可以很容易地完成(假设XmlReader被命名为读者):

XmlDocument doc = new XmlDocument;
doc.Load(reader);
//perform queries

唯一的问题是你需要确保XmlReader当前处于初始状态,因为它只是正向读取并且会产生意外的结果,因为它将从读取器的当前位置加载它位于根节点。

同样根据您发布的代码,您应该注意,MSDN文档建议 NOT 使用GetElementsByTagName()方法。相反,您应该使用SelectNodes()SelectSingleNode()分别使用XPath表达式返回XmlNodeList或单XmlNode

修改 OP修改了他的问题&改变了发布的代码,因为它还不完全清楚。以下是使用XmlReader的问题的当前迭代的答案:

您需要了解,与C#中的其他XML解析不同,XmlReader仅为正向读取。因此,您不能只将代码添加到循环的末尾,因为您需要再次重新读取整个文档,这将是一种浪费。我建议使用一个标志和一个额外的else if语句来执行此操作,以便您可以在单次读取时处理所有这些。这是一个例子:

bool notFound = true;
while (doc.Read())
{
    if ((doc.NodeType == XmlNodeType.Element) && (doc.Name.Equals("var")))
    {
        if (newdoc.HasAttributes)
        {
            String vname = newdoc.GetAttribute("name");
            String vno = newdoc.GetAttribute("number");
            String pname = newdoc.GetAttribute("p-names");

            //File.AppendAllText(@"loca\Var.txt", vname + pname + Environment.NewLine);
        }
    }
    else if(notFound && doc.NodeType == XmlNodeType.Element && doc.Name.Equals("title"))
    {
         notFound = false;
         //do whatever you need to do here w/ this node
    }
}

通过上面的例子,一旦你拥有了所需的所有数据,你很可能需要将你的写入移动到正确的位置,这就是我评论它的原因。另请注意,我将字符串比较更改为使用Equals而不是==。切勿使用==进行字符串比较。