5

我有一系列类,我在 .NET 4.0 中使用 .NET 的 DataContractSerializer 将它们转换为 XML。序列化工作正常,我可以解析 XML 并稍后重新创建 .NET 对象,没有任何困难。

但是,大多数 DataMember 不是必需的。[DataMember(IsRequired = false)]。这对反序列化 XML 非常有效,您可能会错过文档中的 XML 节点,但是当将现有对象序列化为 XML 时,DataContractSerializer 坚持写出具有空值的属性作为具有属性的节点,例如

[DataContract(Name = "response", Namespace = "http://domain.com/name")]
public class MyResponseClass
{
    [DataMember(Name = "count", IsRequired = true, Order = 0)]
    public int Count { get; set; }

    [DataMember(Name = "info", IsRequired = false, Order = 1)]
    public InfoClass Info { get; set; }

    [DataMember(Name = "metadata", IsRequired = false, Order = 2)]
    public MetadataList Metadatas { get; set; }

}

可以从序列化

<response xmlns="http://domain.com/name">
    <count>4</count>
</response>

但是,如果我序列化对象,它会创建:

<response xmlns="http://domain.com/name" xmlns:i="http://www.w3.org/2001/XmlSchema-instance">
    <count>4</count>
    <info i:nil="true" />
    <metadata i:nil="true" />
</response>

当 DataContractSerializer 具有空值时,有没有办法让 DataContractSerializer 不写入节点?

4

2 回答 2

10

用于EmitDefaultValue = false跳过 XML 中的默认值:

[DataContract(Name = "response", Namespace = "http://domain.com/name")]
public class MyResponseClass 
{
    [DataMember(Name = "count", IsRequired = true, Order = 0, EmitDefaultValue = false)]
    public int Count { get; set; }

    [DataMember(Name = "info", IsRequired = false, Order = 1, EmitDefaultValue = false)]
    public InfoClass Info { get; set; }

    [DataMember(Name = "metadata", IsRequired = false, Order = 2, EmitDefaultValue = false)]
    public MetadataList Metadatas { get; set; }
}

要删除xmlns:i="http://www.w3.org/2001/XmlSchema-instance",您必须使用例如Replace()下面的示例

public void Write(string filePath, MyResponseClass myResponse)
{
    var serializer = new DataContractSerializer(typeof(MyResponseClass));

    var sb = new StringBuilder();
    using (var writer = new StringWriter(sb))
    using (var xmlWriter = XmlWriter.Create(writer))
    {
        serializer.WriteObject(xmlWriter, myResponse);
    }

    using (StreamWriter stream = new StreamWriter(filePath))
    {
        sb = sb.Replace(" xmlns:i=\"http://www.w3.org/2001/XMLSchema-instance\"", "");
        stream.Write(sb);
    }
}

带着敬意 :)

于 2013-02-18T10:07:40.567 回答
1

(我不小心在错误的问题中发布了这个答案,但我认为它在这里也很有帮助,所以我暂时不删除它)

[DataContract(Namespace = "")]

在每个类的顶部使它变得更好。它删除了 datacontract 命名空间和丑陋的节点前缀。但是,标准命名空间仍然存在。这对我来说没问题。

前:

<?xml version="1.0" encoding="utf-8"?>
<root xmlns:i="http://www.w3.org/2001/XMLSchema-instance"
  xmlns="http://schemas.datacontract.org/2004/07/MyClassname">
  <prop1>true</prop1>
  <prop2 xmlns:d2p1="http://schemas.datacontract.org/2004/07/MySubclassname">
    <d2p1:sub>true</d2p1:sub>
  </prop2>
</root>

后:

<?xml version="1.0" encoding="utf-8"?>
<root xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
  <prop1>true</prop1>
  <prop2>
    <sub>true</sub>
  </prop2>
</root>
于 2016-09-27T14:53:25.823 回答