简体   繁体   English

如何使用一个Linq查询获取XML属性和元素?

[英]How to get XML Attribute and Element with One Linq Query?

I have an XML document that looks like this: 我有一个看起来像这样的XML文档:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <searchlayers>
    <searchlayer whereClause="ProjectNumber=a">Herbicide</searchlayer>
    <searchlayer whereClause="ProjectNumber=b">Herbicide - Point</searchlayer>
    <searchlayer whereClause="ProjectNumber=c">miscellaneous</searchlayer>
    <searchlayer whereClause="ProjectNumber=d">miscellaneous - Point</searchlayer>
    <searchlayer whereClause="ProjectNumber=e">Regrowth Control</searchlayer>
    <searchlayer whereClause="ProjectNumber=f">Regrowth Control - Point</searchlayer>
    <searchlayer whereClause="ProjectNumber=g">Tree Removal</searchlayer>
    <searchlayer whereClause="ProjectNumber=h">Tree Removal - Point</searchlayer>
    <searchlayer whereClause="ProjectNumber=i">Trimming</searchlayer>
    <searchlayer whereClause="ProjectNumber=j">Trimming - Point</searchlayer>
  </searchlayers>
</configuration>

Is it possible to write one single Linq statement to get each of the element (eg Herbicide, miscellaneous, Regrowth Control... etc) with its matching whereClause (eg for Herbicide, the where clause would be "ProjectNumber=a")? 是否可以编写单个Linq语句来获取具有匹配的whereClause(例如,对于除草剂而言,where子句为“ ProjectNumber = a”)的每个元素(例如,除草剂,其他,再生控制等)?

I can write two statements separately, one to get the elements, one to get the attributes, but it would be nice to write just one Linq statement that gets both at the same time. 我可以分别编写两个语句,一个用于获取元素,一个用于获取属性,但是最好只编写一个同时获得两个语句的Linq语句。

Thanks. 谢谢。

Yes it is possible. 对的,这是可能的。 But there are many possible data structure can be used to store list of 2 values pair, here is one example using Tuple : 但是有许多可能的数据结构可用于存储2个值对的列表,这是一个使用Tuple示例:

XDocument doc = XDocument.Load("path_to_xml_file.xml");
List<Tuple<string, string>> result =
                doc.Root
                   .Descendants("searchlayer")
                   .Select(o => Tuple.Create((string) o, (string) o.Attribute("whereClause")))
                   .ToList();

You can use this to to select all elements matching Herbicide whose whereClause matches ProjectNumber=a 您可以使用它来选择与其中Herbicide匹配ProjectNumber=a Herbicide匹配的所有元素

IEnumerable<XElement> result =
    from el in doc.Elements("Herbicide")
    where (string)el.Attribute("whereClause") == "ProjectNumber=a"
    select el;

Another alternative would be: 另一种选择是:

var result = doc.Descendants()
        .Where(e => e.Attribute("ProjectNumber=a") != null)
        .ToList();

Which should provide you every element whose whereClause equals "ProjectNumber=a". 应该为您提供whereClause等于“ ProjectNumber = a”的每个元素。

You can create a set of anonymous objects as follows: 您可以创建一组匿名对象,如下所示:

var result = root.Element("searchlayers")
                 .Elements("searchlayer")
                 .Select(i => 
                     new {attribute = i.Attribute("whereClause").Value, 
                          value = i.Value});

This will give a set of records, where the attributes are paired with the element values. 这将提供一组记录,其中属性与元素值配对。

If you want this in query syntax, it looks like this: 如果您希望使用查询语法,它看起来像这样:

var result = from el in root.Elements("searchlayers").Elements("searchlayer")
             select new {attribute = el.Attribute("whereClause").Value, 
                         value = el.Value};

You can use the Attributes property to get the attribute from the XML node, along with the InnerText , like so: 您可以使用Attributes属性从XML节点获取属性,以及InnerText ,如下所示:

XmlDocument doc = new XmlDocument();
doc.LoadXml(yourxml);

XmlNodeList xlist = doc.GetElementsByTagName("searchlayer");
for(int i=0;i<xlist.Count;i++)
 {
  Console.WriteLine(xlist[i].InnerText + " " + xlist[i].Attributes["whereClause"].Value);
 }

If you must use LINQ, you could use XDocument and then return anonymous class objects consisting of the attribute and text, like so: 如果必须使用LINQ,则可以使用XDocument ,然后返回由属性和文本组成的匿名类对象,如下所示:

XDocument xdoc = XDocument.Load(yourxmlfile);
var result = xdoc.Root.Elements("searchlayers").Elements("searchlayers").Select(x => new {attr = x.Attribute("whereClause").Value, txt = x.Value});
foreach (var r in result)
 {
  Console.WriteLine(r.attr + " " + r.txt);
 }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM