Deborah's Developer MindScape






         Tips and Techniques for Web and .NET developers.

September 1, 2010

XML Literals: Reading an XML File with a Variable Namespace

Filed under: VB.NET,XML @ 1:40 am

This post covers the technique for reading an XML file that includes an XML namespace (xmlns) attribute, when that attribute is not predefined at compile time.

This post continues the series on using XML literals which starts here. If you need to read an XML file with a namespace that is predefined at compile time, you can use the simple technique detailed in this prior post. Since XML Literals are a VB.NET feature only (new in VB9/VS 2008), this post only includes VB.NET code.

The title of this post is a little bit of a misnomer because, as far as I could find, you cannot read an XML file using XML literals if the namespace is not predefined at compile time.

So here is the XML in a file named CustomerInfo.xml:

<?xml version="1.0" encoding="utf-8" ?>
<Customers xmlns="
http://customer/2010/info">
  <Customer>
    <LastName>Baggins</LastName>
    <FirstName>Bilbo</FirstName>
  </Customer>
  <Customer>
    <LastName>Baggins</LastName>
    <FirstName>Frodo</FirstName>
  </Customer>
  <Customer>
    <LastName>Gamgee</LastName>
    <FirstName>Sam</FirstName>
  </Customer>
</Customers>

Notice the xmlns attribute defining the namespace.

If you then want to use XML literals to read the file, you must define an Imports statement as shown in the prior post and listed below:

VB.NET:

Imports <xmlns="http://customer/2010/info">

But this code assumes the code has the name of the namespace at compile time. What if the namespace can change depending on the user or test vs. production or the day of the week or the third party application that the XML is coming from? Then you cannot use the Imports statement.

The trick to reading an XML file with a variable XML namespace is to use the XNamespace class.

VB.NET:

Dim ns As XNamespace = "http://customer/2010/info"
For Each custXML In xmlDoc.Descendants(ns + "Customer")
    fullName = custXML.Descendants(ns + "LastName").Value & ", " &
                custXML.Descendants(ns + "FirstName").Value
    Debug.WriteLine(fullName)
Next

This code creates an XNamespace variable. This example still hard-codes the correct namespace into this variable, but since it is a variable the value could come from anywhere. It could be read from a table or from a configuration file or be passed in as a command line parameter.

The XML Descendants method is then used to find the nodes. The Descendants method takes an XName, so you can add the XNamespace to the string name of the element to generate the XName. By using the XNamespace in this manner, the code finds the appropriate elements.

Use this technique any time you need to read an XML file that contains a namespace and you cannot hard-code that namespace into an Imports statement.

Enjoy!

1 Comment

  1.   Richard — September 3, 2010 @ 1:46 pm    Reply

    If you don’t know what the namespace is, you can use:
    ns = xmlDoc.Root.Name.Namespace

    You don’t need Descendants to get the FirstName and LastName elements, as they’re direct children of the custXML node; you should use Element instead.

    Accessing the Value property will throw an exception if the element doesn’t exist. You can take advantage of the explicit conversions defined on XElement to get the value or return null/Nothing if the element doesn’t exist.

    As this example isn’t specific to VB.NET, the equivalent C# code is:

    XNamespace ns = “http://customer/2010/info”;
    // Or: XNamespace ns = xmlDoc.Root.Name.Namespace;
    foreach (XElement custXML in xmlDoc.Descendants(ns + “Customer”))
    {
    fullName = (string)custXML.Element(ns + “LastName”) + “, ” + (string)custXML.Element(ns + “FirstName”);
    Debug.WriteLine(fullName);
    }

RSS feed for comments on this post. TrackBack URI

Leave a comment

© 2019 Deborah's Developer MindScape   Provided by WPMU DEV -The WordPress Experts   Hosted by Microsoft MVPs