C# 我需要一个 LINQ 表达式来查找元素名称和属性与输入节点匹配的 XElement

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/155685/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-03 16:00:54  来源:igfitidea点击:

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

提问by Wonko

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

当元素名称和所有属性名称和值与输入元素匹配时,我需要替换 XElement 层次结构中节点的内容。(如果没有匹配项,则可以添加新元素。)

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 have no hard-coded element or attribute names - it simply matches the input to the data.

该方法不应该有硬编码的元素或属性名称——它只是将输入与数据相匹配。

采纳答案by Mark Cidade

This will match any given element with 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);

回答by Wonko

You can do an XPathSelectElement with the path (don't quote me, been to the bar; will clean up in the morn) /root/thing2[@a1='a' and @a2='b'] and then take .LastOrDefault() (XPathSelectElement is an extension method in system.Linq.Xml).

你可以用路径做一个 XPathSelectElement(不要引用我,去过酒吧;早上会清理) /root/thing2[@a1='a' and @a2='b'] 然后取 . LastOrDefault()(XPathSelectElement 是 system.Linq.Xml 中的扩展方法)。

That will get you the node you wish to change. I'm not sure how you want to change it, however. The result you get is the actual XElement, so changing it will change the tree element.

这将为您提供您希望更改的节点。但是,我不确定您想如何更改它。您得到的结果是实际的 XElement,因此更改它会更改树元素。