views:

538

answers:

2

Hi

I'm trying to get more into LINQ-to-XML, so I've made myself a neat little example XML-document to try things out on. In addition, I tried (and successfully) made my own XML-schema for that file, just to test things out. The XML-document is pretty straightforward, and pretty much looks like this:

<cars xmlns="/carsSchema.xsd">
  <car age="5">
    <carId>1</carId>
    <brand>BMW</brand>
    <model>320i</model>
    <color paintType="metallic">Red</color>
  </car>

  <car age="2">
    <carId>2</carId>
    <brand>VW</brand>
    <model>Golf</model>
    <color paintType="matt">White</color>
  </car>
[...]
</cars>

Now, querying this document works just fine if i remove the xmlns-attribute from the root element. When i add it back in, the query returns null and nothing. I've tried to find out by myself, but I've yet to find a sollution that fixes my problem.

Here's the C#-bit:

        XDocument xmlDoc = XDocument.Load(currentDir + "\\Cars.xml");

// XNamespace ns = "{" + currentDir + "\\carSchema.xsd}";
// Tried to query xmlDoc.Descendants(ns+"car") after reading another post, 
// but that  made no difference

        var carInfo1 = from car in xmlDoc.Descendants("car")
                       select (string)car.Element("brand") + ": " + (string)car.Element("model");

Anyone sees what's wrong? And why should LINQ really care that much about the namespace? Can't it just query my file and don't care about it?

Thanks in advance! :-)

+2  A: 

When you're searching by descendants and element, you need to specify the namespace. This is pretty easy with LINQ to XML. It looks like you were nearly there, but didn't do it for the elements:

XDocument xmlDoc = XDocument.Load(currentDir + "\\Cars.xml");
// I don't think namespace URIs are really resolved. I'm not sure though -
// for a proof of concept, I suggest you use a namespace of
// http://dummy.com/dummy.xsd
XNamespace ns = "/carSchema.xsd";

var carInfo1 = from car in xmlDoc.Descendants(ns + "car")
                   select (string)car.Element(ns + "brand") + ": " + 
                          (string)car.Element(ns + "model");
Jon Skeet
Now, that fixed it. Thanks a lot! However, is there some way to make LINQ ignore the namespace, except for removing it from the XML-doc in the first place?
Arve Systad
I don't believe so, no. Although it's a bit of a pain, I think it makes sense really.
Jon Skeet
A: 

This also works when you use a fictitious "http://" URI as your namespace. You are correct. It is not resolved.

        private XNamespace ns = "http://schemas.xin2009.com/DataMap/2009";

                IEnumerable<string> names = (from spnode in _map.Descendants(ns + "Entity")
                                         where spnode.Attribute("name").Value == this.Entity
                                         select spnode.Element(ns + "StoredProcedure").Attribute("name").Value);

Note the ns for the namespace only had to be added to the Elements not the Attributes.

Calendar Software Expert