本文介绍了XML序列化期间将忽略属性XmlNamespaceDeclarations的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我尝试使用自定义名称空间序列化对象.这是该类的样子:

I try to serialize an object with custom namespaces. This is how the class looks like:

[XmlRoot("Root", Namespace = "myNamespace")]
public partial class MyClass
{
    public MyClass()
    {
        this.Xmlns = new XmlSerializerNamespaces();
        this.Xmlns.Add(string.Empty, "myNamespace");
    }

    [XmlNamespaceDeclarations()]
    public XmlSerializerNamespaces Xmlns = null;
}

这是序列化它的代码:

XmlSerializer serializer = new XmlSerializer(typeof(MyClass));
serializer.Serialize(xmlWriter, obj);

预期结果是

<Root xmlns="myNamespace" />

但是它仍然具有xmlns:xsi和xmlns:xsd属性:

However it still has xmlns:xsi and xmlns:xsd attributes:

<Root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="myNamespace" />

当我使用 serializer.Serialize(xmlWriter,obj,obj.Xmlns)进行序列化时,结果是正确的.

When I serialize using serializer.Serialize(xmlWriter, obj, obj.Xmlns), the result is correct.

为什么序列化程序会忽略该 XmlNamespaceDeclarations 属性?它不应该自动从中获取名称空间声明吗?如何在序列化类中定义名称空间?

Why does serializer ignore that XmlNamespaceDeclarations attribute? Shouldn't it automatically take the namespace declarations from it? How can I define namespaces inside serialized class?

提前谢谢!

推荐答案

实际上,序列化器的作用是 忽略您的 XmlNamespaceDeclarations ,而是添加>将它们添加到默认的内部 XmlWriter名称空间.

Actually, what the Serializer does is not ignoring your XmlNamespaceDeclarations but adding them into the default, internal, XmlWriter namespaces.

默认情况下,在中已经嵌入了一些 prefixes-namespaces 对(或者为简单起见,我将简单地称为 namespaces ).XmlWriter .它们就是您所看到的:

By default, there are already some prefixes-namespaces pairs (or I would simply call namespaces for simplicity for the rests of this answer) embedded to the XmlWriter. They are what you see:

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" //note the lovely pairs here
xmlns:xsd="http://www.w3.org/2001/XMLSchema"

因此,如果使用 XmlWriter ,则必须忍受其默认命名空间,不幸的是,这些命名空间不会暴露给外部用户.而且,为了使事情更糟"(实际上,还没有那么糟,但是我尝试将其放在上下文中),它某种程度上不允许您对此做任何事情.

Thus, if you use XmlWriter, you got to bear with its default namespaces which unfortunately are not exposed to the outside user. And, to make things "worse" (actually, not that worse, but I try to put this in context), it somehow does not allow you to do anything with it.

namespace 有关的唯一 XmlWriter 属性是 NamespaceHandling ,只能设置为删除 duplicate namespaces 或保留它们.这意味着,仅当您以某种方式-神奇地-为您的 serializable class 可序列化的类声明了 duplicate名称空间时,该属性才有任何用处:

The only XmlWriter property that got something to do with namespace is NamespaceHandling, which can only be set to either removing duplicate namespaces or retaining them. Which means, the property would only be of any use if you have somehow - rather magically - declared duplicate namespaces for your serializable class:

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"

尽管如此, XmlWriter 仍然具有一些好"的东西,您可以通过设置以下内容来省略 XmlDeclaration :

Nevertheless, XmlWriter still have some "good" things that you can omit the XmlDeclaration by setting:

OmitXmlDeclaration = true;

在创建 XmlWriterSettings 并使用设置初始化 XmlWriter

when you create your XmlWriterSettings and use the settings to initialize your XmlWriter

简而言之,我们不能希望 XmlWriter 通过删除其默认名称空间对我们做些好事-根本做不到.

In short, we cannot hope XmlWriter to do good things to us by removing its default namespaces - it simply can't.

因此,我们必须转到 Serializer 以获得解决方案

And thus, we must to the Serializer to get the solution

信不信由你,它就像你已经做过的一样!

Believe it or not, it is exactly like what you already did!

重载方法序列化(XmlWriter,Object,XmlSerializerNamespaces)就是为此目的而设计的.呼叫时:

The overloading method Serialize(XmlWriter, Object, XmlSerializerNamespaces) is designed just for that purpose. When you call it:

serializer.Serialize(xmlWriter, obj, obj.Xmlns);

默认命名空间+您的命名空间替换为 您的命名空间

如果使用 Serialize(XmlWriter,Object)重载, Serializer 所做的就是获取中的所有命名空间XmlWriter 以及 Object 中,然后写入XML文件.因此,您在那里找到了所有命名空间:默认名称和您的.

If you use Serialize(XmlWriter, Object) overload, what the Serializer does is to take all the namespaces in the XmlWriter as well as in the Object and then write XML file. Thus you got all the namespaces there: the default and yours.

这可能是因为 XmlWriter 也(内部)应用了 XmlNamespaceScope 称为 XmlNamespaceScope.All ,您-再也不能对此做任何事情.

This is probably because XmlWriter also (internally) apply XmlNamespaceScope to be XmlNamespaceScope.All which you - again - can do nothing about it.

但是,当您使用 Serialize(XmlWriter,Object,XmlSerializerNamespaces)时,您实际上告诉 Serializer 仅使用指定的 XmlSerializerNamespaces .因此,它做对了!

But when you use Serialize(XmlWriter, Object, XmlSerializerNamespaces), you actually tell the Serializer to only use XmlSerializerNamespaces that you specify. And so, it does the right thing!

换句话说,您所做的已经是在 Xml 文件中获取所需名称空间的一种正式"方式.

In other words, what you did is already an "official" way for getting the namespaces that you want in the Xml file.

除了那条注释,您还可以根据需要通过简单地使用多次 Xmlns.Add(prefix,ns)来将多个命名空间放入XML文件中想要.

That note aside, you could also put multiple namespaces to your XML file as you wish by simply using as many times Xmlns.Add(prefix, ns) as you want.

因此,您已经为自己的目的做了正确的事情.我只是想解释为什么会这样.

Thus, you already did the right thing for your purpose. I merely trying to explain why it is so.

这篇关于XML序列化期间将忽略属性XmlNamespaceDeclarations的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-02 10:36