Reputation: 543
Here is a snippet of my XML (with only a few entries whereas there are actually around a thousand).
<?xml version="1.0" encoding="UTF-8"?>
<information_code version="3.5">
<entry code="000" title="Function, data for plans and description"/>
<entry code="001" title="Title page"/>
<entry code="002" title="List of pages or data modules"/>
<entry code="003" title="Change records and highlights"/>
<entry code="004" title="Access illustration"/>
</information_code>
What I need to do is match the 'code' attribute with a value that I pass into my query, then return the value of the 'title' attribute. It really shouldn't be hard but I'm going around in circles.
Here's where I currently am, but it always gets caught without matching. Obviously something wrong with my query.
private string getInfoName(string infoCode)
{
XDocument mydoc = XDocument.Load(GlobalVars.pathToInfoCodes);
string name = string.Empty;
try
{
var entry = mydoc
.Elements("entry")
.Where(e => e.Attribute("code").Value == infoCode)
.Single();
name = entry.Attribute("title").Value;
}
catch
{
MessageBox.Show("Info code not recognised: " + infoCode);
}
return name;
}
Upvotes: 1
Views: 498
Reputation: 37299
The problem is that when you use Elements
it searches only in the level you are currently at, which in this point is the <information_code>
- so there are no <entry>
elements there.
You can use .Element("information_code").Elements("entry")
or use instead .Descendants
:
string wantedCode = "001";
var title = XDocument.Load(GlobalVars.pathToInfoCodes)
.Descendants("entry")
.Where(e => e.Attribute("code")?.Value == wantedCode)
.Select(e => e.Attribute("title").Value).FirstOrDefault();
You can also do it with the query syntax. Might look nicer:
var title = (from e in XDocument.Load("data.xml").Descendants("entry")
where e.Attribute("code")?.Value == wantedCode
select e.Attribute("title")?.Value).FirstOrDefault();
Note that the ?.
syntax is C# 6.0 Null Propagation. If you are with an earlier C# version then you will have to store the attribute in a variable, check that it is not null
and only then access .Value
Upvotes: 1