【问题标题】:C# & LINQ - Get names of parent elements in xml queryC# & LINQ - 在 xml 查询中获取父元素的名称
【发布时间】:2015-08-10 21:42:52
【问题描述】:

我有一个 XML 文件,其中包含 IP 地址及其分配的位置/楼层,如下所示:

<Locations>
   <LOCATION1>
      <FLOOR1>
         <SECTION1>
            <IP>10.10.10.10</IP>
            <IP>etc....
         </SECTION1>
      </FLOOR1>
   </LOCATION1>
.....

我试图做的是获取 IP 地址的查询并返回父元素的名称。我能够查询该 IP,但我没有任何运气弄清楚如何获取父元素名称(即 SECTION1、FLOOR1、LOCATION1)。这是我用于查询 xml 以查找 IP 的代码,我只是让它返回该值以验证我的查询是否成功:

var query = from t in xmlLocation.Descendants("IP")
            where t.Value.Equals(sIP)
            select t.Value;

【问题讨论】:

  • XElement 有一个名为Parent 的属性链接到它的父元素。您可以使用它来遍历树直到根。
  • 您正在寻找.Ancestors()

标签: c# xml linq linq-to-xml


【解决方案1】:

试试这个: XML

<?xml version="1.0" encoding="utf-8" ?>
<Locations>
  <LOCATION1>
    <FLOOR1>
      <SECTION1>
        <IP>10.10.10.10</IP>
        <IP>20.20.20.20</IP>
      </SECTION1>
    </FLOOR1>
    <FLOOR2>
      <SECTION1>
        <IP>30.30.30.30</IP>
        <IP>40.40.40.40</IP>
      </SECTION1>
    </FLOOR2>
  </LOCATION1>
</Locations >

​

代码

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

namespace ConsoleApplication1
{
    class Program
    {
        const string FILENAME = @"c:\temp\test.xml";
        static void Main(string[] args)
        {
            XDocument doc = XDocument.Load(FILENAME);

            var results = doc.Descendants("LOCATION1").Elements().Select(x => new
            {
                parent = x.Name.ToString(),
                ip = x.Descendants("IP").Select(y => (string)y).ToList()
            }).ToList();

        }
    }

}
​

下面的代码获取位置、楼层和剖面

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

namespace ConsoleApplication1
{
    class Program
    {
        const string FILENAME = @"c:\temp\test.xml";
        static void Main(string[] args)
        {
            XDocument doc = XDocument.Load(FILENAME);

            var results = doc.Descendants("Locations").Elements().Select(x => x.Elements().Select(y => y.Elements().Select(z => new {
                location = x.Name.ToString(),
                floor = y.Name.ToString(),
                section = z.Name.ToString(),
                ip = z.Descendants("IP").Select(i => (string)i).ToList()
            })).SelectMany(a => a)).SelectMany(b => b).ToList();

        }
    }

}
​

【讨论】:

    【解决方案2】:
    var xDoc = XDocument.Load(filename);
    var ip = xDoc.XPathSelectElement("//IP['10.10.10.10']");
    var names = ip.Ancestors().Select(a => a.Name.LocalName).ToList();
    

    名称将包含SECTION1, FLOOR1, LOCATION1, Locations

    如果您事先知道这些名称,您也可以使用它们来选择正确的节点

    var ip = xDoc.XPathSelectElement("//LOCATION1/FLOOR1/SECTION1/IP['10.10.10.10']");
    

    var section = xDoc.XPathSelectElement("//LOCATION1/FLOOR1/SECTION1[IP['10.10.10.10']]");
    

    【讨论】:

    • 考虑添加一些文字、解释、细节。
    • 效果很好,谢谢。对于那些可能偶然发现这一点的人,请确保您有“使用 System.Xml.XPath”来访问 XPathSelectElement。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多