2012-12-04 10 views
40

未知のXMLを以下のように逆シリアル化することは可能ですか?動的にオブジェクトをXMLに逆シリアル化する

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

なぜあなたはそれを試してみませんか? –

+0

例外をスローしましたが、同じロジックがJsonのために働いていたのですがなぜXMLでサポートされていないのですか – user1875919

+0

[XMLを動的C#オブジェクトに変換]の可能な複製(https://stackoverflow.com/questions/13171525/converting-xml-to- a-dynamic-c-sharp-object) –

答えて

66

これを試してください。

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

これは、複数の要素が1つの要素だけが返されて失敗して返され、foreachで使用している場合に効果的です!私は変更することをお勧めします "結果=新しいDynamicXml(ノード);" "結果=新しいリスト(){新しいDynamicXml(ノード)};" 1つの要素でリストを返します。 –

+0

TrySetIndex/TryGetIndexを使用すると、属性値を設定または取得する方が効果的です。したがって、のような要素がある場合、name属性に到達する構文はperson ["name"]になります。 –

+1

@RezoMegrelidzeしかし私はそれを 'person.name'として実装したかったのです。 –

関連する問題