Tuesday, May 06, 2008

 

Recently I was playing with some LINQ to XML for a demo I was preparing and was having trouble retrieving the expected values from what was a very straightforward query.

Have a look at the XML file that looks like this (the results of programmatically calling this Amazon service).

Each Item element represents a book and I wanted to retrieve the Title. How would you form that query with LINQ to XML?

I went for the obvious:
  var res =
from ia in XElement.Parse(e.Result).DescendantsAndSelf("ItemAttributes")
select ia.Element("Title").Value;
When that did not produce the expected results I scratched my "tired" head at the time and pinged MikeT who came up with the correct way of doing this (you still have time to work it out on your own).

The clue (and at the same time further "excuse") is that all my previous experiments with LINQ to XML involved using my own demo XML files that never had namespaces inside so I forgot all about them (haven't paid the tax in a while). I find quite ugly what you have to do to incorporate namespaces in a LINQ to XML query, but there seems to be no nicer alternative to the following (thanks Mike):
void SomeMethod()
{
var res =
from ia in XElement.Parse(e.Result).DescendantsAndSelf(n("ItemAttributes"))
select ia.Element(n("Title")).Value;

// TODO use res
}

static XName n(string name)
{
return XNamespace.Get("http://webservices.amazon.com/AWSECommerceService/2005-10-05") + name;
}
I still didn't like this solution for the simple demo I wanted to use it for. So, I recalled VB's superior support for XML and I converted the project to VB and used the following instead which needs no extra method and is all round more elegant:
  Dim res = _
From ia In XElement.Parse(e.Result)...<n:ItemAttributes> _
Select ia...<n:Title>.Value()
...and if you are wondering where the n comes from, that is at the top of the VB file:
Imports <xmlns:n="http://webservices.amazon.com/AWSECommerceService/2005-10-05">
...another aspect of VB's beauty and another thing I had the opportunity to mention in my demo ;-)

Labels: ,


Comments:
I think as with most VB features, they are great when you have a simple case(demo) but are nothing but trouble in a real complex project.

 
_________________

Mr. Fischer your comment is absolutely ridiculous. Would you care to explain how this elegant feature could cause trouble in your "real complex project"?

 
_________________

thank u r information

it very useful

u r blog Is very nice

 
_________________

I think you'll find this works in C#

XElement resultXML = XElement.Load(url);
XNamespace ns = "http://schemas.microsoft.com/LiveSearch/2008/04/XML/web";



var results = resultXML.Descendants(ns + "WebResult");

 
_________________

Post a Comment

Please keep comments directly relevant to this blog post. Remember that generic support questions are best posted to the MSDN Forums.

Note that Anonymous comments are likely not going to appear so Sign-in or at least pick a Name even if you don't have a URL.





« Latest Posts

Copyright © Daniel Moth