要素名と属性が入力ノードと一致するXElementを見つけるためにLINQ式が必要です
-
03-07-2019 - |
質問
要素名とすべての属性名と値が入力要素と一致する場合、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