1

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;
}

1 Answer 1

1

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

Sign up to request clarification or add additional context in comments.

1 Comment

You should always prefer casting over using the Value property.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.