简体   繁体   English

将键/值xml反序列化为对象

[英]Deserialize key/value xml into an object

Having some difficulties deserializing the following xml to an object in the most efficient/cleanest possible way: 在以最有效/最干净的方式将以下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>

This is a single item along with its properties. 这是单个项目及其属性。 As you can see the properties are defined as key/value pairs. 如您所见,属性定义为键/值对。

Because they are key value pairs i could not find a way to use the Xml deserialize attributes (as described in this question: How to deserialize xml to object ) 因为它们是键值对,所以我找不到使用Xml反序列化属性的方法(如本问题所述: 如何将xml反序列化为object

Therefore i have created the following alternative: 因此,我创建了以下替代方法:

// 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);

As you can see this is alot more code than when using the deserialize attributes. 如您所见,这比使用反序列化属性时要多得多的代码。 Is there any way i could still use these attributes so that my code could be cleaner/ efficient? 有什么办法可以让我仍然使用这些属性,以便使我的代码更干净/更有效? i am going to have to make alot of these functions otherwise. 否则,我将不得不大量使用这些功能。

I don't think attributes will work because of key/value structure. 我不认为属性会因为键/值结构而起作用。 There is no way for a program to infer from the xml alone what properties an object has. 程序无法仅从xml推断对象具有什么属性。 I would make a static extension method helper function to get the values: 我将使用静态扩展方法辅助函数来获取值:

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

That way your code could look like this: 这样,您的代码可能如下所示:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM