2012-12-04 9 views
40

Ist es möglich Deserialize unbekannten XML zu Objekt wie unten?Deserialize XML To Object mit 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

Warum versuchen Sie es einfach nicht? –

+0

Ich habe versucht, es auszuwerfen, aber die gleiche Logik funktioniert für Json, warum es nicht mit xml unterstützt – user1875919

+0

Mögliches Duplikat von [XML in ein dynamisches C# -Objekt konvertieren] (https://stackoverflow.com/questions/13171525/converting-xml-to- a-dynamic-c-sharp-object) –

Antwort

66

Sie können dies versuchen.

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

Dies funktioniert hervorragend, wenn mehrere Elemente zurückgegeben werden, wenn nur ein einzelnes Element zurückgegeben wird und Sie es in einer foreach verwenden! Ich würde vorschlagen, "result = new DynamicXml (node)" zu ändern; zu "Ergebnis = neue Liste () {new DynamicXml (node)};" was eine Liste mit einem einzelnen Element zurückgibt. –

+0

Das Setzen oder Abrufen von Attributwerten wird besser mit TrySetIndex/TryGetIndex durchgeführt. Wenn wir also ein Element wie haben, wäre die Syntax zum Erreichen des Namensattributs person ["name"]. –

+1

@RezoMegrelidze Aber ich wollte es als 'person.name' implementieren. –