Wal*_*mar 3 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;
}
Run Code Online (Sandbox Code Playgroud)
以下是序列化它的代码:
XmlSerializer serializer = new XmlSerializer(typeof(MyClass));
serializer.Serialize(xmlWriter, obj);
Run Code Online (Sandbox Code Playgroud)
预期的结果是
<Root xmlns="myNamespace" />
Run Code Online (Sandbox Code Playgroud)
但是它仍然有xmlns:xsi和xmlns:xsd属性:
<Root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="myNamespace" />
Run Code Online (Sandbox Code Playgroud)
当我序列化使用时serializer.Serialize(xmlWriter, obj, obj.Xmlns),结果是正确的.
为什么序列化程序会忽略该XmlNamespaceDeclarations属性?它不应该自动从它获取命名空间声明吗?如何在序列化类中定义名称空间?
提前致谢!
为什么序列化程序会忽略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"
Run Code Online (Sandbox Code Playgroud)
因此,如果你使用XmlWriter,你必须忍受它default namespaces,不幸的是不暴露给外部用户.而且,为了让事情"变得更糟"(实际上,情况并非如此糟糕,但我试图将其置于上下文中),它不知何故不允许你对它做任何事情.
唯一XmlWriter与之有关的属性namespace是NamespaceHandling,它只能设置为删除重复 namespaces或保留它们.这意味着,如果您以某种方式(相当神奇地)duplicate namespaces为您声明的属性,该属性将只有任何用途serializable class:
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
Run Code Online (Sandbox Code Playgroud)
尽管如此,XmlWriter仍然有一些"好"的东西你可以XmlDeclaration通过设置省略:
OmitXmlDeclaration = true;
Run Code Online (Sandbox Code Playgroud)
当您创建XmlWriterSettings并使用设置初始化您的XmlWriter
简而言之,我们不能希望XmlWriter通过删除它来为我们做好事default namespaces- 它根本不可能.
因此,我们必须Serializer得到解决方案
如何在序列化类中定义名称空间?
信不信由你,它就像你已经做过的一样!
的重载方法序列化(XmlWriter的,对象,XmlSerializerNamespaces)只是用于该目的而设计的.当你打电话时:
serializer.Serialize(xmlWriter, obj, obj.Xmlns);
Run Code Online (Sandbox Code Playgroud)
它取代了default namespaces + your namespaces与只 your namespaces
如果你使用Serialize(XmlWriter,?Object)过载,有什么Serializer做的是采取一切namespaces的XmlWriter,以及在Object然后写XML文件.因此,你得到了所有namespaces:默认和你的.
这可能是因为XmlWriter(内部)将XmlNamespaceScope应用于XmlNamespaceScope.All您 - 再次 - 对此无能为力.
但是当你使用时Serialize(XmlWriter,?Object,?XmlSerializerNamespaces),你实际上告诉你Serializer只使用XmlSerializerNamespaces你指定的.所以,它做对了!
换句话说,您所做的就是获取文件中所需命名空间的"官方"方式Xml.
除此之外,您还可以根据需要将多个数据放入namespacesXML文件中,只需使用多次即可Xmlns.Add(prefix, ns).
因此,您已经为您的目的做了正确的事情.我只想解释为什么会这样.
| 归档时间: |
|
| 查看次数: |
2519 次 |
| 最近记录: |