Мне нужно выражение LINQ, чтобы найти XElement, где имя элемента и атрибуты соответствуют входному узлу - PullRequest
5 голосов
/ 01 октября 2008

Мне нужно заменить содержимое узла в иерархии XElement, когда имя элемента и все имена и значения атрибутов соответствуют элементу ввода. (Если совпадений нет, можно добавить новый элемент.)

Например, если мои данные выглядят так:

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

Я хочу найти последний элемент при вызове метода с таким вводом:

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

Метод не должен иметь жестко запрограммированных имен элементов или атрибутов - он просто сопоставляет ввод с данными.

Ответы [ 2 ]

5 голосов
/ 01 октября 2008

Это будет соответствовать любому данному элементу с точным именем тега и парами имя / значение атрибута:

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);
0 голосов
/ 01 октября 2008

Вы можете сделать XPathSelectElement с путем (не заключайте меня в кавычки, был в баре; уберут по утрам) / root / thing2 [@ a1 = 'a' and @ a2 = 'b'] затем возьмите .LastOrDefault () (XPathSelectElement - это метод расширения в system.Linq.Xml).

Это даст вам узел, который вы хотите изменить. Однако я не уверен, как вы хотите это изменить. В результате вы получите реальный XElement, поэтому при его изменении изменится элемент дерева.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...