2014-11-21 2 views
0

임의의 메시지 내용을 포함 할 수있는 XML 봉투를 나타 내기 위해 직렬화 가능 클래스를 만들고 싶습니다. 아래의 예 XML (간체) :가변 내용을 포함하는 표준 표준 xml 봉투

<?xml version="1.0" encoding="utf-8"?> 
<Envelope> 
    <MessageA> 
     <Url></Url> 
    </MessageA> 
</Envelope> 

<?xml version="1.0" encoding="utf-8"?> 
<Envelope> 
    <MessageB> 
     <Value></Value> 
    </MessageB> 
</Envelope> 

내 생각이 처리하는 일반적인 봉투 클래스를 사용하는 것입니다

[Serializable] 
[XmlRoot(ElementName="Envelope")] 
public class Envelope<TContent> where TContent : new() 
{ 
    public Envelope() 
    { 
     Content = new TContent(); 
    } 
    public TContent Content { get; set; } 
} 

[Serializable] 
public class MessageA 
{ 
    public string Url { get; set; } 
} 

[Serializable] 
public class MessageB 
{ 
    public string Value { get; set; } 
} 

이 너무 직렬화 수 :

var envelope = new Envelope<MessageA>(); 
envelope.Content.Url = "http://www.contoso.com"; 
string xml = envelope.ToXml(); 

을하지만, 대신 위의 예제에 따라 원하는 xml 메시지 중에서 다음을 얻습니다. 어떻게 Content 요소의 이름을 메시지 자체의 이름으로 바꾸도록 클래스 또는 직렬화 프로세스를 변경할 수 있습니까?

<?xml version="1.0" encoding="utf-8"?> 
<Envelope> 
    <Content> 
     <Url>http://www.contoso.com</Url> 
    </Content> 
</Envelope> 

답변

0

XmlAttributeOverrides 클래스에이 문제에 대한 해결책이있는 것으로 나타났습니다. Envelope 클래스에 다음 메서드를 추가하면 ToXml() 확장 메서드가 필요에 따라 개체를 serialize합니다.

public string ToXml() 
{ 
    return ToXml(typeof(TContent).Name); 
} 

public string ToXml(string contentElementName) 
{ 
    XmlElementAttribute element = new XmlElementAttribute(contentElementName, typeof(TContent)); 
    XmlAttributes attributes = new XmlAttributes(); 
    attributes.XmlElements.Add(element); 
    XmlAttributeOverrides overrides = new XmlAttributeOverrides(); 
    overrides.Add(typeof(Envelope<TContent>), "Content", attributes); 
    return ToXml(this, overrides); 
} 

public string ToXml(Envelope<TContent> value, XmlAttributeOverrides overrides) 
{ 
    using (var sw = new Utf8StringWriter()) 
    { 
     var settings = new XmlWriterSettings 
     { 
      OmitXmlDeclaration = omitXmlDeclaration, 
      Indent = true 
     }; 
     XmlSerializer xs = new XmlSerializer(typeof(Envelope<TContent>), overrides); 
     using (XmlWriter writer = XmlWriter.Create(sw, settings)) 
     { 
      xs.Serialize(writer, value); 
     } 
     return sw.ToString(); 
    } 
}