Archive

Posts Tagged ‘XML namespaces’

Working with XML Namespaces and LINQ

October 11, 2010 3 comments

Ben XML Namespaces

October 11th 2010 | Ben Yoder

Working with XML Namespaces and LINQ

While working on a project using LINQ to XML to parse a web response, I ran into an issue whereby my calls to get an entity’s Descendants or Elements were returning no results. It turned out that the specified response included a namespace. In this case you can’t use the common element name—you must get the fully qualified XName.

For example, given the following XML and LINQ Query:

    string xml = @"<Employees>
      <Employee>
        <FirstName>John</FirstName>
        <LastName>Smith</LastName>
        <Id>1</Id>
      </Employee>
    </Employees>";

        XElement employee = XElement.Parse(xml);

    var employees = from e in employee.Descendants("Employee")
                        select new
                        {
                            Id = e.Element("Id").Value,
                            FirstName = e.Element("FirstName").Value,
                            LastName = e.Element("LastName").Value
                        };

The query works and the employees object contains John Smith. However if the XML changes, the query returns nothing:

    <h:Employees xmlns:h="http://www.w3.org">
      <h:Employee>
        <h:FirstName>John</h:FirstName>
        <h:LastName>Smith</h:LastName>
        <h:Id>1</h:Id>
      </h:Employee>
    </h:Employees>

After browsing through some MSDN documentation, I learned that I have to include the namespace in the query. I got the full name using XName.Get()

    XName root = XName.Get("Employee", "http://www.w3.org");
    XName firstName = XName.Get("FirstName", "http://www.w3.org");
    XName lastName = XName.Get("LastName", "http://www.w3.org");
    XName id = XName.Get("Id", "http://www.w3.org");

Replace the names in the LINQ query and it returns the correct results. Of course, there are other ways to accomplish this. You could create an XNamespace object based on the namespace string and prepend it to each element name in the query. Creating an individual XName object for each query parameter gets kind of verbose, so for more complex LINQ this is probably not the preferred way.

Ben Yoder is a Senior .NET developer at Thycotic Software, an agile software services and product development company based in Washington DC. Secret Server is our flagship password management software product.