Ho bisogno di un'espressione LINQ per trovare un XElement in cui il nome e gli attributi dell'elemento corrispondono a un nodo di input

StackOverflow https://stackoverflow.com/questions/155685

Domanda

Devo sostituire il contenuto di un nodo in una gerarchia XElement quando il nome dell'elemento e tutti i nomi e i valori degli attributi corrispondono a un elemento di input. (Se non è presente alcuna corrispondenza, è possibile aggiungere il nuovo elemento.)

Ad esempio, se i miei dati sono così:

<root>
  <thing1 a1="a" a2="b">one</thing1>
  <thing2 a1="a" a2="a">two</thing2>
  <thing2 a1="a" a3="b">three</thing2>
  <thing2 a1="a">four</thing2>
  <thing2 a1="a" a2="b">five</thing2>
<root>

Voglio trovare l'ultimo elemento quando chiamo un metodo con questo input:

<thing2 a1="a" a2="b">new value</thing2>

Il metodo non dovrebbe avere elementi codificati o nomi di attributo: corrisponde semplicemente all'input ai dati.

È stato utile?

Soluzione

Questo corrisponderà a ogni dato elemento con il nome esatto del tag e le coppie nome / valore dell'attributo:

public static void ReplaceOrAdd(this XElement source, XElement node)
{
    var q = from x in source.Elements()
            where x.Name == node.Name
            && x.Attributes().All(a =>node.Attributes().Any(b =>a.Name==b.Name && a.Value==b.Value))
            select x;

    var n = q.LastOrDefault();

    if (n == null) source.Add(node);
    else n.ReplaceWith(node);                                              
}

var root = XElement.Parse(data);
var newElem =XElement.Parse("<thing2 a1=\"a\" a2=\"b\">new value</thing2>");

root.ReplaceOrAdd(newElem);

Altri suggerimenti

Puoi fare un XPathSelectElement con il percorso (non citarmi, sono stato al bar; pulirò la mattina) / root / thing2 [@ a1 = 'a' e @ a2 = 'b'] e quindi prendere .LastOrDefault () (XPathSelectElement è un metodo di estensione in system.Linq.Xml).

Questo ti porterà il nodo che desideri cambiare. Non sono sicuro di come tu voglia cambiarlo, comunque. Il risultato che ottieni è l'attuale XElement, quindi cambiandolo cambierà l'elemento dell'albero.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top