2015-06-03 75 views
1

XML反序列化到我如何反序列化這樣的XML特性

<query> 
    <parameters> 
    <param name="lastUpdate">2012-05-25</param> 
    <param name="code">11222122</param> 
    <param name="type">idnLookup</param> 
    </parameters> 
    <response> 
    <category name="person" version="1"> 
     <field name="surname">Soap</field> 
     <field name="name1">Joe</field> 
     <field name="date_of_birth">1973-05-09</field> 
    </category> 
    <category name="contact" version="1"> 
     <row> 
     <field name="phone">0118063433</field> 
     <field name="type">home</field> 
     <field name="date">2003-01-01</field> 
     </row> 
     <row> 
     <field name="phone">0124666566</field> 
     <field name="type">home</field> 
     <field name="date">2008-03-11</field> 
     </row> 
    </category> 
    </response> 
</query> 

成階級結構是這樣的。或者我需要推出自己的?

+1

對於標準的Xml串行器來說,輸入過於具體,無法做到這一點。我認爲你可以在標準的標準反序列化之前運行XSL轉換,但是它可能更容易編寫自定義c#...你也可以看看IXmlSerializable接口 –

+0

@SimonMourier我會一直建議DTO模型(模型在域模型和序列化表單之間,與序列化層相匹配)在'IXmlSerializable'之前 - 該API是* horrendous *以便正確。我確實喜歡這裏的XSLT。 –

+1

作爲一個便箋:誰想出了該XML佈局......不知道如何XML; p –

回答

1

要擴大西蒙的XSLT想法,請考慮以下XSLT:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output method="xml" indent="yes"/> 

    <xsl:template match="@* | node()"> 
    <xsl:copy> 
     <xsl:apply-templates select="@* | node()"/> 
    </xsl:copy> 
    </xsl:template> 
    <xsl:template match="/query/parameters"> 
    <xsl:apply-templates select="*"/> 
    <!-- removes a level from the hierarchy by applying directly --> 
    </xsl:template> 
    <xsl:template match="*[@name]"> 
    <xsl:element name="{@name}"> 
     <xsl:apply-templates select="@*[name()!='name'] | * | text()"/> 
    </xsl:element> 
    </xsl:template> 
</xsl:stylesheet> 

這裏的關鍵比賽是*[@name],它採取的形式的東西:

<foo name="abc" ...>...</foo> 

並重寫它:

<abc ...>...</abc> 

這會將您的xml轉換爲:

<query> 
    <lastUpdate>2012-05-25</lastUpdate> 
    <code>11222122</code> 
    <type>idnLookup</type> 
    <response> 
    <person version="1"> 
     <surname>Soap</surname> 
     <name1>Joe</name1> 
     <date_of_birth>1973-05-09</date_of_birth> 
    </person> 
    <contact version="1"> 
     <row> 
     <phone>0118063433</phone> 
     <type>home</type> 
     <date>2003-01-01</date> 
     </row> 
     <row> 
     <phone>0124666566</phone> 
     <type>home</type> 
     <date>2008-03-11</date> 
     </row> 
    </contact> 
    </response> 
</query> 

可以映射到你的模型具有非常小的調整爲屬性:

[XmlRoot("query")] // <==== add this 
public class Query {...} 

[XmlArray("contact"), XmlArrayItem("row")] // <=== add this 
public Contact[] contacts { get; set; } 

哪些可以使用,例如:

static void Main() 
{ 
    XslCompiledTransform xslt = new XslCompiledTransform(); 
    xslt.Load("my.xslt"); 
    var sw = new StringWriter(); 
    xslt.Transform("my.xml", null, sw); 
    var transformedXml = sw.ToString(); 

    Console.WriteLine(transformedXml); 
    Query query; 
    using (var reader = XmlReader.Create(new StringReader(transformedXml))) 
    { 
     query = (Query)new XmlSerializer(typeof(Query)).Deserialize(reader); 
    } 
    // query is now fully populated 
} 
+0

謝謝你。奇蹟般有效。我爲西蒙的建議xslt發表了評論 –

0

試試這個

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Xml; 
using System.Xml.Serialization; 
using System.IO; 

namespace ConsoleApplication32 
{ 
    class Program 
    { 
     const string FILENAME = @"c:\temp\Test.xml"; 
     static void Main(string[] args) 
     { 
      XmlSerializer xs = new XmlSerializer(typeof(Query)); 
      XmlTextReader reader = new XmlTextReader(FILENAME); 
      Query query = (Query)xs.Deserialize(reader); 
      query.Response.GetContacts(); 

     } 
    } 
    [XmlRoot("query")] 
    public class Query 
    { 
     [XmlElement("parameters")] 
     public Parameters Parameters {get;set;} 
     [XmlElement("response")] 
     public Response Response {get;set;} 
    } 
    [XmlRoot("parameters")] 
    public class Parameters{ 
     private string lastUpdate {get;set;} 
     private string code {get;set;} 
     private string type {get;set;} 

     [XmlElement("param")] 
     public List<Param> m_params {get; set;} 

    } 
    [XmlRoot("param")] 
    public class Param 
    { 
     [XmlAttribute("name")] 
     public string name {get; set;} 
    } 

    [XmlRoot("response")] 
    public class Response 
    { 
     private Person person {get;set;} 
     private List<Contact> contacts = new List<Contact>(); 
     [XmlElement("category")] 
     public List<Category> categories {get;set;} 

     public void GetContacts() 
     { 
      foreach (Category category in categories) 
      { 
       string catName = category.name; 
       switch (catName) 
       { 
        case "person" : 
         person = new Person(); 
         foreach (Field field in category.fields) 
         { 
          switch (field.name) 
          { 
           case "surname" : 
            person.surname = field.value; 
            break; 
           case "name1": 
            person.name1 = field.value; 
            break; 
           case "date_of_birth": 
            person.date_of_birth = field.value; 
            break; 
           default : 
            break; 
          } 
         } 
         break; 
        case "contact" : 
         foreach (Row row in category.row) 
         { 
          Contact newContact = new Contact(); 
          contacts.Add(newContact); 

          foreach (Field field in row.fields) 
          { 
           switch (field.name) 
           { 
            case "phone": 
             newContact.phone = field.value; 
             break; 
            case "type": 
             newContact.type = field.value; 
             break; 
            case "date": 
             newContact.date = field.value; 
             break; 
            default: 
             break; 
           } 
          } 
         } 
         break; 
       } 
      } 
     } 
    } 
    [XmlRoot("category")] 
    public class Category 
    { 
     [XmlAttribute("name")] 
     public string name {get; set;} 
     [XmlAttribute("version")] 
     public string version { get; set; } 
     [XmlElement("field")] 
     public List<Field> fields {get; set;} 
     [XmlElement("row")] 
     public List<Row> row {get;set;} 
    } 
    [XmlRoot("row")] 
    public class Row 
    { 
     [XmlElement("field")] 
     public List<Field> fields {get; set;} 
    } 

    [XmlRoot("field")] 
    public class Field 
    { 
     [XmlAttribute("name")] 
     public string name { get; set; } 
     [XmlText] 
     public string value { get; set; } 
    } 

    class Person { 
     public string surname {get;set;} 
     public string name1 {get;set;} 
     public string date_of_birth {get;set;} 
    } 
    class Contact { 
     public string phone {get;set;} 
     public string type {get;set;} 
     public string date {get;set;} 
    } 
}