tags:

views:

180

answers:

4

I have the following method to parse XMLElements:

DisplayMessages(XElement root)
{
  var items = root.Descendants("Item");
  foreach (var item in items)
  {
     var name = item.Element("Name");
     ....
  }
}

In debug mode, I can see the root as XML like this:

<ItemInfoList>
  <ItemInfo>
    <Item>
      <a:Name>item 1</a:Name>
      ...
    <Item>
    ...

and var name is null (I expect to get "item 1"). I tried to use "a:Name" but it caused exception("character : cannot be used in name"). I am not sure if I have to set namespace in root XElelement or not. All the xml node under root should be in the same namespace.

I am new to XElement. In my codes, item.Element("Name") will get its children node "Name"'s value value, is that right?

A: 

You need to create XNames that have a non-null Namespace. To do so, you have to create an XNamespace, and add the element name, see Creating an XName in a Namespace.

Martin v. Löwis
+2  A: 

You do need to define the "a" namespace in the root element:

<Root a:xmlns="http:///someuri.com">
...
</Root>

Then you can select an element in a non-default namespace using this syntax in LINQ to XML:

XNamespace a = "http:///someuri.com"; // must match declaration in document
...
var name = item.Element(a + "Name");

EDIT:

To retrieve the default namespace:

XNamespace defaultNamespace = document.Root.GetDefaultNamespace();
// XNamespace.None is returned when default namespace is not explicitly declared

To find other namespace declarations:

var declarations = root.Attributes().Where(a => a.IsNamespaceDeclaration);

Note that namespaces can be declared on any element though so you would need to recursively search all elements in a document to find all namespace declarations. In practice though this is generally done in the root element, if you can control how the XML is generated then that won't be an issue.

Sam
The xml is from REST service based on WCF REST preview kit 2. I guess I have to add namespace in my REST svr class like "a:xlmns...". On my client side, if there is any way to detect if incoming xml contains a namespace or not?
David.Chu.ca
See edit.
Sam
A: 

If you work with XML data that contains namespaces, you need to declare these namespaces. (That's a general observation I made, even though it seems to make it difficult to "just have a look" on data you don't know).

You need to declare an XNamespace for your XElements, as in these MSDN samples: Element(), XName

devio
+1  A: 

You need to use element names that include namespace. Try this:

static void DisplayMessages(XElement root)
{
    var items = root.Descendants(root.GetDefaultNamespace() + "Item");
    foreach (var item in items)
    {
        var name = item.Element(item.GetNamespaceOfPrefix("a") + "Name");
        Console.WriteLine(name.Value);
    }
}

Note that operator + is overloaded for XNamespace class in order to make code shorter: XNamespace.Addition Operator.

Konstantin Spirin