Reputation: 2451
I have got an xml string like this, and I am trying to deserialize it to an object with class Credentials. But the namespace prefix is stopping me.
The Credentials class itself doesn't have any XmlRoot attribute to set namespace. But some class which contains a Credentials property does. And the "ds" prefix below is from the container's serialized xml.
The container's xml is like this:
<ds:DataSource xmlns:ds="urn:My-Namespace">
<ds:Credentials>
<ds:UserName>foo</ds:UserName>
<ds:Domain>bar</ds:Domain>
</ds:Credentials>
</ds:DataSource>"
Then when I get the element "Credentials" from the containter element, it returns this:
<ds:Credentials xmlns:ds="urn:My-Namespace">
<ds:UserName>foo</ds:UserName>
<ds:Domain>bar</ds:Domain>
</ds:Credentials>
I can't deserialize this to a correct Credentials object because of the extra namespace. Is that possible to remove it? I have tried How to remove namespace prefix. (C#), the element still got a default namespace there.
<Credentials xmlns="urn:My-Namespace">
<UserName>foo</UserName>
<Domain>bar</Domain>
</Credentials>
Upvotes: 0
Views: 2076
Reputation: 2451
Thanks for the inspiration of har07 and http://bohu7.wordpress.com/2008/12/11/removing-default-namespaces-from-an-xdocument/, I worked out the solution myself, it would keep normal attributes and remove other namespaces:
public static void RemoveNamespace(this XElement element)
{
foreach (XElement e in element.DescendantsAndSelf())
{
if (e.Name.Namespace != XNamespace.None)
e.Name = e.Name.LocalName;
if (e.Attributes().Any(a => a.IsNamespaceDeclaration || a.Name.Namespace != XNamespace.None))
e.ReplaceAttributes(e.Attributes().Select(NoNamespaceAttribute));
}
}
private static XAttribute NoNamespaceAttribute(XAttribute attribute)
{
return attribute.IsNamespaceDeclaration
? null
: attribute.Name.Namespace != XNamespace.None
? new XAttribute(attribute.Name.LocalName, attribute.Value)
: attribute;
}
Upvotes: 0
Reputation: 89295
There is an article in MSDN that can be adapted to do what you want : How to: Change the Namespace for an Entire XML Tree
Basically the article suggests to change Name
of every XElement
in the tree to a new Name
(FYI, Name
property contains information about the namespace and the local name). In this case, since we want to change each element to no namespace, you can change Name
to the corresponding Name.LocalName
:
var xml = @"<ds:DataSource xmlns:ds=""urn:My-Namespace"">
<ds:Credentials>
<ds:UserName>foo</ds:UserName>
<ds:Domain>bar</ds:Domain>
</ds:Credentials>
</ds:DataSource>";
var tree1 = XElement.Parse(xml);
foreach (XElement el in tree1.DescendantsAndSelf())
{
el.Name = el.Name.LocalName;
List<XAttribute> atList = el.Attributes().ToList();
el.Attributes().Remove();
foreach (XAttribute at in atList)
el.Add(new XAttribute(at.Name.LocalName, at.Value));
}
//remove xmlns:ds="urn:My-Namespace"
tree1.RemoveAttributes();
//print result to console
Console.WriteLine(tree1.ToString());
Upvotes: 1