2013-04-09 142 views
0

大家好消息! 我遇到了一些棘手的XML新問題。如何反序列化元素名稱列表編號的XML?

<?xml version="1.0" encoding="UTF-8"?> 
<response> 
<osmp_txn_id>100500</osmp_txn_id> 
<result>0</result> 
<fields> 
<field1 name="name">Ko Chu Bey</field1> 
<field2 name="contract">777-1</field2> 
... 
<fieldN name="account">65000</fieldN> 
</fields> 
<comment>Result for round 1 of fight vs Pe Re Svet: 1:1</comment> 
</response> 

我的問題是,內置的實用工具,生成XSD的ANS CS的使不同類各fieldX。而且因爲它們的數量可能會很多,所以它變成了一個非常親密的地方。 有沒有辦法將對象從這個XML反序列化成一個具有field對象數組的類?

+0

您需要完全控制反序列化過程;看起來像這些字段可以創建一個不錯的KeyValuePair。在我的手機上,現在無法真正給出答案,但我會研究如何實現ISerializable。 – 2013-04-09 12:09:03

回答

0

如果你有一個字符串,你可以做到這一點使用LINQ to XML和名稱的正則表達式的XML:

var fieldElementNameRegex = new Regex(
    "^field[0-9]+$", 
    RegexOptions.IgnoreCase | RegexOptions.Compiled); 

var xml = XElement.Parse(xmlString); 

var fieldElements = xml 
    .Descendants() 
    .Where(e => fieldElementNameRegex.IsMatch(e.Name.ToString())) 
    .ToArray(); 
+0

對不起,看起來像我所說的被誤解了。我知道,是否有可能將這樣的xml反序列化成一個具有'field'對象數組的類。 – Hikiko 2013-04-09 12:05:50

+0

作爲一種可能的解決方案,我發現使用'Regex'遍歷響應字符串並將所有'fieldX'變成'field'並在替換後將其反序列化。 – Hikiko 2013-04-09 12:08:37

+0

只是爲了澄清你爲什麼指'反序列化' - 你的意思是在運行時將它變成一個對象? – 2013-04-09 12:10:17

0

最好的解決辦法是讓自己的IXmlSerializable實施使用XML有問題。預先做好會很麻煩,但從長遠來看,這可能是值得的。

作爲一種替代方法(我不會推薦它太強烈),您可以寫一些小技巧來反思默認序列化對象的屬性 - 您解釋的屬性是由內置實用程序生成的。

例如,假設:

公共類字段 { 公共字符串名稱; 公共字符串值; }

public class response 
{ 
    public Field field1; 
    public Field field2; 
    public Field field3; 
    public Field field4; 
    public Field field5; 
    public Field field6; 
    public Field field7; 
    public string comments; 
    public string osmp_txn_id; 
    public string result; 
} 

可以定義下面的 「方便」 類:

public class myResponse 
{ 
    public string comments; 
    public string osmp_txn_id; 
    public string result; 
    public List<Field> fields; 
} 

,這將是如何填充更方便類:

myResponse ConvertFromResult(response target) 
{ 
    var returnObject = new myResponse(); 

    var fields = target.GetType().GetFields().Where(f => f.FieldType == typeof(Field)); 
    returnObject.fields = (from f in fields 
    let fp = f.GetValue(target) as Field 
    where fp != null 
    select fp).ToList(); 

    returnObject.comments = target.comments; 
    returnObject.osmp_txn_id = target.osmp_txn_id; 
    returnObject.result = target.result; 

    return returnObject; 
} 

這都是概念性的,所以你可能需要從這裏「推出自己的」解決方案。另一種方法是使用擴展方法爲xml反序列化對象返回一個IEnumerable<field>,如果要以非性能密集型方式使用它,這將是可行的。

public static class responseExtensions 
{ 
    private static IEnumerable<Field> GetFields(this response target) 
    { 
    var fields = target.GetType().GetFields().Where(f => f.FieldType == typeof(Field)); 
    return from f in fields 
      let fp = f.GetValue(target) as Field 
      where fp != null 
      select fp; 
    } 
}