Voie (s) pour extraire des valeurs de noeuds sélectionnés à partir de ce balisage XML
Question
Compte tenu des (spécimen - réel balisage peut être beaucoup plus compliqué) le balisage et les contraintes énumérées ci-dessous, tout le monde pourrait proposer une solution (C #) plus efficace / efficace que la marche l'arbre entier pour récupérer { « @@ valeur1 @@ », « @@ valeur2 @@ », « @@ value3 @@ »}, soit une liste de jetons qui vont être remplacés lorsque le balisage est effectivement utilisé.
Note:. Je n'ai pas de contrôle sur le balisage, la structure du balisage ou le format / dénomination des jetons qui sont remplacés
<markup>
<element1 attributea="blah">@@value1@@</element1>
<element2>@@value2@@</element2>
<element3>
<element3point1>@@value1@@</element3point1>
<element3point2>@@value3@@</element3point2>
<element3point3>apple</element3point3>
<element3>
<element4>pear</element4>
</markup>
La solution
Que diriez-vous:
var keys = new HashSet<string>();
Regex.Replace(input, "@@[^@]+@@", match => {
keys.Add(match.Value);
return ""; // doesn't matter
});
foreach (string key in keys) {
Console.WriteLine(key);
}
- ne dérange pas l'analyse XML (juste de la manipulation de chaînes)
- ne comprend que les uniques valeurs (pas besoin de retourner un
MatchCollection
avec les doublons que nous ne voulons pas)
Cependant, il peut construire une chaîne plus grande, donc peut-être juste Matches
:
var matches = Regex.Matches(input, "@@[^@]+@@");
var result = matches.Cast<Match>().Select(m => m.Value).Distinct();
foreach (string s in result) {
Console.WriteLine(s);
}
Autres conseils
J'ai écrit un prog rapide avec votre échantillon, cela devrait faire l'affaire.
class Program
{
//I just copied your stuff to Test.xml
static void Main(string[] args)
{
XDocument doc = XDocument.Load("Test.xml");
var verbs=new Dictionary<string,string>();
//Add the values to replace ehre
verbs.Add("@@value3@@", "mango");
verbs.Add("@@value1@@", "potato");
ReplaceStuff(verbs, doc.Root.Elements());
doc.Save("Test2.xml");
}
//A simple replace class
static void ReplaceStuff(Dictionary<string,string> verbs,IEnumerable<XElement> elements)
{
foreach (var e in elements)
{
if (e.Elements().Count() > 0)
ReplaceStuff(verbs, e.Elements() );
else
{
if (verbs.ContainsKey(e.Value.Trim()))
e.Value = verbs[e.Value];
}
}
}
}