Preciso de uma expressão LINQ para encontrar um Xelement onde o nome e os atributos do elemento correspondam a um nó de entrada

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

Pergunta

Preciso substituir o conteúdo de um nó em uma hierarquia XElement quando o nome do elemento e todos os nomes e valores dos atributos correspondem a um elemento de entrada. (Se não houver correspondência, o novo elemento pode ser adicionado.)

Por exemplo, se meus dados se parecem com os seguintes:

<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>

Quero encontrar o último elemento quando chamo um método com esta entrada:

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

O método não deve ter nomes de elemento codificado ou atributo - ele simplesmente corresponde à entrada dos dados.

Foi útil?

Solução

Isso corresponderá a qualquer elemento com o nome exato da tag e o nome do atributo/valores:

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);

Outras dicas

Você pode fazer um XPathSelectElement com o caminho (não me cite, esteve na barra; limpará de manhã) /raiz /thing2 [ @a1 = 'a' e @a2 = 'b'] e depois tomar. LastordEfault () (XpathSelectElement é um método de extensão no System.linq.xml).

Isso lhe dará o nó que você deseja mudar. Não tenho certeza de como você deseja mudar isso, no entanto. O resultado que você obtém é o Xelement real, portanto, alterar o elemento da árvore.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top