问题描述
我尝试使用自定义名称空间序列化对象.这是该类的样子:
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的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!