2013-01-21 35 views
3

我正在與向我們發送XML消息的第三方應用程序進行集成。他們的XML看起來是這樣的:DocType標記上的XML反序列化失敗

<?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的對象。

如果我刪除<!DOCTYPE>標記,那麼它反序列化罰款。

有沒有辦法讓XmlSerializer忽略<!DOCTYPE>標籤?

我知道我可以在將它傳遞給XmlSerializer之前將其去掉,但是如果我不需要,我寧願不去那個XML操作級別。

+0

去拿檢查這個環節,這對我的作品。 [解決方案](http://stackoverflow.com/questions/26228371/allow-net-webapi-to-disregard-doctype-declaration) –

回答

6

而不是使用XmlTextReader的,叫XmlReader.CreateDtdProcessing設置爲Ignore傳遞一個​​對象:

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中,你可以改爲設置ProhibitDtdfalseXmlResolvernull

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

你可以僅僅刪除了doctype

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