2011-10-17 148 views
0

需要您的幫助來設置XML反序列化的xml屬性。使用xml元素/屬性對XML進行反序列化

這是我的輸入XML:

<form> 
<question id="QnA"> 
<answer>AnswerforA</answer> 
</question> 
<question id="QnB"> 
<answer>AnswerforB</answer> 
</question> 
<question id="QnC"> 
<answer>AnswerforC</answer> 
</question> 
</form> 

每個問題元素標籤的ID對應於一個類的屬性和它的值是對應的答案元素的innerText。

的cs文件看起來像

public class Test 
{ 

    private string qnaAns;  
    private string qnbAns; 
    private string qncAns; 

    public string QnA 
    { 
    get{ return qnaAns;} 
    set{qnaAns = value;} 
    } 

    public string QnB 
    { 
    get{ return qnbAns;} 
    set{qnbAns = value;} 
    } 

    public string QnC 
    { 
    get{ return qncAns;} 
    set{qncAns = value;} 
    } 
} 

我用的是follwing代碼反序列化

XmlSerializer ser = new XmlSerializer(typeof(Test)); 

XmlReader xr = new xmlReader(inputxml); 

Test t = ser.Deserialize(xr) as Test; 

請讓我知道如何設置的XML元素/屬性的測試類做到這一點。

感謝您的時間。

+0

我有點懶得通過您的代碼看,並找出您遇到什麼麻煩,所以請讓我們知道什麼是問題你有。 – Kiril 2011-10-17 13:26:28

+0

你應該構建你的DTO來表示你試圖序列化的數據,否則你將不得不實現'IXmlSerializable'(不好玩)。請參閱Matt的回答,以獲得第一個(也是正確的,IMO)選項的示例。 – 2011-10-17 13:31:08

回答

2
[XmlRoot("form")] 
    public class Form 
    { 
     [XmlElement("question")] 
     public List<Question> Questions { get; set; } 

     public Form() 
     { 
      Questions = new List<Question>(); 
     } 
    } 
    public struct Question 
    { 
     [XmlAttribute("id")] 
     public string ID { get; set; } 

     [XmlElement("answer")] 
     public string Answer { get; set; } 
    } 

然後序列化,我用以下擴展名:

public static bool XmlSerialize<T>(this T item, string fileName) 
     { 
      return item.XmlSerialize(fileName, true); 
     } 
     public static bool XmlSerialize<T>(this T item, string fileName, bool removeNamespaces) 
     { 
      object locker = new object(); 

      XmlSerializerNamespaces xmlns = new XmlSerializerNamespaces(); 
      xmlns.Add(string.Empty, string.Empty); 

      XmlSerializer xmlSerializer = new XmlSerializer(typeof(T)); 

      XmlWriterSettings settings = new XmlWriterSettings(); 
      settings.Indent = true; 
      settings.OmitXmlDeclaration = true; 

      lock (locker) 
      { 
       using (XmlWriter writer = XmlWriter.Create(fileName, settings)) 
       { 
        if (removeNamespaces) 
        { 
         xmlSerializer.Serialize(writer, item, xmlns); 
        } 
        else { xmlSerializer.Serialize(writer, item); } 

        writer.Close(); 
       } 
      } 

      return true; 
     } 
     public static T XmlDeserialize<T>(this string s) 
     { 
      object locker = new object(); 
      StringReader stringReader = new StringReader(s); 
      XmlTextReader reader = new XmlTextReader(stringReader); 
      try 
      { 
       XmlSerializer xmlSerializer = new XmlSerializer(typeof(T)); 
       lock (locker) 
       { 
        T item = (T)xmlSerializer.Deserialize(reader); 
        reader.Close(); 
        return item; 
       } 
      } 
      finally 
      { 
       if (reader != null) 
       { reader.Close(); } 
      } 
     } 
     public static T XmlDeserialize<T>(this FileInfo fileInfo) 
     { 
      string xml = string.Empty; 
      using (FileStream fs = new FileStream(fileInfo.FullName, FileMode.Open, FileAccess.Read)) 
      { 
       using (StreamReader sr = new StreamReader(fs)) 
       { 
        return sr.ReadToEnd().XmlDeserialize<T>(); 
       } 
      } 
     } 

希望這有助於。

PS - 這些擴展從我來到圖書館在CodeProject上:http://www.codeproject.com/KB/dotnet/MBGExtensionsLibrary.aspx

+0

你可以這樣反序列化:'Form form = new FileInfo(「c:\\ test.xml」)。XmlDeserialize

();' – Matt 2011-10-17 13:34:46

+0

不確定擴展方法是否真的值得,但總體方法(有一個DTO反映xml的模型)絕對是正確的。 – 2011-10-17 13:40:02

+0

感謝您的回答。但我的意圖是不在裏面有兩個元素的列表。根據你的代碼,我必須將QnA屬性設置爲公共字符串QnA {{Question.FindIndex(t => t.ID ==「QnA」)]。 } set {; } } ..是否有可能直接設置屬性?謝謝。 – 2011-10-17 16:40:12