XML序列化期间将忽略属性XmlNamespaceDeclarations

时间:2016-02-15 19:33:04

标签: c# xml serialization xml-namespaces

我尝试使用自定义命名空间序列化对象。这就是班级的样子:

[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属性?它不应该自动从中获取命名空间声明吗?如何在序列化类中定义名称空间?

提前致谢!

2 个答案:

答案 0 :(得分:5)

  

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

实际上,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未向外部用户公开。并且,为了使事情更糟糕&#34; (实际上,并没有那么糟糕,但我试着把它放在上下文中),它不知何故不允许你用它做任何事情。

namespaces有关的唯一duplicate namespaces属性为NamespaceHandling,只能将其设置为删除重复 serializable class或保留它们。这意味着,如果您以某种方式 - 相当神奇地 - 为您的xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" 声明XmlWriter,该属性将会有用:

XmlDeclaration

然而,OmitXmlDeclaration = true; 仍然有一些&#34;好&#34;您可以通过设置忽略XmlWriterSettings的内容:

XmlWriter

创建XmlWriter并使用设置初始化default namespaces

简而言之,我们不能希望Serializer通过删除serializer.Serialize(xmlWriter, obj, obj.Xmlns); 来为我们做好事 - 它根本无法做到。

因此,我们必须到default namespaces + your namespaces获得解决方案

  

如何在序列化类中定义命名空间?

信不信由你,就像你已经做过的那样

overloading方法Serialize(XmlWriter, Object, XmlSerializerNamespaces)专为此目的而设计。当你打电话时:

your namespaces

仅用替换 Serialize(XmlWriter, Object) Serializer

如果您使用namespaces重载,则XmlWriter执行的操作是Object以及namespaces中的所有XmlWriter,然后写XML文件。因此,您获得了所有XmlNamespaceScope.All默认值和您的

这可能是因为Serialize(XmlWriter, Object, XmlSerializerNamespaces)也(内部)将XmlNamespaceScope应用为Serializer,您再次对此无能为力。

但是当您使用XmlSerializerNamespaces时,实际上是告诉Xml仅使用您指定的namespaces。所以,它做对了!

换句话说,你所做的就是&#34;官方&#34;在Xmlns.Add(prefix, ns)文件中获取所需命名空间的方法。

除此之外,您还可以根据需要将多个git commit -m "All Files with cache and session Directories"添加到XML文件中,只需使用git push origin master次。{/ p>

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

答案 1 :(得分:0)

你无法对序列化的类做任何特殊的事情 - 这是一个已知的问题。这里提出了各种解决方法:

XmlSerializer: remove unnecessary xsi and xsd namespaces

How to serialize an object to XML without getting xmlns="..."?

xml serialization - remove namespace

相关问题