2016-04-01 196 views
0

有一些困​​難反序列化下面的XML到對象以最有效的/清潔的方式:反序列化鍵/值XML到對象

<item xsi:type="ns2:Map" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 
    <item> 
     <key xsi:type="xsd:string">mailinglistid</key> 
     <value xsi:type="xsd:string">1</value> 
    </item> 
    <item> 
     <key xsi:type="xsd:string">uniqueid</key> 
     <value xsi:type="xsd:string">1a0d0d2195</value> 
    </item> 
    <item> 
     <key xsi:type="xsd:string">name</key> 
     <value xsi:type="xsd:string">OSM NL</value> 
    </item> 
</item> 

這是它的特性沿着單個項目。正如你所看到的,屬性被定義爲鍵/值對。

因爲他們是鍵值對我不能找到一種方法,使用XML反序列化的屬性(在這個問題描述:How to deserialize xml to object

因此,我創建了以下選擇:

// Retrieves all the elements from the "return" node in the Mailinglist_allResponse node. 
var items = response.ResponseFromServer.Descendants(_engineResponseNamespace + "Mailinglist_allResponse").Descendants("return").Elements(); 

foreach (var item in items) 
{ 
    var values = item.Descendants("item").ToArray(); 

    var list = new EngineMailingList 
    { 
     MailingListId = 
      values.Descendants("key") 
       .First(v => v.Value == "mailinglistid") 
       .ElementsAfterSelf("value") 
       .First() 
       .Value, 
     UniqueId = 
      values.Descendants("key") 
       .First(v => v.Value == "uniqueid") 
       .ElementsAfterSelf("value") 
       .First() 
       .Value, 
     Name = 
      values.Descendants("key") 
       .First(v => v.Value == "name") 
       .ElementsAfterSelf("value") 
       .First() 
       .Value, 
    }; 

    result.Add(list); 

如您所見,與使用反序列化屬性相比,這是更多的代碼。有什麼辦法可以繼續使用這些屬性,這樣我的代碼就可以更清潔/更高效了嗎?否則,我將不得不做出許多這些功能。

+0

這XML看起來無效。應該有來自'xsi:type =「ns2:Map」'和'xsi:type =「xsd:string」'的命名空間前綴'ns'和'xsd'的命名空間。 ['xsi:type'](https://www.w3.org/TR/xmlschema-1/#xsi_type)屬性是指定多態元素類型的標準方法,請參見[Xsi:type Attribute Binding Support ](https://msdn.microsoft.com/en-us/library/ca1ks327.aspx)。 – dbc

+0

對不起,文章中的xml只是其中的一部分。它有頂部的命名空間,我只是決定不把它們包含在這篇文章中。 –

+0

@Jurgen Welschen您可以向我們展示您不包含的命名空間.... – Monty

回答

1

我不認爲屬性會因爲關鍵/價值結構而起作用。程序無法單獨從xml推斷對象具有的屬性。我會做一個靜態的擴展方法輔助函數來獲取值:

public static string GetValue(this XElement element, string key){ 
     return values.Descendants("key") 
        .First(v => v.Value == key) 
        .ElementsAfterSelf("value") 
        .First() 
        .Value; 
    } 

這樣,你的代碼看起來是這樣的:

MailingListId = values.GetValue("mailinglistid"), 
UniqueId = values.GetValue("uniqueid"), 
Name = values.GetValue("name") 
+0

好的謝謝!所以沒有真正的方法來使用反序列化屬性來做到這一點。助手功能是一個好主意! –

+0

您可能可以爲此創建自己的自定義屬性,但可能比它值得更麻煩 – jle