I need a LINQ expression to find an XElement where the element name and attributes match the input of node

I need to replace the contents of the node in the XElement hierarchy when the element name and all attribute names and values ​​match the input element. (If there is no match, you can add a new item.)

For example, if my data looks like this:

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

I want to find the last element when I call a method with this input:

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

The method should not have any hard-coded elements or attribute names - it just matches the data entry.

+5
source share
2 answers

This will match any element with the exact tag name and attribute name / value pairs:

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

XPathSelectElement ( , , )/root/thing2 [@a1 = 'a' @a2 = 'b'] .LastOrDefault() (XPathSelectElement - system.Linq.Xml).

node, . , . , , XElement, .

0

All Articles