2009-10-07 8 views
1

J'essaie de charger des données à partir d'une chaîne XML dans une structure de sorte que, une fois chargé, je peux alors dire Data.PropertyName pour lire les valeurs.Est-ce le moyen le plus efficace de charger des valeurs XML dans une structure?

Le code ci-dessous est-il le moyen le plus optimal de charger les données dans la structure?

De toute évidence, l'appel de First() a un impact sur la mémoire, donc si vous avez des éléments avec des sous-éléments appellera First() pour chacun d'entre eux devient un problème?

Merci

string xml = @"<ROOT> 
        <ID>1</ID> 
        <NAME>RF1</NAME> 
        <STAT>10200</STAT> 
        <TEST> 
         <ID>1</ID> 
         <NAME>BIGUN</NAME> 
        </TEST> 
        </ROOT> 
        "; 

    XElement Data = XElement.Parse(xml); 


    var Element = (from p in Data.Descendants("ROOT") 
        select new { 
         ID = (int)p.Element("ID"), 
         Test = new { 
            ID = p.Element("TEST").Descendants("ID").First(), 
            NAME = p.Element("TEST").Descendants("NAME").First() 
           }, 
         Stat = p.Element("STAT") }).First(); 

//Read Element.ID, Element.Test.Name 

Répondre

3

Vous pouvez utiliser XmlSerializer pour le désérialiser?

using System; 
using System.IO; 
using System.Xml.Serialization; 

[XmlRoot("ROOT")] 
public class MyType 
{ 
    [XmlElement("ID")] 
    public string Id { get; set; } 
    [XmlElement("NAME")] 
    public string Name { get; set; } 
    [XmlElement("STAT")] 
    public string Stat { get; set; } 
    [XmlElement("TEST")] 
    public MyOtherType Nested { get; set; } 
} 
public class MyOtherType 
{ 
    [XmlElement("ID")] 
    public string Id { get; set; } 
    [XmlElement("NAME")] 
    public string Name { get; set; } 
} 
static class Program 
{ 

    static void Main() 
    { 
     string xml = @"<ROOT> 
        <ID>1</ID> 
        <NAME>RF1</NAME> 
        <STAT>10200</STAT> 
        <TEST> 
         <ID>1</ID> 
         <NAME>BIGUN</NAME> 
        </TEST> 
        </ROOT>"; 
     MyType obj = (MyType) new XmlSerializer(typeof(MyType)) 
      .Deserialize(new StringReader(xml)); 
     Console.WriteLine(obj.Id); 
     Console.WriteLine(obj.Name); 
     Console.WriteLine(obj.Stat); 
     Console.WriteLine(obj.Nested.Id); 
     Console.WriteLine(obj.Nested.Name); 
    } 
} 
+0

Wow, merci. Je n'ai jamais vu cette approche auparavant. Diriez-vous que c'est plus efficace que LINQ ou très similaire? Que faire si vous avez une propriété dans la classe qui se rapporte à un XMLElement qui n'apparaît pas dans le fichier XML, lance-t-il une exception ou définit simplement la valeur de la propriété à null? – Jon

+0

@Jon: Je m'attends à ce qu'il soit légèrement moins efficace que LINQ, car il doit utiliser la réflexion pour savoir ce qu'il faut lire dans le XML. Vous auriez à profiler le code pour le savoir avec certitude. Vous pouvez utiliser la propriété IsNullable dans l'attribut XmlElement pour spécifier si l'élément est requis dans XML. – Guffa

1

Je vais pour désérialisation et les attributs Xml: beaucoup plus facile à lire.

+0

Pourriez-vous fournir un exemple ou un lien vers un exemple? – Jon

+0

Marc l'a déjà fait. –

0

Non, ce n'est pas la manière la plus optimale, mais elle sera probablement assez bonne.

Le plus optimal pour les performances serait d'écrire votre propre analyseur XML qui est spécialisé pour cela, mais ce serait bien sûr beaucoup plus de code.

Je ne sais pas pourquoi vous êtes concerné par la méthode First. Il va juste laisser le premier élément à travers et ensuite arrêter de lire, de sorte qu'il ne posera aucun problème. L'analyseur XML doit toujours analyser tous les enfants, bien sûr.

Questions connexes