5

我有一系列的类,我使用.NET 4.0中的.NET DataContractSerializer转换为XML。序列化工作正常,我可以解析XML并稍后重新创建.NET对象。避免在.Net DataContractSerializer中使用“http://www.w3.org/2001/XMLSchema-instance”命名空间

但是,大多数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的不写节点,而不是,当它有一个空值?

+0

你忽略了你的榜样。 –

+0

斑点...切割和粘贴出错了... –

回答

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"你在下面的例子中

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); 
    } 
} 

与问候使用例如Replace()喜欢:)

+0

为我工作。谢谢。 – TravisWhidden

+4

'String.Replace'去除它看起来像一个黑客。有更好的选择吗? –

0

(我偶然在错误的问题中发布了这个答案,但我认为这也有帮助,所以我不会删除它现在)

[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>