2008-11-14 12 views
10

Je suis nouveau sur .net et C#, donc je veux m'assurer que j'utilise le bon outil pour le travail.Marcher dans un arbre XML en C#

Le code XML que je reçois est une description d'une arborescence de répertoires sur une autre machine, ce qui la rend très profonde. Ce que je dois faire maintenant est de prendre le XML et de créer une structure d'objets (classes personnalisées) et de les remplir avec des informations de l'entrée XML, comme Fichier, Dossier, Tags, Propriété ...

La structure d'arbre de cette entrée XML en fait, dans mon esprit, un candidat privilégié pour utiliser la récursivité pour marcher dans l'arbre.

Existe-t-il une manière différente de faire cela dans .net 3.5?

Je l'ai regardé XmlReaders, mais ils semblent marcher l'arbre de façon linéaire, pas vraiment ce que je cherche ...

Le XML que je reçois fait partie d'un 3ème partie api, donc est hors de mon contrôle, et peut changer dans les futurs. J'ai examiné la désérialisation, mais ses défauts (l'implémentation de la boîte noire, la nécessité de déclarer les membres publics, lente, ne fonctionne que pour les objets simples ...) la retirent également de la liste.

Merci de votre participation à ce sujet.

+0

J'ai posé une question similaire, suivez le lien pour voir une bonne discussion: http://stackoverflow.com/questions/9371541/how-to-create-a-collection-from-list-of-strings-that -represents-a-directory-stru – geekzster

Répondre

1

Chargez votre code XML dans un XMLDocument. Vous pouvez ensuite parcourir le DOM XMLDocuments en utilisant la récursivité.

Vous pouvez également consulter le modèle de méthode d'usine pour créer vos classes, ce qui serait très utile ici.

2

XmlReader n'est pas une API particulièrement conviviale. Si vous pouvez utiliser .NET 3.5, le chargement dans LINQ to XML est probablement votre meilleur choix. Vous pourriez facilement utiliser la récursivité avec ça. Sinon, XmlDocument ferait encore l'affaire ... un peu moins agréablement.

22

J'utiliserais les classes XLINQ dans System.Xml.Linq (c'est l'espace de noms et l'assembly dont vous aurez besoin pour référencer). Chargez le XML dans et XDocument:

XDocument doc = XDocument.Parse(someString); 

Ensuite, vous pouvez soit récursion utilisation ou une boucle de pseudo-récursion à itérer sur les nœuds enfants. Vous pouvez choisir vous nœuds enfants comme:

//if Directory is tag name of Directory XML 
//Note: Root is just the root XElement of the document 
var directoryElements = doc.Root.Elements("Directory"); 

//you get the idea 
var fileElements = doc.Root.Elements("File"); 

Les variables directoryElements et fileElements seront types IEnumerable, ce qui signifie que vous pouvez utiliser quelque chose comme un foreach à boucle à travers tous les éléments. Une façon de construire vous des éléments serait quelque chose comme ceci:

List<MyFileType> files = new List<MyFileType>(); 

foreach(XElelement fileElement in fileElements) 
{ 
    files.Add(new MyFileType() 
    {  
     Prop1 = fileElement.Element("Prop1"), //assumes properties are elements 
     Prop2 = fileElement.Element("Prop2"), 
    }); 
} 

Dans l'exemple, MyFileType est un type créé pour représenter les fichiers. C'est un peu une attaque par force brute, mais ça va faire le travail.

Si vous souhaitez utiliser XPath, vous devrez utiliser en utilisant System.Xml.XPath.


Note sur System.XML vs System.Xml.Linq

Il y a un certain nombre de classes XML qui ont été en .Net depuis les 1.0 jours. Ceux-ci vivent (principalement) dans System.Xml. Dans .Net 3.5, un magnifique ensemble de classes XML a été publié sous System.Xml.Linq. Je ne peux pas trop insister sur la façon dont ils doivent travailler avec les anciennes classes de System.Xml. Je les recommande fortement à n'importe quel programmeur de .Net et particulièrement à quelqu'un entrant juste dans. Net/C#.

+1

+1 pour souligner la différence entre System.Xml et System.Xml.Linq. –

2

Ceci est un problème qui est très approprié pour la récursivité.

Pour élaborer un peu plus sur ce que dit une autre affiche, vous voulez commencer en chargeant le XML dans un System.Xml.XmlDocument, (en utilisant LoadXml ou charge).

Vous pouvez accéder à la racine de l'arbre en utilisant la propriété XmlDocument.DocumentElement, et accéder aux enfants de chaque nœud en utilisant le ChildNodes propriété. Les nœuds enfants retournent une collection, et lorsque la collection est de taille 0, vous savez que vous avez atteint votre scénario de base. L'utilisation de LINQ est également une bonne option, mais je suis incapable d'élaborer sur cette solution, parce que je ne suis pas vraiment un expert LINQ. Comme Jon l'a mentionné, XmlReader n'est pas très convivial. Si vous rencontrez des problèmes de perf, vous voudrez peut-être l'examiner, mais si vous voulez simplement faire le travail, allez avec XmlDocument/ChildNodes en utilisant la récursivité.

Questions connexes