我需要一个LINQ表达式来找到一个XElement,其中元素名称和属性与输入节点匹配
时间:2020-03-06 14:57:18 来源:igfitidea点击:
当元素名称以及所有属性名称和值与输入元素匹配时,我需要替换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>
该方法应该没有硬编码的元素或者属性名称,它只将输入与数据匹配即可。
解决方案
我们可以使用以下路径执行XPathSelectElement(不要引用我,去过酒吧;将在早晨清理)/ root / thing2 [@ a1 ='a'和@ a2 ='b'],然后使用。 LastOrDefault()(XPathSelectElement是system.Linq.Xml中的扩展方法)。
这将为我们提供我们想要更改的节点。不过,我不确定我们要如何更改它。我们得到的结果是实际的XElement,因此对其进行更改将更改tree元素。
这将匹配具有给定标签名称和属性名称/值对的任何给定元素:
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);