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는 Null 값을 갖는 속성을 특성이있는 노드로 쓰는 것을 주장합니다.

<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를 얻을 방법이 있나요 :
[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> 

에서 직렬화 할 수 있습니다 , 그것은 null 값을 때?

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

는 다음 예제와 관련하여

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()을 위해 사용해야 할 xmlns:i="http://www.w3.org/2001/XmlSchema-instance"을 제거 :)

+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> 
관련 문제