我尝试使用自定义 namespace 序列化对象。这是该类的样子:
[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
属性?它不应该自动从中获取 namespace 声明吗?如何在序列化类中定义 namespace ?提前致谢!
最佳答案
实际上,Serializer
的作用是而不是而不是忽略您的XmlNamespaceDeclarations
,而是将它们添加到默认的内部XmlWriter namespaces
中。
默认情况下,prefixes-namespaces pairs
中已经嵌入了一些namespaces
(或者为简单起见,我会简单地称呼XmlWriter
)。它们是您所看到的:
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
,但不幸的是,该XmlWriter
不会暴露给外部用户。而且,为了使事情变得“更糟”(实际上,还没有那么糟,但是我尝试将其放在上下文中),它以某种方式不允许您对此做任何事情。与
namespace
有关的唯一namespaces
属性是NamespaceHandling,只能将其设置为删除重复的duplicate namespaces
或保留它们。这意味着,只有当您以某种方式(相当神奇地)为serializable class
声明了XmlWriter
时,该属性才有任何用处:xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
但是,
XmlDeclaration
仍然具有一些“好”的东西,您可以通过设置以下内容来忽略XmlWriterSettings
:OmitXmlDeclaration = true;
当您创建
XmlWriter
并使用设置初始化XmlWriter
时简而言之,我们不能希望
default namespaces
通过删除其Serializer
对我们有所作为-简直是做不到。因此,我们必须对
default namespaces + your namespaces
进行求解信不信由你,这就像你已经做过的一样!
overloading方法Serialize(XmlWriter, Object, XmlSerializerNamespaces)就是为此目的而设计的。调用时:
serializer.Serialize(xmlWriter, obj, obj.Xmlns);
它将
your namespaces
替换为Serialize(XmlWriter, Object)
如果使用
Serializer
重载,那么namespaces
要做的是将XmlWriter
和Object
中的所有namespaces
都接受,然后编写XML文件。因此,您在那里获得了所有的XmlWriter
:默认的和您的。这可能是因为
XmlNamespaceScope.All
也(内部)将XmlNamespaceScope用作Serialize(XmlWriter, Object, XmlSerializerNamespaces)
,您-再次-对此无能为力。但是,当您使用
Serializer
时,实际上是告诉XmlSerializerNamespaces
仅使用您指定的Xml
。因此,它做对了!换句话说,您所做的已经是一种在
namespaces
文件中获取所需 namespace 的“官方”方法。除了该注释之外,您还可以根据需要将多个
Xmlns.Add(prefix, ns)
放入您的XML文件中,只需简单地使用所需的ojit_code次数即可。因此,您已经针对自己的目的做了正确的事情。我只是试图解释为什么会这样。
关于c# - XML序列化期间将忽略属性XmlNamespaceDeclarations,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/35417590/