user726720
user726720

Reputation: 1237

C# Xelement not able to retrieve elements

I'm trying to test the Linq for retrieving some values of elements in the xml file:

Here is the code:

  try
        {
            XElement doc = XElement.Load(@"Z:\test.xml");

            string abc, def;


            foreach (XElement elm in doc.Descendants().Elements("test"))
            {
                abc = elm.Element("att").Value;
                def = elm.Element("title").Value;
                Console.WriteLine(abc);
                Console.WriteLine(def);
            }
        }

        catch (XmlException xe)
        {
            Console.WriteLine(xe);
        }

But this doesn't seem to go through the foreach loop. It's not giving me any error. I have debugged it and it reads the xml file just fine. But when it reaches the foreach loop, it just quits. What's the reason.

Part of my XML FILE:

<root xmlns:xsi="w3.org/2001/XMLSchema-instance"; xsi:noNamespaceSchemaLocation="test.xsd">
<test att="123" title="XXXX" />
<test att="2324" title="YYYY" />
</root>

Upvotes: 0

Views: 3609

Answers (2)

Marc Gravell
Marc Gravell

Reputation: 1062492

First we must note that

foreach (XElement elm in doc.Descendants().Elements("test"))

will only find elements that are not the root, not the immediate children of the root, but are at least 2 levels down; that is necessary to be a child-element of a descendant of the root. So: are your elements at least 2 levels down? If not:


Since you say it loads, this is probably a namespace issue. I'm guessing you have something like:

<foo xmlns="blahblahblah">
    ...
    <test>...</test>
</foo>

or

<bar:foo xmlns:bar="blahblahblah">
    ...
    <test>...</test>
</bar:foo>

in which case the name of those elements is not test, it is blahblahblah:test. To query that, you need to use a full XName.

For a concrete example:

string text = @"<foo xmlns=""blah""><test/></foo>";
var doc = XDocument.Parse(text);
var el0 = doc.Root.Element("test"); // null
XNamespace ns = "blah";
var el1 = doc.Root.Element(ns + "test"); // not null

Obviously you need to use the right namespace in your code, then .Elements(ns + "test").

Upvotes: 2

Adil Mammadov
Adil Mammadov

Reputation: 8676

First of all you need to have single root element otherwise it will throw exception:

<testRoot>
    <test att="123" title="XXXX" />
    <test att="2324" title="YYYY" />
</testRoot>

And code should be as below:

//Not XElement but XDocument
XDocument doc = XDocument.Load(@"D:\test\test.xml");

string abc, def;

foreach (XElement elm in doc.Descendants().Elements("test"))
{
    //Not elm.Element but elm.Attribute
    abc = elm.Attribute("att").Value;
    def = elm.Attribute("title").Value;
    Console.WriteLine(abc);
    Console.WriteLine(def);
}

Upvotes: 1

Related Questions