使用多个可能的内部元素序列化 XML
Serializing XML with multiple possible inner elements
我无法弄清楚如何为 serializing/deserializing XML 构建和配置 class 结构,例如 .Net 中的这个:
<OuterElem>
<InnerElem>
<C1>...</C1>
</InnerElem>
</OuterElem>
一些注意事项:
- C1 是复杂类型。
- 也可以有 C2、C3 等不同的复杂类型。
- 可以同时存在一个或多个 Cx 元素。
- OuterElem 和 InnerElem 来自与 Cx 元素不同的命名空间。
- 在运行时(实际上是编译时),可能的 Cx 元素的完整集合在当前用例中是众所周知的,但是包装元素是通用解决方案的一部分,因此最好它们不应依赖或了解 Cx 元素.
这是我目前拥有的:
[XmlRoot(Namespace = "urn:outer-ns")]
public class OuterElem
{
public object[] InnerElem { get; set; }
}
[XmlRoot(ElementName = "C1", Namespace = "urn:ns1")]
public class C1 { }
[XmlRoot(ElementName = "C2", Namespace = "urn:ns1")]
public class C2 { }
但这并没有给我想要的。序列化:
var xs = new XmlSerializer (typeof(OuterElem),
new [] {typeof(C1), typeof(C2)});
var s = new StringWriter();
xs.Serialize (s, outerElemInstance);
产量 XML 为:
<?xml version="1.0" encoding="utf-16"?>
<OuterElem>
<Body>
<anyType xmlns:q1="urn:ns1" xsi:type="q1:C1">
如何让它使用元素名称 C1 而不是这个 anyType
?
对于此用例,通常 InnerElem 必须使用 XmlElement 属性进行修饰,如下所示:
public class OuterElem
{
[XmlElement(typeof(C1))]
[XmlElement(typeof(C2))]
public object[] InnerElem { get; set; }
}
然而,正如您所提到的,您正在开发一个不依赖于 C1/C2... 类型的通用解决方案,一种可能的解决方案是通过 XmlAttributeOverrides[= 添加这些属性13=]
XmlAttributeOverrides overrides = new XmlAttributeOverrides();
XmlAttributes attribs = new XmlAttributes();
attribs.XmlIgnore = false;
attribs.XmlElements.Add(new XmlElementAttribute(typeof(C1)));
attribs.XmlElements.Add(new XmlElementAttribute(typeof(C2)));
overrides.Add(typeof(OuterElem), "InnerElem", attribs);
var xs = new XmlSerializer(typeof(OuterElem), overrides, new [] {typeof(C1), typeof(C2)}, null, null);
var s = new StringWriter();
xs.Serialize(s, outerElemInstance);
我无法弄清楚如何为 serializing/deserializing XML 构建和配置 class 结构,例如 .Net 中的这个:
<OuterElem>
<InnerElem>
<C1>...</C1>
</InnerElem>
</OuterElem>
一些注意事项:
- C1 是复杂类型。
- 也可以有 C2、C3 等不同的复杂类型。
- 可以同时存在一个或多个 Cx 元素。
- OuterElem 和 InnerElem 来自与 Cx 元素不同的命名空间。
- 在运行时(实际上是编译时),可能的 Cx 元素的完整集合在当前用例中是众所周知的,但是包装元素是通用解决方案的一部分,因此最好它们不应依赖或了解 Cx 元素.
这是我目前拥有的:
[XmlRoot(Namespace = "urn:outer-ns")]
public class OuterElem
{
public object[] InnerElem { get; set; }
}
[XmlRoot(ElementName = "C1", Namespace = "urn:ns1")]
public class C1 { }
[XmlRoot(ElementName = "C2", Namespace = "urn:ns1")]
public class C2 { }
但这并没有给我想要的。序列化:
var xs = new XmlSerializer (typeof(OuterElem),
new [] {typeof(C1), typeof(C2)});
var s = new StringWriter();
xs.Serialize (s, outerElemInstance);
产量 XML 为:
<?xml version="1.0" encoding="utf-16"?>
<OuterElem>
<Body>
<anyType xmlns:q1="urn:ns1" xsi:type="q1:C1">
如何让它使用元素名称 C1 而不是这个 anyType
?
对于此用例,通常 InnerElem 必须使用 XmlElement 属性进行修饰,如下所示:
public class OuterElem
{
[XmlElement(typeof(C1))]
[XmlElement(typeof(C2))]
public object[] InnerElem { get; set; }
}
然而,正如您所提到的,您正在开发一个不依赖于 C1/C2... 类型的通用解决方案,一种可能的解决方案是通过 XmlAttributeOverrides[= 添加这些属性13=]
XmlAttributeOverrides overrides = new XmlAttributeOverrides();
XmlAttributes attribs = new XmlAttributes();
attribs.XmlIgnore = false;
attribs.XmlElements.Add(new XmlElementAttribute(typeof(C1)));
attribs.XmlElements.Add(new XmlElementAttribute(typeof(C2)));
overrides.Add(typeof(OuterElem), "InnerElem", attribs);
var xs = new XmlSerializer(typeof(OuterElem), overrides, new [] {typeof(C1), typeof(C2)}, null, null);
var s = new StringWriter();
xs.Serialize(s, outerElemInstance);