Reputation: 3084
I have an XML document that looks like this:
<?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 (e.g. Herbicide, miscellaneous, Regrowth Control... etc) with its matching whereClause (e.g. for Herbicide, the where clause would be "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.
Thanks.
Upvotes: 1
Views: 836
Reputation: 21757
You can use the Attributes
property to get the attribute from the XML node, along with the InnerText
, like so:
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:
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);
}
Upvotes: 0
Reputation: 89325
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
:
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();
Upvotes: 1
Reputation: 7414
You can use this to to select all elements matching Herbicide
whose whereClause matches ProjectNumber=a
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".
Upvotes: 0
Reputation: 11840
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};
Upvotes: 0