When generating XML from XmlDocument in .NET, a blank xmlns attribute appears the first time an element without an associated namespace is inserted; how can this be prevented?
Example:
XmlDocument xml = new XmlDocument();
xml.AppendChild(xml.CreateElement("root",
"whatever:name-space-1.0"));
xml.DocumentElement.AppendChild(xml.CreateElement("loner"));
Console.WriteLine(xml.OuterXml);
Output:
<root xmlns="whatever:name-space-1.0"><loner xmlns="" /></root>
Desired Output:
<root xmlns="whatever:name-space-1.0"><loner /></root>
Is there a solution applicable to the XmlDocument code, not something that occurs after converting the document to a string with OuterXml?
My reasoning for doing this is to see if I can match the standard XML of a particular protocol using XmlDocument-generated XML. The blank xmlns attribute may not break or confuse a parser, but it's also not present in any usage that I've seen of this protocol.
-
If the
<loner>element in your sample XML didn't have thexmlnsdefault namespace declaration on it, then it would be in thewhatever:name-space-1.0namespace rather than being in no namespace. If that's what you want, you need to create the element in that namespace:xml.CreateElement("loner", "whatever:name-space-1.0")If you want the
<loner>element to be in no namespace, then the XML that's been produced is exactly what you need, and you shouldn't worry about thexmlnsattribute that's been added automatically for you.Craig Trader : The problem lies with non-compliant XML parsers (typically from Microsoft) that can't cope with xmnls="").Will : /. called. They want their random MS bashing comment back.Kev : @W. Craig Trader - can't say I've encountered that as a problem. Example?Neil C. Obremski : Correct, I do not want thenode to have a namespace, but I don't want it to have a blank namespace attribute (xmlns) either. My reasoning is just to see if I can match the XML output of a particular protocol which is setup like this. Craig Trader : It wasn't random bashing. The Microsoft Updater Application Block uses an XML Manifest to determine what to deliver to a client. Unfortunately, the Manifest parser can't cope with xmlns=""; I had to write a post-processor that would strip out the empty xmlns attributes.From JeniT -
Since root is in an unprefixed namespace, any child of root that wants to be un-namespaced has to be output like your example. The solution would be to prefix the root element like so:
<w:root xmlns:w="whatever:name-space-1.0"> <loner/> </w:root>code:
XmlDocument doc = new XmlDocument(); XmlElement root = doc.CreateElement( "w", "root", "whatever:name-space-1.0" ); doc.AppendChild( root ); root.AppendChild( doc.CreateElement( "loner" ) ); Console.WriteLine(doc.OuterXml);Neil C. Obremski : Thanks, but adding the namespace to the actual root would break my XML in relation to the particular protocol I'm working with.Neil C. Obremski : Ah! I realized more what you were saying and took it into account when writing my own answer. Thanks JeremyFrom jlew -
If possible, create a serialization class then do:
XmlSerializerNamespaces ns = new XmlSerializerNamespaces(); ns.Add("", ""); XmlSerializer serializer = new XmlSerializer(yourType); serializer.Serialize(xmlTextWriter, someObject, ns);It's safer, and you can control the namespaces with attributes if you really need more control.
From ilitirit -
Thanks to Jeremy Lew's answer and a bit more playing around, I figured out how to remove blank
xmlnsattributes: pass in the root node's namespace when creating any child node you want not to have a prefix on. Using a namespace without a prefix at the root means that you need to use that same namespace on child elements for them to also not have prefixes.Fixed Code:
XmlDocument xml = new XmlDocument(); xml.AppendChild(xml.CreateElement("root", "whatever:name-space-1.0")); xml.DocumentElement.AppendChild(xml.CreateElement("loner", "whatever:name-space-1.0")); Console.WriteLine(xml.OuterXml);Thanks everyone to all your answers which led me in the right direction!
JeniT : Precisely. Putting theelement in the "whatever:name-space-1.0" namespace means that the empty xmlns attribute (which puts it in no namespace) won't be added to it when it's serialised. If you need refreshing on how namespaces work, have a look at http://www.jclark.com/xml/xmlns.htm From Neil C. Obremski -
Thanks for sharing the fixed code, is what i have need
-
Is there a way to do the same thing...but using the XmlNamespaceManager somehow instead of the code shown above?
From the0ther
0 comments:
Post a Comment