Behroz Sikander
Behroz Sikander

Reputation: 4049

XDocument Multiple namespaces

I have a weird problem and I tried everything regarding XDocument.

I want to get the value of "CategoryClass" nodes and populate the sub nodes in my own object of type "ListBoxClass". But the LINQ query is not returning anything.

System.Xml.Linq.XNamespace lName = xDoc.Root.GetDefaultNamespace();
        System.Xml.Linq.XNamespace lANamespace = "http://schemas.datacontract.org/2004/07/KRefreshService";

        var lEle = from xml2 in xDoc.Element(lName + "GetCategoriesResponse").Element(lName + "GetCategoriesResult").Elements(lANamespace + "CategoryClass")
                                                    select new ListBoxClass 
                                                    {
                                                        Id =  (int)xml2.Element(lName + "ID"),
                                                        Name = xml2.Element(lName+ "CatName").ToString(),
                                                        Description = xml2.Element(lName + "CatDescription").ToString()
                                                    };

Here is the XML

<GetCategoriesResponse xmlns="http://tempuri.org/">
 <GetCategoriesResult xmlns:a="http://schemas.datacontract.org/2004/07/KRefreshService" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<a:CategoryClass>
  <a:CatDescription>General questions regarding IQ. These questions will help you prepare for the interviews.</a:CatDescription>
  <a:CatName>IQ</a:CatName>
  <a:ID>1</a:ID>
</a:CategoryClass>
<a:CategoryClass>
  <a:CatDescription>This category will help you improve your general knowledge. It have information from all the different subjects.</a:CatDescription>
  <a:CatName>General Knowledge</a:CatName>
  <a:ID>2</a:ID>
</a:CategoryClass>
<a:CategoryClass>
  <a:CatDescription>If you feel that you computer science basics are slipping by your head as you involve more in technology. No problem! subscribe to this category.</a:CatDescription>
  <a:CatName>Computer Science</a:CatName>
  <a:ID>3</a:ID>
</a:CategoryClass>

Upvotes: 0

Views: 1506

Answers (1)

Jon Skeet
Jon Skeet

Reputation: 1502066

The problem is this part of the query:

select new ListBoxClass 
{
    Id =  (int)xml2.Element(lName + "ID"),
    Name = xml2.Element(lName+ "CatName").ToString(),
    Description = xml2.Element(lName + "CatDescription").ToString()
};

You're using the wrong namespace here - those elements have the a prefix:

<a:CatDescription>...</a:CatDescription>
<a:CatName>IQ</a:CatName>
 <a:ID>1</a:ID>

... so they're using namespace http://schemas.datacontract.org/2004/07/KRefreshService". You're using the namespace declared in the root element of the document instead.

Also I expect you want the value of each XElement, which I tend to fetch by the explicit conversion to string. Calling ToString() will give you the indented XML for the element. So you want:

select new ListBoxClass 
{
    Id =  (int) xml2.Element(lANamespace + "ID"),
    Name = (string) xml2.Element(lANamespace + "CatName"),
    Description = (string) xml2.Element(lANamespace + "CatDescription")
};

(It's not clear why you're fully-qualifiying System.Xml.Linq.XNamespace by the way, or why you've got an l prefix for your variables... you could do a lot to make this code clearer, when you've made it work.)

EDIT: The code that you said doesn't work behaves fine for me:

using System;
using System.Linq;
using System.Xml.Linq;

public class Test
{
    static void Main(string[] args)
    {
        XDocument doc = XDocument.Load("test.xml");
        XNamespace envelopeNs = doc.Root.GetDefaultNamespace();
        XNamespace resultNs = "http://schemas.datacontract.org/2004/07/KRefreshService";

        Console.WriteLine(doc.Element(envelopeNs + "GetCategoriesResponse")
                             .Element(envelopeNs + "GetCategoriesResult")
                             .Elements(resultNs + "CategoryClass")
                              .Count());
    }
}

That prints 3. So if you're having trouble with it, there must be something you haven't told us.

Upvotes: 1

Related Questions