XML 序列化期间忽略属性 XmlNamespaceDeclarations
Attribute XmlNamespaceDeclarations is ignored during XML serialization
我尝试用自定义命名空间序列化一个对象。这是 class 的样子:
[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 属性:
<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)
进行序列化时,结果是正确的。
为什么序列化程序会忽略 XmlNamespaceDeclarations
属性?它不应该自动从中获取名称空间声明吗?如何在序列化 class 中定义命名空间?
提前致谢!
您将无法对您的序列化 class 执行任何特殊操作 - 这是一个已知问题。这里提出了各种解决方法:
XmlSerializer: remove unnecessary xsi and xsd namespaces
How to serialize an object to XML without getting xmlns="..."?
xml serialization - remove namespace
Why does serializer ignore that XmlNamespaceDeclarations attribute?
Shouldn't it automatically take the namespace declarations from it?
实际上,Serializer
所做的是 而不是 忽略 你的 XmlNamespaceDeclarations
但 将 它们添加到默认的内部 XmlWriter namespaces
中。
默认情况下,XmlWriter
中已经嵌入了一些 prefixes-namespaces pairs
(或者为了简单起见,我会简单地调用 namespaces
以简化此答案的其余部分)。他们就是你所看到的:
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" //note the lovely pairs here
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
因此,如果您使用 XmlWriter
,您必须忍受它的 default namespaces
,不幸的是,它不会暴露给外部用户。而且,为了让事情变得 "worse"(实际上,并没有那么糟糕,但我试着把它放在上下文中),它以某种方式不允许你用它做任何事情。
唯一与 namespace
有关的 XmlWriter
属性 是 NamespaceHandling,它只能设置为删除 duplicate namespaces
或保留它们。这意味着,属性 只有在您以某种方式 - 相当神奇地 - 为您的 serializable class
:
声明 duplicate namespaces
时才有用
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
尽管如此,XmlWriter
仍然有一些 "good" 可以通过设置省略 XmlDeclaration
的东西:
OmitXmlDeclaration = true;
当您创建 XmlWriterSettings
并使用设置初始化您的 XmlWriter
简而言之,我们不能希望 XmlWriter
通过删除它 default namespaces
来为我们做好事 - 它根本不可能。
因此,我们必须Serializer
得到解决方案
How can I define namespaces inside serialized class?
信不信由你,这和您已经做过的完全一样!
overloading method Serialize(XmlWriter, Object, XmlSerializerNamespaces) 正是为此目的而设计的。当你调用它时:
serializer.Serialize(xmlWriter, obj, obj.Xmlns);
它仅用替换default namespaces + your namespaces
your namespaces
如果您使用 Serialize(XmlWriter, Object)
重载,Serializer
所做的是获取 XmlWriter
和 Object
中的所有 namespaces
然后写入 XML 文件。因此,您在那里获得了所有 namespaces
: 默认值和您的 。
这可能是因为 XmlWriter
也(在内部)将 XmlNamespaceScope 应用为 XmlNamespaceScope.All
,而您再次对此无能为力。
但是当您使用 Serialize(XmlWriter, Object, XmlSerializerNamespaces)
时,您实际上告诉 Serializer
仅使用您指定的 XmlSerializerNamespaces
。所以,它做对了!
换句话说,您所做的已经是在 Xml
文件中获取所需名称空间的 "official" 方法。
除此之外,您还可以根据需要将多个 namespaces
放入 XML 文件,只需使用任意多次 Xmlns.Add(prefix, ns)
。
因此,您已经为您的目的做了正确的事情。我只是想解释为什么会这样。
我尝试用自定义命名空间序列化一个对象。这是 class 的样子:
[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 属性:
<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)
进行序列化时,结果是正确的。
为什么序列化程序会忽略 XmlNamespaceDeclarations
属性?它不应该自动从中获取名称空间声明吗?如何在序列化 class 中定义命名空间?
提前致谢!
您将无法对您的序列化 class 执行任何特殊操作 - 这是一个已知问题。这里提出了各种解决方法:
XmlSerializer: remove unnecessary xsi and xsd namespaces
How to serialize an object to XML without getting xmlns="..."?
xml serialization - remove namespace
Why does serializer ignore that XmlNamespaceDeclarations attribute? Shouldn't it automatically take the namespace declarations from it?
实际上,Serializer
所做的是 而不是 忽略 你的 XmlNamespaceDeclarations
但 将 它们添加到默认的内部 XmlWriter namespaces
中。
默认情况下,XmlWriter
中已经嵌入了一些 prefixes-namespaces pairs
(或者为了简单起见,我会简单地调用 namespaces
以简化此答案的其余部分)。他们就是你所看到的:
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" //note the lovely pairs here
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
因此,如果您使用 XmlWriter
,您必须忍受它的 default namespaces
,不幸的是,它不会暴露给外部用户。而且,为了让事情变得 "worse"(实际上,并没有那么糟糕,但我试着把它放在上下文中),它以某种方式不允许你用它做任何事情。
唯一与 namespace
有关的 XmlWriter
属性 是 NamespaceHandling,它只能设置为删除 duplicate namespaces
或保留它们。这意味着,属性 只有在您以某种方式 - 相当神奇地 - 为您的 serializable class
:
duplicate namespaces
时才有用
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
尽管如此,XmlWriter
仍然有一些 "good" 可以通过设置省略 XmlDeclaration
的东西:
OmitXmlDeclaration = true;
当您创建 XmlWriterSettings
并使用设置初始化您的 XmlWriter
简而言之,我们不能希望 XmlWriter
通过删除它 default namespaces
来为我们做好事 - 它根本不可能。
因此,我们必须Serializer
得到解决方案
How can I define namespaces inside serialized class?
信不信由你,这和您已经做过的完全一样!
overloading method Serialize(XmlWriter, Object, XmlSerializerNamespaces) 正是为此目的而设计的。当你调用它时:
serializer.Serialize(xmlWriter, obj, obj.Xmlns);
它仅用替换default namespaces + your namespaces
your namespaces
如果您使用 Serialize(XmlWriter, Object)
重载,Serializer
所做的是获取 XmlWriter
和 Object
中的所有 namespaces
然后写入 XML 文件。因此,您在那里获得了所有 namespaces
: 默认值和您的 。
这可能是因为 XmlWriter
也(在内部)将 XmlNamespaceScope 应用为 XmlNamespaceScope.All
,而您再次对此无能为力。
但是当您使用 Serialize(XmlWriter, Object, XmlSerializerNamespaces)
时,您实际上告诉 Serializer
仅使用您指定的 XmlSerializerNamespaces
。所以,它做对了!
换句话说,您所做的已经是在 Xml
文件中获取所需名称空间的 "official" 方法。
除此之外,您还可以根据需要将多个 namespaces
放入 XML 文件,只需使用任意多次 Xmlns.Add(prefix, ns)
。
因此,您已经为您的目的做了正确的事情。我只是想解释为什么会这样。