Solved

Why do I have trouble using linq on XML with namespaces?

Posted on 2010-08-27
4
725 Views
Last Modified: 2013-11-11
Hello,

I have a class that parses XML from a string and sets the values from the XML to the class properties. I can parse an XML string fine except when a tag has a namespace attribute (xmlns). When I have the namespace included I get an index out of range error on the .ElementAt(0).

An exmaple of _responseXML is

<NetConnectResponse xmlns="http://www.experian.com/NetConnectResponse">
  <CompletionCode>0000</CompletionCode>
  <ReferenceId></ReferenceId>
  <Products xmlns="http://www.experian.com/ARFResponse">
    <CreditProfile>
      <Header>
        <ReportDate>08222010</ReportDate>
        <ReportTime>161300</ReportTime>
        <Preamble>TCA5</Preamble>
        <ARFVersion>07</ARFVersion>
      </Header>
      ...
      ...

Thanks for the help!
-gtar


//load response into XDoc
        xdoc = XDocument.Parse(_responseXML);

 
       //create assimble reportDateTime
        var header = from h in xdoc.Descendants("Header")
                     select new
                     {
                         ReportDate = h.Element("ReportDate").Value,
                         ReportTime = h.Element("ReportTime").Value
                     };

        //set linq vars to local vars
        string rawDate = header.ElementAt(0).ReportDate;
        string rawTime = header.ElementAt(0).ReportTime;

Open in new window

0
Comment
Question by:gtar
4 Comments
 
LVL 21

Accepted Solution

by:
chapmanjw earned 500 total points
ID: 33547859
Here is Microsoft's article on using XML namespaces with LINQ: http://msdn.microsoft.com/en-us/library/bb669152.aspx
0
 
LVL 27

Expert Comment

by:nmarun
ID: 33547967
Try something like this:

xdoc = XDocument.Parse(_responseXML);
XNamespace xNamespace = "http://www.experian.com/ARFResponse";

//create assimble reportDateTime
var header = from h in xdoc.Descendants(xNamespace + "Header")
             select new
             {
                   ReportDate = h.Element(xNamespace + "ReportDate").Value,
                   ReportTime = h.Element(xNamespace + "ReportTime").Value
             };

Arun

0
 
LVL 62

Expert Comment

by:Fernando Soto
ID: 33548048
Hi gtar;

I have corrected the code you placed in the question. You have two issues. One is that you need to use the namespace for the nodes that it is assigned to in the XML, see code snippet comments and two the query would never execute because it needs to be enumerated so I added the ToList() which will do the job.

Fernando
//load response into XDoc

xdoc = XDocument.Parse(_responseXML);



// Namespace to be used for child elements off the Root node

// except for the element Products and its child nodes which have 

// another namespace. 

XNamespace rns = "http://www.experian.com/NetConnectResponse";

// Namesapce to be used on the Products element and it child nodes

XNamespace pns = "http://www.experian.com/ARFResponse";



//create assimble reportDateTime

var header = (from h in xdoc.Descendants(pns + "Header")

              select new

              {

                  ReportDate = h.Element(pns + "ReportDate").Value,

                  ReportTime = h.Element(pns + "ReportTime").Value

              }).ToList();



//set linq vars to local vars

string rawDate = header.ElementAt(0).ReportDate;

string rawTime = header.ElementAt(0).ReportTime;

Open in new window

0
 

Author Comment

by:gtar
ID: 33548076
All that was needed for my query to execute was to include the root <NetConnectResponse> namespace in the query.

I was able to execute the query without the toList() method. I'm unclear as to why this is needed. Are you saying that if I had several <Header> values that the ToList would ad them to a list and that my original query would not?

Thanks for all your help!

I awarded chapmanjw with the points because I read the suggested msdn article and resolved my problem before I saw the rest of the posts.

Do you have a better approach to accessing the header data. It seems awkward to do the following

header.ElementAt(0).ReportDate

Thanks again,
Gtar

        XNamespace xNamespace = "http://www.experian.com/NetConnectResponse";



        //create assimble reportDateTime

        var header = from h in xdoc.Descendants(xNamespace + "Header")

                     select new

                     {

                         ReportDate = h.Element(xNamespace + "ReportDate").Value,

                         ReportTime = h.Element(xNamespace + "ReportTime").Value

                     };

Open in new window

0

Featured Post

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
c# string handling 1 27
Class object 2 26
DateTimepicker 4 33
How useful is the free version of Selenium? 3 0
Wouldn’t it be nice if you could test whether an element is contained in an array by using a Contains method just like the one available on List objects? Wouldn’t it be good if you could write code like this? (CODE) In .NET 3.5, this is possible…
Entity Framework is a powerful tool to help you interact with the DataBase but still doesn't help much when we have a Stored Procedure that returns more than one resultset. The solution takes some of out-of-the-box thinking; read on!
With the power of JIRA, there's an unlimited number of ways you can customize it, use it and benefit from it. With that in mind, there's bound to be things that I wasn't able to cover in this course. With this summary we'll look at some places to go…
Many functions in Excel can make decisions. The most simple of these is the IF function: it returns a value depending on whether a condition you describe is true or false. Once you get the hang of using the IF function, you will find it easier to us…

911 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

16 Experts available now in Live!

Get 1:1 Help Now