C# – Noob LINQ – reading, filtering XML with XDocument

clinqlinq-to-xml

I'm just learning XDocument and LINQ queries. Here's some simple XML (which doesn't look formatted exactly right in this forum in my browser, but you get the idea . . .)

<?xml version="1.0" encoding="utf-8"?>
<quiz  
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://www.example.com/name XMLFile2.xsd"
  title="MyQuiz1">
  <q_a>
    <q_a_num>1</q_a_num>
    <q_>Here is question 1</q_>
    <_a>Here is the answer to 1</_a>
  </q_a>

  <q_a>
    <q_a_num>2</q_a_num>
    <q_>Here is question 2</q_>
    <_a>Here is the answer to 2</_a>
  </q_a>
</quiz>

I can iterate across all elements in my XML file and display their Name, Value, and NodeType in a ListBox like this, no problem:

        XDocument doc = XDocument.Load(sPath);
        IEnumerable<XElement> elems = doc.Descendants();

        IEnumerable<XElement> elem_list = from elem in elems
                                          select elem;

        foreach (XElement element in elem_list)
        {
            String str0 = "Name = " + element.Name.ToString() + 
                          ",  Value = " + element.Value.ToString() +
                          ",  Nodetype = " + element.NodeType.ToString();
            System.Windows.Controls.Label strLabel = new System.Windows.Controls.Label();
            strLabel.Content = str0;
            listBox1.Items.Add(strLabel);
        }

…but now I want to add a "where" clause to my query so that I only select elements with a certain name (e.g., "qa") but my element list comes up empty. I tried . . .

            IEnumerable<XElement> elem_list = from elem in elems
                                        where elem.Name.ToString() == "qa"
                                        select elem;

Could someone please explain what I'm doing wrong? (and in general are there some good tips for debugging Queries?) Thanks in advance!

Best Answer

The problem is that the Name property is not a string, it's an XName. When you ToString it, you get a lot more than you think.

While it's possible to write the query in the way you're attempting to, also consider these possibilites:

//from nodes immediately below this one
IEnumerable<XElement> elem_list = doc.Elements("qa");

//from nodes of all levels below this node.
IEnumerable<XElement> elem_list = doc.Descendants("qa");