我目前正在创建一堆文件,然后应该由另一个程序使用。其中大部分是xml文件。自然地,我从程序中提取了.xsd文件并使用
xsd.exe
自动生成C类的工具,它工作得相当好。
问题
序列化自动生成的类会生成如下XML文件:
<root xmlns="ns1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<group xmlns="">
<item>foo</item>
<item>bar</item>
</group>
</root>
两者
xsi
和
xsd
到目前为止我发现的东西都没用,但那应该不是问题。
程序期望的XML如下所示:
<n1:root xmlns:n1="ns1">
<group>
<item>foo</item>
<item>bar</item>
</group>
</n1:root
两个XML在反序列化时应该导致相同的结果,因此我不会将错误放在xsd.exe上。
但是,当试图在程序中打开生成的XML时,它会产生“对象引用未设置为对象实例”错误。两者
xmlns:xsi
和
xmlns:xsd
必须移除,并且必须使用
xmlns:n1
而不是默认的命名空间。
我试过的
起初我想,我可以使用
IXmlSerializable
,但是在序列化时会产生运行时错误,因为xsd.exe会自动添加
XmlTypeAttribute
和
XmlRootAttribute
是的。
产生的错误读取
InvalidOperationException: Only XmlRoot attribute may be specified for the type myNs.MyClass. Please use XmlSchemaProviderAttribute to specify schema type.
我不认为使用xmlschemaproviderattribute是一个好主意,因为这违背了从给定模式自动生成类的想法。(在程序的未来版本中,模式可能会改变)
如果你想要一个最小的例子,这里有一些运行在
rextester.com
:(注意,rextester使用.net framework 4.5,而我使用的是.netframework4.7,因此任何使用新功能的答案都是非常受欢迎的)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
using System.Xml;
using System.Xml.Schema;
using System.Xml.Serialization;
namespace Rextester
{
// AUTOGENERATED
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.7.2558.0")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(Namespace="http://www.somens.com")]
[System.Xml.Serialization.XmlRootAttribute(Namespace="http://www.somens.com", IsNullable=false)]
public partial class Test {
[System.Xml.Serialization.XmlArrayAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
[System.Xml.Serialization.XmlArrayItemAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified, IsNullable=false)]
public Item[] Group { get; set; }
}
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.7.2558.0")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(Namespace="http://www.somens.com")]
public partial class Item {
[System.Xml.Serialization.XmlAttributeAttribute()]
public int Value { get; set; }
}
// CUSTOM
public partial class Test : IXmlSerializable
{
public XmlSchema GetSchema()
{
return null;
}
public void ReadXml(XmlReader reader)
{
throw new NotImplementedException();
}
public void WriteXml(XmlWriter writer)
{
foreach (var item in Group) {
writer.WriteStartElement("item");
writer.WriteAttributeString("Value", item.Value.ToString());
writer.WriteEndElement();
}
}
}
public class Program
{
public static void Main(string[] args)
{
var t = new Test();
t.Group = new Item[] { new Item { Value = 5}, new Item { Value = 10} };
var serializer = new XmlSerializer(typeof(Test));
serializer.Serialize(Console.Out, t);
}
}
}