XML 序列化命名空间
本文关键字:命名空间 序列化 XML | 更新日期: 2023-09-27 18:34:27
我的代码生成的命名空间有问题。我想要的是下面的XML:
<?xml version="1.0" encoding="utf-8"?>
<ClassToSerialize Type="Customer" Name="Some Name" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.123.org/namespace C:'Schema'ClassToSerialize.xsd"
xmlns:Test="http://www.Test.org/" xmlns="http://www.nrf-arts.org/namespace">
<Address>
<Line1>Addr1</Line1>
<Line2>Addr2</Line2>
</Address>
</ClassToSerialize>
我得到的是这个XML:
<?xml version="1.0" encoding="utf-8"?>
<ClassToSerialize xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:schemaLocation="http://www.123.org/namespace C:'Schema'ClassToSerialize.xsd"
xmlns:Test="http://www.Test.org/" xmlns:xmlns="http://www.nrf-arts.org/namespace" Type="Customer" Name="Some Name">
<Address>
<Line1>Addr1</Line1>
<Line2>Addr2</Line2>
</Address>
</ClassToSerialize>
主要区别是:
1. xmlns:schemaLocation= needs to be xsi:schemaLocation=
2. xmlns:xmlns= needs to be xmlns=
3. Attributes Order, I would prefer the Attributes to be presented before the namespace attributes (This is not a big Issue, just nice to have)
目前我正在做的是将上面 1 和 2 中的序列化字符串中的值替换为我想要的值,这是一个有效的黑客,但我怀疑有一种方法可以修改命名空间代码来做到这一点?
这是我正在使用的代码,我如何更改 GetNameSpace() 以执行第 1 点和第 2 点中我需要的操作,我还可以重新排序属性吗?
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
ClassToSerialize myInstance = new ClassToSerialize();
myInstance.Type = "Customer";
myInstance.Name = "Some Name";
myInstance.AddressField = new Address("Addr1", "Addr2");
String sString = SerializeObject<ClassToSerialize>(myInstance, GetNameSpace());
//Hack to achieve what I want from namespaces
sString = sString.Replace("xmlns:schemaLocation=", "xsi:schemaLocation=");
sString = sString.Replace("xmlns:xmlns=", "xmlns=");
}
private XmlSerializerNamespaces GetNameSpace()
{
XmlSerializerNamespaces xsNS = new XmlSerializerNamespaces();
xsNS.Add("xsi", "http://www.w3.org/2001/XMLSchema-instance");
xsNS.Add("xmlns", "http://www.nrf-arts.org/namespace");
xsNS.Add("schemaLocation", "http://www.123.org/namespace C:''Schema''ClassToSerialize.xsd");
xsNS.Add("Test", "http://www.Test.org/");
return xsNS;
}
public static string SerializeObject<X>(X toSerialize, XmlSerializerNamespaces xmlNameSpace)
{
string strRetVal = "";
try
{
XmlSerializer xmlSerializer = new XmlSerializer(toSerialize.GetType());
StringWriter textWriter = new StringWriter();
using (StringWriter writer = new Utf8StringWriter())
{
xmlSerializer.Serialize(writer, toSerialize, xmlNameSpace);
strRetVal = writer.ToString();
}
}
catch (Exception ex)
{
string strError = ex.ToString();
}
return strRetVal;
}
}
public class Utf8StringWriter : StringWriter
{
public override Encoding Encoding
{
get { return Encoding.UTF8; }
}
}
public class ClassToSerialize
{
[XmlAttribute()]
public string Type { get; set; }
[XmlAttribute()]
public string Name { get; set; }
[XmlElement("Address")]
public Address AddressField { get; set; }
}
public class Address
{
[XmlElement, DefaultValue("")]
public string Line1 { get; set; }
[XmlElement, DefaultValue("")]
public string Line2 { get; set; }
public Address()
{
}
public Address(string L1, string L2)
{
Line1 = L1;
Line2 = L2;
}
}
-
可以通过按照如何将 xsi 架构位置添加到根 c # 对象 XmlSerializer 中的答案行添加合成属性来添加
xsi:schemaLocation
- 但使用属性而不是字段。 如果使用字段,则实际上会增加类在内存中的占用空间。 -
要定义默认命名空间
xmlns="http://www.nrf-arts.org/namespace"
,您可以将[XmlRoot("ClassToSerialize", Namespace="http://www.nrf-arts.org/namespace")]
应用于ClassToSerialize
或分配XmlRootAttribute
覆盖并将其传递给XmlSerializer
构造函数。 如果执行后者,请确保缓存序列化程序。 -
除了实现
IXmlSerializable
有些繁琐之外,我不知道是否可以用XmlSerializer
来控制属性顺序。 但是,XML 规范声明"开始标记或空元素标记中的属性规范顺序并不重要",因此我建议不要担心它。
因此,以下应该可以解决问题。 请注意,我将GetNameSpace()
移到ClassToSerialize
内并将其重命名为GetAdditionalNamespaces()
:
[XmlRoot("ClassToSerialize", Namespace="http://www.nrf-arts.org/namespace")]
public class ClassToSerialize
{
public static XmlSerializerNamespaces GetAdditionalNamespaces()
{
XmlSerializerNamespaces xsNS = new XmlSerializerNamespaces();
xsNS.Add("xsi", "http://www.w3.org/2001/XMLSchema-instance");
xsNS.Add("Test", "http://www.Test.org/");
return xsNS;
}
[XmlAttribute("schemaLocation", Namespace = "http://www.w3.org/2001/XMLSchema-instance")]
public string XSDSchemaLocation
{
get
{
return "http://www.123.org/namespace C:''Schema''ClassToSerialize.xsd";
}
set
{
// Do nothing - fake property.
}
}
[XmlAttribute()]
public string Type { get; set; }
[XmlAttribute()]
public string Name { get; set; }
[XmlElement("Address")]
public Address AddressField { get; set; }
}