2012-12-04 30 views
40

Có thể Deserialize XML chưa biết đối tượng như dưới đây không?Deserialize XML Để đối tượng sử dụng Dynamic

var xml = @"<Students><Student><Name>Arul</Name><Mark>90</Mark></Student></Students>"; 

var serializer = new XmlSerializer(typeof(DynamicObject)); 

dynamic students = serializer.Deserialize(new XmlTextReader(new StringReader(xml))); 
+9

Tại sao bạn không chỉ cần thử nó? –

+0

tôi đã thử nó ném ngoại lệ nhưng cùng một logic làm việc cho Json tại sao nó không hỗ trợ với xml – user1875919

+0

Có thể trùng lặp của [Chuyển đổi XML thành một đối tượng C# động] (https://stackoverflow.com/questions/13171525/converting-xml-to- a-dynamic-c-sharp-object) –

Trả lời

66

Bạn có thể thử điều này.

string xml = @"<Students> 
       <Student ID=""100""> 
        <Name>Arul</Name> 
        <Mark>90</Mark> 
       </Student> 
       <Student> 
        <Name>Arul2</Name> 
        <Mark>80</Mark> 
       </Student> 
      </Students>"; 

dynamic students = DynamicXml.Parse(xml); 

var id = students.Student[0].ID; 
var name1 = students.Student[1].Name; 

foreach(var std in students.Student) 
{ 
    Console.WriteLine(std.Mark); 
} 

public class DynamicXml : DynamicObject 
{ 
    XElement _root; 
    private DynamicXml(XElement root) 
    { 
     _root = root; 
    } 

    public static DynamicXml Parse(string xmlString) 
    { 
     return new DynamicXml(XDocument.Parse(xmlString).Root); 
    } 

    public static DynamicXml Load(string filename) 
    { 
     return new DynamicXml(XDocument.Load(filename).Root); 
    } 

    public override bool TryGetMember(GetMemberBinder binder, out object result) 
    { 
     result = null; 

     var att = _root.Attribute(binder.Name); 
     if (att != null) 
     { 
      result = att.Value; 
      return true; 
     } 

     var nodes = _root.Elements(binder.Name); 
     if (nodes.Count() > 1) 
     { 
      result = nodes.Select(n => n.HasElements ? (object)new DynamicXml(n) : n.Value).ToList(); 
      return true; 
     } 

     var node = _root.Element(binder.Name); 
     if (node != null) 
     { 
      result = node.HasElements || node.HasAttributes ? (object)new DynamicXml(node) : node.Value; 
      return true; 
     } 

     return true; 
    } 
} 
+4

Điều này làm việc tuyệt vời nếu nhiều phần tử được trả về bởi thất bại của chỉ một phần tử duy nhất được trả về và bạn đang sử dụng nó trong một foreach! Tôi sẽ đề nghị thay đổi "result = new DynamicXml (node);" tới "result = new List () {new DynamicXml (node)};" sẽ trả về một danh sách với một phần tử duy nhất. –

+0

Cài đặt hoặc nhận các giá trị thuộc tính được thực hiện tốt hơn với TrySetIndex/TryGetIndex. Vì vậy, nếu chúng ta có một phần tử như cú pháp để tiếp cận thuộc tính name sẽ là person ["name"]. –

+1

@RezoMegrelidze Nhưng tôi muốn thực hiện nó như 'person.name'. –

Các vấn đề liên quan