如何防止.NET的XmlDocument的输出中的空白xmlns属性?

当从.NET中的XmlDocument生成XML时,第一次插入一个没有关联名称空间的元素时会出现一个空的xmlns属性; 这怎么能防止?

例:

 XmlDocument xml = new XmlDocument(); xml.AppendChild(xml.CreateElement("root", "whatever:name-space-1.0")); xml.DocumentElement.AppendChild(xml.CreateElement("loner")); Console.WriteLine(xml.OuterXml); 

输出:

 <root xmlns="whatever:name-space-1.0"><loner xmlns="" /></root> 

期望的输出:

 <root xmlns="whatever:name-space-1.0"><loner /></root> 

是否有适用于XmlDocument代码的解决scheme,而不是将文档转换为使用OuterXml的string之后发生的OuterXml

我这样做的理由是看我是否可以使用XmlDocument生成的XML匹配特定协议的标准XML。 空白的xmlns属性可能不会破坏或混淆parsing器,但它也没有出现在我看到这个协议的任何用法。

感谢Jeremy Lew的回答和更多的玩耍,我想出了如何去除空白的xmlns属性:在创build任何你不想在前缀上的子节点时,传入根节点的名字空间。 在根目录下使用没有前缀的命名空间意味着你需要在子元素上使用同样的命名空间,以使它们没有前缀。

固定代码:

 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); 

谢谢大家的所有答案,使我朝着正确的方向前进!

这是JeniT答案的一个变种(非常感谢你btw!)

 XmlElement new_element = doc.CreateElement("Foo", doc.DocumentElement.NamespaceURI); 

这消除了无处不在复制或重复命名空间。

如果示例XML中的<loner>元素没有xmlns默认名称空间声明,那么它将位于whatever:name-space-1.0命名空间中,而不是不在命名空间中。 如果这是你想要的,你需要在该命名空间中创build该元素:

 xml.CreateElement("loner", "whatever:name-space-1.0") 

如果您希望<loner>元素不在名称空间中,那么生成的XML正是您所需要的,您不必担心为您自动添加的xmlns属性。

由于root位于一个没有前缀的命名空间中,所以想要取消命名空间的根子的任何子都必须像你的例子一样输出。 解决方法是像这样在根元素的前面:

 <w:root xmlns:w="whatever:name-space-1.0"> <loner/> </w:root> 

码:

 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); 

如果可能的话,创build一个序列化类然后做:

 XmlSerializerNamespaces ns = new XmlSerializerNamespaces(); ns.Add("", ""); XmlSerializer serializer = new XmlSerializer(yourType); serializer.Serialize(xmlTextWriter, someObject, ns); 

这是更安全的,如果你真的需要更多的控制,你可以控制名称空间的属性。

我已经通过使用工厂模式解决了这个问题。 我为XElement对象创build了一个工厂。 作为工厂实例化的参数,我已经指定了一个XNamespace对象。 因此,每当工厂创buildXElement时,名称空间将自动添加。 这是工厂的代码:

 internal class XElementFactory { private readonly XNamespace currentNs; public XElementFactory(XNamespace ns) { this.currentNs = ns; } internal XElement CreateXElement(String name, params object[] content) { return new XElement(currentNs + name, content); } } 

是的,您可以阻止来自XmlElement的XMLNS。 首先创build时间即将到来:就像那样

 <trkpt lat="30.53597" lon="-97.753324" xmlns=""> <ele>249.118774</ele> <time>2006-05-05T14:34:44Z</time> </trkpt> 

更改代码:并像这样传递xml命名空间

C#代码:

 XmlElement bookElement = xdoc.CreateElement("trkpt", "http://www.topografix.com/GPX/1/1"); bookElement.SetAttribute("lat", "30.53597"); bookElement.SetAttribute("lon", "97.753324");