以下数据合约:
[DataContract(Namespace = "http://namespace", Name = "Blarg")]
public class Blarg
{
[XmlAttribute("Attribute")]
public string Attribute{ get; set; }
[DataMember(Name = "Record", IsRequired = false, Order = 4)]
public List<Record> Record{ get; set; }
}
序列化为:
<Blarg Attribute="blah">
<Record>
<Record/>
<Record/>
<Record/>
</Record>
</Blarg>
但我想要这个:
<Blarg>
<Record/>
<Record/>
<Record/>
<Blarg/>
DataContractSerializer 似乎会自动插入标头父级,但我不想要它。
如何去除包装纸
<Record>
?
我认为你做不到。
DataContractSerializer
针对速度进行了优化,但在此过程中它牺牲了一些灵活性和一些功能(如 XML 属性)。我认为你没有太多机会影响 DCS——它会按照它认为合适的方式、尽快地完成它的工作。您可以非常整齐地定义 what 来序列化(使用 [DataMember]
属性,但您实际上对 how 来序列化没有发言权。
如果您需要更多控制,您可以选择
XmlSerializer
- 在这种情况下,序列化速度会慢 10-15%,但您可以控制数据形状等。但即使在这种情况下 - 我也是不知道有什么方法可以告诉 XML 序列化器将集合序列化为一系列 XML 标签,而无需集合的封闭标签。
DataContract
对象序列化包装元素内集合属性的项目。但是,您可以通过创建一个实现
IXmlSerializable
和
WriteXml
方法的类来生成所需的 XML。这是您提供的示例的代码:
public class Blarg : IXmlSerializable
{
public string Attribute { get; set; }
public List<Record> Records { get; set; }
public XmlSchema GetSchema()
{
return null;
}
public void ReadXml(XmlReader reader)
{
throw new System.NotImplementedException();
}
public void WriteXml(XmlWriter writer)
{
writer.WriteStartElement(nameof(Blarg), "http://namespace");
writer.WriteAttributeString(nameof(Attribute), Attribute);
DataContractSerializer recordSerializer = new DataContractSerializer(typeof(Record));
foreach (Record rec in Records)
{
recordSerializer.WriteObject(writer, rec);
}
writer.WriteEndElement();
}
}
即使 Blarg
不是
DataContract
类,它也可以包含
DataContract
类的对象属性,例如
Record
,以便可以使用
WriteXml
实例在
DataContractSerializer
内序列化它们。如果您需要一个也实现
IXmlSerializable
的属性,则需要通过在包含类的
WriteXml
中调用其自己的
WriteXml
方法来序列化它。