我有一个List,其中填充了子类BaseType
的各种具体类型的对象我正在使用WCF DataContractSerializer
<Children>
<BaseType xmlns:d3p1="http://schemas.datacontract.org/2004/07/Tasks"
i:type="d3p1:ConcreteTypeA"></BaseType>
<BaseType xmlns:d3p1="http://schemas.datacontract.org/2004/07/Tasks"
i:type="d3p1:ConcreteTypeB"></BaseType>
</Children>
有没有办法让它生成
<Children>
<ConcreteTypeA/>
<ConcreteTypeB/>
</Children>
真正的目标是让用户生成一些XML以加载到内存中,并且用户具有技能水平,要求他们提供原始XML并不会成功。
答案 0 :(得分:7)
DataContractSerializer并非旨在让您控制输出。它被设计为快速,隐式,并且易于使用。
来定义类你想要的是XmlSerializer。这使您可以更好地控制XML输出。
请注意,在我下面的示例中,我指定了很多可以从属性名称中推断出来的东西,但只是为了让您感觉可以在属性中覆盖它们。事实上,我认为如果删除了所有属性并且应用了一些KnownTypeAttributes但我还没有测试它,那么整个类将序列化很好。我不知道这是否会为您提供您描述的确切XML(它将在Children之上创建一个根元素),但希望这会让您朝着正确的方向前进。
Attributes That Control XML Serialization
[XmlRoot(Namespace="")]
public class MyClass {
[XmlArray("Children")]
[XmlArrayItem("ConcreteTypeA", typeof(ConcreteTypeA))]
[XmlArrayItem("ConcreteTypeB", typeof(ConcreteTypeB))]
public BaseType[] Children {
get;
set;
}
}
public class BaseType {
}
public class ConcreteTypeA : BaseType {
}
public class ConcreteTypeB : BaseType {
}
编辑:我刚刚测试过它产生的东西非常接近你想要的东西。
void Main()
{
var mc = new MyClass();
mc.Children = new BaseType[] {
new ConcreteTypeA(),
new ConcreteTypeB(),
new ConcreteTypeA(),
new ConcreteTypeB()
};
var serializer = new XmlSerializer(typeof(MyClass));
using ( var str = new StringWriter() ) {
serializer.Serialize(str, mc);
str.ToString().Dump();
}
}
...生成......(从顶部删除无用的xmlns)
<MyClass>
<Children>
<ConcreteTypeA />
<ConcreteTypeB />
<ConcreteTypeA />
<ConcreteTypeB />
</Children>
</MyClass>