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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/135000/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-03 15:00:40  来源:igfitidea点击:

How to prevent blank xmlns attributes in output from .NET's XmlDocument?

提问by Neil C. Obremski

When generating XML from XmlDocument in .NET, a blank xmlnsattribute appears the first time an element withoutan associated namespace is inserted; how can this be prevented?

在.NET 中从XmlDocument 生成XML 时,xmlns第一次插入没有关联命名空间的元素时会出现空白属性;如何防止这种情况发生?

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>

DesiredOutput:

期望输出:

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

Is there a solution applicable to the XmlDocumentcode, not something that occurs afterconverting the document to a string with OuterXml?

是否有适用于XmlDocument代码的解决方案,而不是将文档转换为字符串发生的事情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 xmlnsattribute maynot break or confuse a parser, but it's also not present in any usage that I've seen of this protocol.

我这样做的原因是看看我是否可以使用 XmlDocument 生成的 XML 匹配特定协议的标准 XML。空白xmlns属性可能不会破坏或混淆解析器,但它也没有出现在我见过的该协议的任何用法中。

采纳答案by Neil C. Obremski

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 notto 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 alsonot have prefixes.

由于杰里米Lew的答案,并多一点玩耍,我想出如何删除空白xmlns属性:创建任何你想要的子节点时,通过根节点的命名空间并不会对前缀。在根使用没有前缀的命名空间意味着您需要在子元素上使用相同的命名空间,以便它们没有前缀。

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!

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

回答by JeniT

If the <loner>element in your sample XML didn't have the xmlnsdefault namespace declaration on it, then it would be in the whatever: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:

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

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 the xmlnsattribute that's been added automatically for you.

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

回答by jlew

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:

由于 root 位于不带前缀的命名空间中,因此任何想要取消命名空间的 root 子项都必须像您的示例一样输出。解决方案是为根元素添加前缀,如下所示:

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

回答by ilitirit

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.

它更安全,如果您确实需要更多控制,您可以使用属性来控制命名空间。

回答by brinke

I've solved the problem by using the Factory Pattern. I created a factory for XElement objects. As parameter for the instantiation of the factory I've specified a XNamespace object. So, everytime a XElement is created by the factory the namespace will be added automatically. Here is the code of the factory:

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

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

回答by C Johnson

This is a variant of JeniT's answer (Thank you very very much btw!)

这是 JeniT 答案的一个变体(顺便说一句,非常感谢!)

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

This eliminates having to copy or repeat the namespace everywhere.

这消除了必须在任何地方复制或重复命名空间。

回答by Debabrata Ghosh

Yes you can prevent the XMLNS from the XmlElement . First Creating time it is coming : like that

是的,您可以从 XmlElement 阻止 XMLNS。第一个创造时间即将到来:就像那样

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

Change the code : And pass xml namespace like this

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

C# code:

C#代码:

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