May 28
2008

I've been struggling all day to query an XDocument instance, the XPath query I am trying to use seems fairly straightforward:

//OrderResponseHeader/ListOfReferenceCoded[.//ReferenceTypeCoded = 'AgreementNumber']//RefNum

Translating this query into Linq To Xml was neither intuitive nor extensible. So I looked at using the XPathSelectElement[s] extension, and found one major problem with the implementation - it cannot handle default namespaces without a prefix, which the XDocument I am querying against has.

This means that in order for my query to work I would have to amend it include a prefix before each element name. This is not ideal, and the potential for error increases.

After much of the afternoon Googling for an answer, I eventually came across a simple solution on the MSDN forums which removes all namespaces from an XDocument instance. Here is how I have implemented it:

private XDocument RemoveNamespace(XDocument xdoc)
{
	foreach (XElement e in xdoc.Root.DescendantsAndSelf())
	{
		if (e.Name.Namespace != XNamespace.None)
		{
			e.Name = XNamespace.None.GetName(e.Name.LocalName);
		}
		
		if (e.Attributes().Where(a => a.IsNamespaceDeclaration || a.Name.Namespace != XNamespace.None).Any())
		{
			e.ReplaceAttributes(e.Attributes().Select(a => a.IsNamespaceDeclaration ? null : a.Name.Namespace != XNamespace.None ? new XAttribute(XNamespace.None.GetName(a.Name.LocalName), a.Value) : a));
		}
	}
  
	return xdoc;
}

And now I can query directly on the XDocument using XPathSelectElement: 

AgreementNumber = message.XPathSelectElement("//OrderResponseHeader/ListOfReferenceCoded[.//ReferenceTypeCoded='AgreementNumber']//RefNum").Value

Tags: | | |



mike posted on May 28, 2008 15:10

Comments

Posted on Thursday, 11 December 2008 00:28
Pingback from bohu7.wordpress.com

Removing default namespaces from an XDocument « Bo Hu’s Blog
Bo
Posted on Thursday, 11 December 2008 05:21
Thank you very much sir, exactly the solution I am looking for.
Excellent post!
Carlos
Posted on Friday, 17 April 2009 18:17
I also had the same problem.
I have a much simpler workaround to remove namespaces (when you know them):

[code]

XDocument _catalog = XDocument.Load(xmlPath);
string catalogString = _catalog.ToString();
catalogString = catalogString.Replace(string.Format(" xmlns=\"{0}\"",catalogNamespace), "");

catalogXML = XDocument.Parse(catalogString);

[/code]
Posted on Thursday, 16 July 2009 22:52
Great idea - this process was typically a pain especially when you just wanted to grab some data out real quick.
Posted on Tuesday, 15 December 2009 00:26
Pingback from everydayinternetstuff.com

Default namespace for LINQ to XML query | Everyday Internet Stuff

Add comment




  Country flag

biuquote
Loading