Reputation: 123
In the following code I am using XPath to find all of the matching nodes using XPath, and appending the values to a StringBuilder.
StringBuilder sb = new StringBuilder();
foreach (XmlNode node in this.Data.SelectNodes("ID/item[@id=200]/DAT[1]/line[position()>1]/data[1]/text()"))
{
sb.Append(node.Value);
}
return sb.ToString();
How do I do the same thing, except using Linq to XML instead? Assume that in the new version, this.Data is an XElement object.
Upvotes: 1
Views: 1037
Reputation: 39248
I have created an open source helper library that let's you generate xpath expressions using Linq-esq expressions. Not sure if it is helpful in your context, but posting the link to the API
http://www.syntaxsuccess.com/viewarticle/how-to-create-xpath-using-linq
Upvotes: 0
Reputation: 22433
Query syntax would look something like this.
var nodes = from item in Data.Elements("item")
where item.Attribute("id").Value == "200"
let dat = item.Element("DAT")
from line in dat.Elements("line").Skip(1)
let data = line.Element("data")
select data;
var sb = new StringBuilder();
foreach (var node in nodes)
sb.Append(node.Value);
... this would get rid of the possible nullref exceptions and would get rid of the foreach
loop.
var nodes = from item in Data.Elements("item")
let id = item.Attribute("id")
where id != null && id.Value == "200"
let dat = item.Element("DAT")
where dat != null
from line in dat.Elements("line").Skip(1)
let data = line.Element("data")
where data != null
select data.Value;
return nodes.Aggregate(new StringBuilder(), (sb, r) => sb.Append(r))
.ToString();
Upvotes: 0
Reputation: 292355
You can try something like that :
var query =
from id in this.Data.Elements("ID") // ID
from item in id.Elements("item") // /item
where item.Attribute("id").Value == "200" // [@id=200]
let dat in item.Elements("DAT").ElementAtOrDefault(1) // /DAT[1]
where dat != null // (ensure there is an element at index 1)
from line in dat.Elements("line").Skip(1) // /line[position()>1]
let data in line.Elements("data").ElementAtOrDefault(1) // /data[1]
where data != null // (ensure there is an element at index 1)
select data // /text()
StringBuilder sb = new StringBuilder();
foreach(XElement data in query)
{
sb.Append(data.Value);
}
return sb.ToString();
As you can see, it's not really more convenient than XPath, so you should probably keep using XPath (as explained in Pierre-Alain's answer)
Upvotes: 0
Reputation: 23083
You can still use XPath with a XElement. You have to include the System.Xml.XPath namespace since its an extension method
var xml = XDocument.Parse("<xml></xml>");
var elements = xml.XPathSelectElements("ID/item[@id=200]/DAT[1]/line[position()>1]/data[1]/text()");
Upvotes: 1