【问题标题】:Retrieve first element value using XMLReader C#使用 XMLReader C# 检索第一个元素值
【发布时间】:2015-03-19 13:50:54
【问题描述】:

我目前正在开发一个应用程序来解析多个 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 所做的那样,我想继续这样做。

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

【问题讨论】:

  • 你可以很容易地使用 linq to xml:XDocument doc = XDocument.Load(string); XElement root = doc.Root; XElement wantedElement = root.Elements("title").First();
  • @CalebB OP 想知道如何使用 XmlReader,因此您将使用 XDocument.Load(reader) 而不是字符串。
  • @JNYRanger 你是对的,我只是在表达另一种选择。 :)
  • @CalebB 我支持你,我是 linq to xml 的忠实粉丝,不惜一切代价避免XmlDocument

标签: c# xml-parsing xmlreader


【解决方案1】:

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

这很容易做到(假设XmlReader 被命名为 reader):

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

唯一需要注意的是,您需要确保 XmlReader 当前处于初始状态,因为它只是正向读取,并且可能会产生意外结果,因为它会从阅读器的当前位置加载,假设它是在根节点。

此外,根据您发布的代码,您应该注意 MSDN 文档建议使用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 而不是==。切勿使用== 进行字符串比较。

【讨论】:

  • 感谢您的回复。 XmlReader doc = XmlReader.Create(sr, settings); while (doc.Read()) { if ((doc.NodeType == XmlNodeType.Element) && (doc.Name == "title")) { } 现在的问题是,如果我写,doc.ReadInnerXML(),它检索所有标题元素的所有文本,但我只需要第一个。这就是我被卡住的地方
  • 一次一步。首先处理阅读。在您拥有正确的节点之前,不要打扰任何写入。我的示例是向您展示如何在XmlDocument 中使用您的XmlReader,因为您说您已经熟悉了。此评论说明与您的原始帖子完全不同的问题。
  • 此外,当您第一次输入 if 语句的代码块时,您注释中示例中的循环应该立即中断,否则您将继续阅读文档并输入条件代码块。跨度>
  • 对不起。我很困惑。我现在更新了代码。我的要求是我需要添加一段代码来使用 XMLreader 代码本身检索第一次出现的标题标签。我不想将 XMLreader 加载到 XML 文档中。我想以这种方式继续做下去。
  • @ShahulHameed 现在看看。
猜你喜欢
  • 1970-01-01
  • 2016-12-05
  • 1970-01-01
  • 2019-03-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-01-10
相关资源
最近更新 更多