2013-01-21 3 views
3

XML 메시지를 보내는 타사 응용 프로그램과 통합하려고합니다.XML이 DocType 태그에서 탈 직렬화하지 못했습니다.

<?xml version="1.0" encoding="UTF-8"?> 
<!DOCTYPE theirObj SYSTEM "theirDTD-2.0.dtd"> 
<theirObj> 
    <properties> 
     <datasource>ThirdParty</datasource> 
     <datetime>2009-03-05T14:45:39</datetime> 
    </properties> 
     <data> 
      ... 
     </data> 
</theirObj> 

내가 XmlSerializer를을 사용하여 직렬화하기 위해 노력하고있어 :

public theirObj Deserialize(string message) { 
      if(string.IsNullOrWhiteSpace(message)) { 
       throw new ArgumentNullException("message"); 
      } 
      XmlSerializer xmlSerializer = new XmlSerializer(typeof(theirObj)); 

      TextReader textReader = new StringReader(message); 

      using (XmlReader xmlReader = new XmlTextReader(textReader)) { 
       object deserializedObject = xmlSerializer.Deserialize(xmlReader); 

       theirObj ent = deserializedObject as theirObj ; 

       if (ent == null) { 
        throw new InvalidCastException("Unable to cast deserialized object to an theirObj object. {0}".FormatInvariant(deserializedObject)); 
       } 

       return ent; 
      } 
     } 
} 

내가 xsd.exe를 사용하여 객체를 생성 그들의 XML은 다음과 같이 보인다.

<!DOCTYPE> 태그를 제거하면 정상적으로 비 직렬화됩니다.

XmlSerializer에서 <!DOCTYPE> 태그를 무시하는 방법이 있습니까?

XmlSerializer를 전달하기 전에 제거 할 수 있지만 XML 조작 수준으로 이동하지 않아도됩니다.

+0

이동이 링크를 확인 얻을, 그것은 나를 위해 작동합니다. [솔루션] (http://stackoverflow.com/questions/26228371/allow-net-webapi-to-disregard-doctype-declaration) –

답변

6

을 제거 XmlReader.Create를 호출 DtdProcessing 세트 Ignore에로에게 XmlReaderSettings 개체를 전달할 수 있습니다

TextReader textReader = new StringReader(message); 
var settings = new XmlReaderSettings { DtdProcessing = DtdProcessing.Ignore }; 

using (XmlReader xmlReader = XmlReader.Create(textReader, settings)) 

참고 :DtdProcessing 특성 .NET 4.0에 추가되었습니다. .NET 3.5에서 대신 nullfalseXmlResolverProhibitDtd을 설정할 수 있습니다

var settings = new XmlReaderSettings { ProhibitDtd = false, XmlResolver = null }; 
+0

완벽! 그것은 매력처럼 작용했습니다. 나는 태그를 제거해야한다는 것을 두려워했다. (해킹처럼 느껴졌다.) –

0

DOCTYPE에는 XmlSerlization 특성이 기본 제공되지 않습니다. 사실 XML 직렬화는 문서 기반이 아닌 요소 기반이기 때문입니다. 나는 당신이 당신의 직렬화에 DOCTYPE을 건너 뛰려면 다음과 같은 방법을 사용할 수 있다고 생각 : 문서를 직렬화 복원 된 후

public static String Serialize(object obj) 
{ 
    StringBuilder builder = new StringBuilder(); 
    XmlSerializer serializer = new XmlSerializer(typeof(theirObj)); 

    using (XmlWriter writer = XmlWriter.Create(builder, new XmlWriterSettings() { OmitXmlDeclaration = true })) 
     xmlSerializer.Serialize(writer, obj); 

    return builder.ToString(); 
} 

그런 다음 다시 주입.

0

당신은 단지의 문서 타입 대신 XmlTextReader를 사용

TextReader textReader = new StringReader(message); 
XmlDocument XDoc = new XmlDocument(); 
XDoc.Load(textReader); 
XmlDocumentType XDType = XDoc.DocumentType; 
XDoc.RemoveChild(XDType); 

using (XmlReader xmlReader = new XmlTextReader(XDoc)) { 
       object deserializedObject = xmlSerializer.Deserialize(xmlReader); 

       theirObj ent = deserializedObject as theirObj ; 

       if (ent == null) { 
        throw new InvalidCastException("Unable to cast deserialized object to an theirObj object. {0}".FormatInvariant(deserializedObject)); 
       } 

       return ent; 
      }