2010-11-08 18 views
0

Ceci est une question de conception, pour aiguiser l'appétit du gourou.Construction dynamique de l'arbre xml pendant l'exécution en utilisant linq

Dans une version précédente, le code utilisait une définition de chemin, c'est-à-dire /../../, pour fournir des instructions sur la façon de créer des documents xml d'artbitary. Les documents devaient être corrects selon le schéma xml, donc les chemins étaient essentiellement xpaths, étant lus et utilisés dans les instructions switch pour appeler le code pour construire le doc. Mais ne vous attardez pas dessus.

Par exemple l'appel lors de la lecture et un code

jim.set("/Alert/Source/DetectTime", "12:03:2010 12:22:21"); 

créerait

<Alert> 
    <Source> 
    <DetectTime>12:03:2010 12:22:21</DetectTime> 
    </Source> 
</Alert> 

Le jim.set stocke juste l'arbre dans un contexte particulier. Maintenant, je voudrais utiliser linq pour xsd, pour créer l'arbre xml, mais je cherche toujours une structure qui permettra à un utilisateur de définir comment l'arbre sera construit. Les XPath sont faciles, mais un peu encombrants à mettre en œuvre, pas élégants et je ne cartographie pas facilement. Toutes les idées, tous les programmes, l'open source, la recherche, tout serait apprécié. Si je ne reçois pas de réponse, je vais offrir une prime décente dans 3 jours. Bob.

Répondre

1

Que diriez-vous de faire quelque chose comme ceci:

public XDocument CreateXDocument(string path, string value) 
{ 
    var parts = path.Split(new [] { '/', }, 
     StringSplitOptions.RemoveEmptyEntries); 
    return new XDocument(this.CreateXElement(parts, value)); 
} 

private XElement CreateXElement(IEnumerable<string> parts, string value) 
{ 
    var content = parts.Count() == 1 ? 
     (object)value : 
     (object)this.CreateXElement(parts.Skip(1), value); 
    return new XElement(parts.First(), content); 
} 

Vous pouvez alors exécuter le code comme ceci:

var xd = this.CreateXDocument("/Alert/Source/DetectTime", "12:03:2010 12:22:21"); 
Console.WriteLine(xd.ToString()); 

qui produira:

<Alert> 
    <Source> 
    <DetectTime>12:03:2010 12:22:21</DetectTime> 
    </Source> 
</Alert> 

Je pensais que Je pourrais poster une variation du CreateXElement méthode qui devrait être plus lisible. La fonctionnalité est la même et il peut même y avoir une amélioration marginale des performances.

private XElement CreateXElement(IEnumerable<string> parts, string value) 
{ 
    var head = parts.First(); 
    var tail = parts.Skip(1); 
    var content = tail.Any() ? 
     (object)this.CreateXElement(tail, value) : 
     (object)value; 
    return new XElement(head, content); 
} 
+0

Enigmativité, Merci pour la réponse rapide. Comment voulez-vous ajouter un attribut "id" pour dire, l'élément Source, après qu'il a été créé.? –

+0

Le plus. Approprié. Nom d'utilisateur. Déjà. –

+0

@ 'scope_creep' - Vous pouvez l'ajouter ensuite en faisant ceci:' xd.Descendants ("Source"). First(). Add (nouveau XAttribute ("id", 42)); '. Vous pouvez aussi l'ajouter en prolongeant mon approche et en divisant chaque partie (ie 'head' ou' parts.First() ') par un autre séparateur, disons" | ". – Enigmativity