Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Remove unused xmlns namespaces from an XmlDocument?

694 views
Skip to first unread message

mzarlenga

unread,
Jan 2, 2010, 1:21:23 AM1/2/10
to
My software receives XmlDocuments created by a software library. The
XmlDocuments I receive often contain many unused xmlns namespaces,
such as:

<ns1:Message xmlns:ns1="http://www.domain1.com/v1" xmlns:ns2="http://
www.domain2.com/v1" xmlns:ns3="http://www.domain3.com/v1"
xmlns:ns4="http://www.domain4.com/v1" xmlns:ns5="http://
www.domain5.com/v1"><ns1:Ack ns1:messageId="1"
ns1:dateTimeSent="2009-12-31T01:30:14.0462064Z" /></ns1:Message>

As you can see, ns2 through ns5 are extraneous.

Sometimes, more than 50% of the message is just unused namespaces and
I would like to remove them after I receive the XmlDocument (cannot
change the library) and before I send the message over the wire.

Are there any Xml-related classes or methods (C#, .NET 3.5) that I can
use to parse the XmlDocument and remove the unused namespaces?

Martin Honnen

unread,
Jan 2, 2010, 7:36:44 AM1/2/10
to

Does XmlDocument mean you have a System.Xml.XmlDocument? Or do you get
an XML document you could parse with LINQ to XML
(System.Xml.Linq.XDocument)?

One way to get rid of unused namespaces is to simply get rid of any
namespace declaration attributes, then serialize the document and the
serializer will take care of adding any namespace declarations that are
necessary to have a namespace well-formed document:

So with your above sample document the code

XDocument doc = XDocument.Load("input.xml",
LoadOptions.PreserveWhitespace);
doc.Descendants().Attributes().Where(a =>
a.IsNamespaceDeclaration).Remove();
doc.Save("output.xml", SaveOptions.DisableFormatting);

would output

<Message xmlns="http://www.domain1.com/v1"><Ack p2:messageId="1"
p2:dateTimeSent="2009-12-31T01:30:14.0462064Z"
xmlns:p2="http://www.domain1.com/v1" /></Message>

That document is semantically equivalent to the one you posted, only the
serializer has choosen to put the elements in the default namespace and
to use the prefix 'p2' for the attributes.

Does that suffice for your needs?

--

Martin Honnen --- MVP XML
http://msmvps.com/blogs/martin_honnen/

Mike

unread,
Jan 2, 2010, 12:57:56 PM1/2/10
to

I think it will. I'll try it and get back to you. Thank you.

mzarlenga

unread,
Jan 2, 2010, 1:38:05 PM1/2/10
to
On Jan 2, 4:36 am, Martin Honnen <mahotr...@yahoo.de> wrote:
> > Are there any Xml-related classes or methods (C#, .NET 3.5) that I can
> > use to parse the XmlDocument and remove the unused namespaces?
...

> Does XmlDocument mean you have a System.Xml.XmlDocument? Or do you get
> an XML document you could parse with LINQ to XML
> (System.Xml.Linq.XDocument)?
>
> One way to get rid of unused namespaces is to simply get rid of any
> namespace declaration attributes, then serialize the document and the
> serializer will take care of adding any namespace declarations that are
> necessary to have a namespace well-formed document:
>
> So with your above sample document the code
>
>              XDocument doc = XDocument.Load("input.xml",
> LoadOptions.PreserveWhitespace);
>              doc.Descendants().Attributes().Where(a =>
> a.IsNamespaceDeclaration).Remove();
>              doc.Save("output.xml", SaveOptions.DisableFormatting);
>
> would output
>
> <Message xmlns="http://www.domain1.com/v1"><Ack p2:messageId="1"
> p2:dateTimeSent="2009-12-31T01:30:14.0462064Z"
> xmlns:p2="http://www.domain1.com/v1" /></Message>
>
> That document is semantically equivalent to the one you posted, only the
> serializer has choosen to put the elements in the default namespace and
> to use the prefix 'p2' for the attributes.
>
> Does that suffice for your needs?

I think it will. I'll try it and get back to you. Thank you.

mzarlenga

unread,
Jan 2, 2010, 5:32:42 PM1/2/10
to
On Jan 2, 10:38 am, mzarlenga <mzarle...@gmail.com> wrote:
> >              XDocument doc = XDocument.Load("input.xml", LoadOptions.PreserveWhitespace);
> >              doc.Descendants().Attributes().Where(a => > > a.IsNamespaceDeclaration).Remove();
> >              doc.Save("output.xml", SaveOptions.DisableFormatting);
...

> > Does that suffice for your needs?

> I think it will. I'll try it and get back to you. Thank you.

I can't get this to build with VS 2008 professional, console app,
project's target framework is .NET 3.5

...
using System.Collections;
using System.Collections.Generic;
using System.Xml.Linq;
...


XDocument doc = XDocument.Load("input.xml",
LoadOptions.PreserveWhitespace);
doc.Descendants().Attributes().Where(a =>
a.IsNamespaceDeclaration).Remove();

Error 504 (on doc.Descendants()...")
'System.Collections.Generic.IEnumerable<System.Xml.Linq.XAttribute>'
does not contain a definition for 'Where' and no extension method
'Where' accepting a first argument of type
'System.Collections.Generic.IEnumerable<System.Xml.Linq.XAttribute>'
could be found (are you missing a using directive or an assembly
reference?)

Been through the MSDN site but I keep hitting an information roadblock
at XDocument.Descendants. Not sure where to proceed from there to get
to .Attributes().Where()

What using or assembly reference might I be missing?

Martin Honnen

unread,
Jan 3, 2010, 6:11:43 AM1/3/10
to
mzarlenga wrote:

> I can't get this to build with VS 2008 professional, console app,
> project's target framework is .NET 3.5
>
> ...
> using System.Collections;
> using System.Collections.Generic;
> using System.Xml.Linq;

You also need
using System.Linq;
and a reference to System.Core.dll.

mzarlenga

unread,
Jan 3, 2010, 3:02:13 PM1/3/10
to
Thank you for the pointers, Martin, you got me going in the right
direction.

I ended up with a different solution, once I understood that I could
XmlSerializer.Serialize() without the XmlSerializerNamespaces()
parameter and still get semantically correct Xml.

Works great!

0 new messages