有没有一种方法可以通过XPath查找XML文件的多个节点的元素?

时间:2020-03-03 08:52:59

标签: c# xml

我想通过XPath在XML文件中找到多个节点的元素。节点的路径为:

(/每章/块/过程/步骤/动作/表格/ tgroup / tbody /行/条目/ p /表单域)

我想从Childnode表单域中获取Element field_id。 XML文件中有多个表单域。全部具有相同的路径,但是位于不同的行(/行)中。

我尝试过:

XmlDocument doc = new XmlDocument();
doc.Load("xmlfile.xml");
XmlNode node = doc.DocumentElement.SelectSingleNode("/chapter/block/procedure/step/action/table/tgroup/tbody/row/entry/p/formfield");
string attr = node.Attributes["field_id"]?.InnerText;
Console.WriteLine(attr);

这仅给我第一个表单字段中的field_id。我已经尝试了多种其他方法来获取每个ID,但是我总是在获取System.NullReferenceException。如何获得每个field_id?

2 个答案:

答案 0 :(得分:1)

如果共享示例XML,这将很容易。但是,您可以使用XmlDocument

尝试以下代码示例
var xmldoc = new XmlDocument();
xmldoc.Load("xmlfile.xml");
var result = xmldoc.SelectNodes("chapter/block/procedure/step/action/table/tgroup/tbody/row/entry/p/formfield/@field_id");
foreach (XmlNode item in result)
{
    Console.WriteLine(item.Value);
}

还有一种使用XDocumentLINQ

的方法
var xdoc = XDocument.Load("xmlfile.xml");
var nodes = string.Join(", ", xdoc.Descendants("formfield")
                                  .Select(x => x.Attribute("field_id")));

根据评论添加了以下代码

下面是使用XElement

读取XML注释的代码
var xdoc = XElement.Load("xmlfile.xml");
var comments = xdoc.DescendantNodes().OfType<XComment>();

foreach (XComment comment in comments)
{
  //read comments here
}

答案 1 :(得分:1)

您可以使用xml linq并将结果放入字典中

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;

namespace ConsoleApplication159
{
    class Program
    {
        const string FILENAME = @"c:\temp\test.xml";
        static void Main(string[] args)
        {
            XDocument doc = XDocument.Load(FILENAME);
            Dictionary<string, XElement> dict1 = doc.Descendants("formfield")
                .GroupBy(x => (string)x.Attribute("field_id"), y => y)
                .ToDictionary(x => x.Key, y => y.FirstOrDefault());
            //where attibutes may be repeated
            Dictionary<string, List<XElement>> dict2 = doc.Descendants("formfield")
                .GroupBy(x => (string)x.Attribute("field_id"), y => y)
                .ToDictionary(x => x.Key, y => y.ToList());
        }
    }
}