2008-11-03 64 views
14

我正在使用XmlSerializer在C#中將對象寫入和讀取到xml。我目前使用屬性XmlElementXmlIgnore來操縱對象的序列化。如果找不到元素,我能否使用C#中的XmlSerializer反序列化?

如果我的xml文件缺少一個我需要的xml元素,我的對象仍然反序列化(xml - > object)就好了。我如何表示(最好通過屬性)某個字段是「必需的」?

下面是我使用目前的樣本方法:

[XmlElement(ElementName="numberOfWidgets")] 
public int NumberThatIsRequired { 
    set ...; 
    get ...; 
} 

我的理想的解決辦法是添加類似的XmlRequired屬性。

另外,有什麼可用於操縱XmlSerializer行爲的屬性的好參考?

+0

類似的msdn問題[這裏](http://social.msdn.microsoft.com/Forums/eu/xmlandnetfx/thread/a134471c-6b20-433e-8dd4-d153cac29810)這也解釋了驗證是你正在嘗試要做 – KCD 2012-02-07 23:06:19

+0

如果你在XML中沒有`numberOfWidgets`元素,你會在屬性NumberThatIsRequired中擁有什麼?零? – 2012-07-11 10:13:05

回答

4

我有第二部分的答案:​​3210。

仍在調查第一部分...

編輯:我強烈懷疑你無法通過XML反序列化本身做到這一點。我剛剛在包含必需屬性的示例模式上運行xsd.exe - 如果屬性標記爲可選屬性,則完全相同。如果有一種要求設置屬性的方法,我希望它能在這種情況下實現。

我懷疑你基本上只是在反序列化它之後驗證你的對象樹。對不起...

+0

您確實需要在您的XSD中引用的源XML中正確設置XML名稱空間,否則使用XSD進行驗證將無法正常運行,包括必需的字段驗證。 – 2010-05-02 23:22:08

15

我發現這樣做的唯一方法是通過XSD。你可以做的是驗證,而你反序列化:

static T Deserialize<T>(string xml, XmlSchemaSet schemas) 
{ 
    //List<XmlSchemaException> exceptions = new List<XmlSchemaException>(); 
    ValidationEventHandler validationHandler = (s, e) => 
    { 
     //you could alternatively catch all the exceptions 
     //exceptions.Add(e.Exception); 
     throw e.Exception; 
    }; 

    XmlReaderSettings settings = new XmlReaderSettings(); 
    settings.Schemas.Add(schemas); 
    settings.ValidationType = ValidationType.Schema; 
    settings.ValidationEventHandler += validationHandler; 

    XmlSerializer serializer = new XmlSerializer(typeof(T)); 
    using (StringReader sr = new StringReader(xml)) 
     using (XmlReader books = XmlReader.Create(sr, settings)) 
      return (T)serializer.Deserialize(books); 
} 
4

爲了可擴展性原因,XmlSerializer是非常寬容的,當涉及到反序列化;之類的東西[DefaultValue]ShouldSerialize{Foo}{Foo}Specified主要在序列(例外是{Foo}Specified,其被反序列化過程集以及序列化期間查詢)使用

因此,除非你實施IXmlSerializable並自己做,否則沒有簡單的方法來做到這一點。 damagednoob顯示一個xsd選項,這也是一個選項。

相關問題