我需要一个LINQ表达式来查找一个XElement,其中元素名称和属性与输入节点匹配
-
03-07-2019 - |
题
当元素名称和所有属性名称和值与input元素匹配时,我需要替换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>
该方法不应具有硬编码元素或属性名称 - 它只是将输入与数据匹配。
解决方案
这将使任何给定元素与精确标记名称和属性名称/值对匹配:
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);
其他提示
你可以用路径做一个XPathSelectElement(不要引用我,去过吧;将在清晨清理)/ root / thing2 [@ a1 ='a'和@ a2 ='b']和然后使用.LastOrDefault()(XPathSelectElement是system.Linq.Xml中的扩展方法)。
这将为您提供您想要更改的节点。但是,我不确定你想怎么改变它。得到的结果是实际的XElement,因此更改它将改变树元素。
不隶属于 StackOverflow