要素名と属性が入力ノードと一致するXElementを見つけるためにLINQ式が必要です

StackOverflow https://stackoverflow.com/questions/155685

質問

要素名とすべての属性名と値が入力要素と一致する場合、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なので、変更するとツリー要素が変更されます。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top