Manera (s) para extraer valores de los nodos seleccionados de este marcado de XML
Pregunta
En vista de las muestras (- marcado real puede ser considerablemente más complicado) de marcado y las limitaciones que figuran a continuación, podría alguien proponer una solución (C #) más eficaz / eficiente que andar todo el árbol para recuperar { "@@ @@ valor1", "valor2 @@ @@", "@@ value3 @@"}, es decir, una lista de símbolos que van a ser reemplazados cuando el marcado se utiliza realmente.
Nota:. No tengo ningún control sobre el marcado, la estructura del formato de marcado o / denominación de las fichas que están siendo reemplazados
<markup>
<element1 attributea="blah">@@value1@@</element1>
<element2>@@value2@@</element2>
<element3>
<element3point1>@@value1@@</element3point1>
<element3point2>@@value3@@</element3point2>
<element3point3>apple</element3point3>
<element3>
<element4>pear</element4>
</markup>
Solución
¿Qué hay de:
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);
}
Este:
- no se molesta análisis del XML (solo la manipulación de cadenas)
- sólo incluye los valores únicos (sin necesidad de devolver un
MatchCollection
con los duplicados que no queremos)
Sin embargo, se puede construir una cadena más grande, por lo que tal vez sólo Matches
:
var matches = Regex.Matches(input, "@@[^@]+@@");
var result = matches.Cast<Match>().Select(m => m.Value).Distinct();
foreach (string s in result) {
Console.WriteLine(s);
}
Otros consejos
escribí un prog rápido con su muestra, esto debería hacer el truco.
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];
}
}
}
}