如何防止从.NET的XmlDocument输出的空白xmlns属性?
时间:2020-03-06 14:44:21 来源:igfitidea点击:
从.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
代码的解决方案,而不是使用OuterXml
将文档转换为字符串后出现的解决方案?
我这样做的理由是看我是否可以使用XmlDocument生成的XML匹配特定协议的标准XML。空白的xmlns属性可能不会破坏或者混淆解析器,但在我对该协议所见的任何用法中,它都不存在。
解决方案
如果示例XML中的<loner>元素上没有默认的xmlns命名空间声明,则它将位于whatever:name-space-1.0命名空间中,而不是没有命名空间中。如果这是我们想要的,则需要在该命名空间中创建元素:
xml.CreateElement("loner", "whatever:name-space-1.0")
如果我们希望元素中没有<loner>元素,那么所生成的XML正是我们所需要的,并且我们不必担心为我们自动添加的xmlns属性。
由于root是在无前缀的命名空间中,因此必须像示例一样输出要取消命名空间的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);
如果可能,创建一个序列化类,然后执行以下操作:
XmlSerializerNamespaces ns = new XmlSerializerNamespaces(); ns.Add("", ""); XmlSerializer serializer = new XmlSerializer(yourType); serializer.Serialize(xmlTextWriter, someObject, ns);
这样比较安全,如果确实需要更多控制,则可以使用属性来控制名称空间。
感谢Jeremy Lew的回答和更多的玩味,我弄清楚了如何删除空白的xmlns属性:在创建任何不希望有前缀的子节点时,传递根节点的名称空间。在根目录使用没有前缀的名称空间意味着我们需要在子元素上使用相同的名称空间,以便它们也没有前缀。
固定代码:
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);
感谢大家对所有回答,这些回答使我朝着正确的方向前进!