いろいろ備忘録日記

主に .NET と Python絡みのメモを公開しています。

Linq入門記-65 (LINQ to XML, 要素の更新, Value, SetValue, SetElementValue)

LINQ to XMLでの要素の更新について.

過去の内容は以下から見れます。よろしければご参照くださいませ。


XElementには、要素の更新を行うためのメソッドがいくつか存在します。

Value { get; set; }
SetValue(object)
SetElementValue(XName, object)


元定義は以下のようになっています。

XElement.Value { get; set; }
XElement.SetValue(object)
XElement.SetElementValue(XName, object)


上記のメソッドの中でSetElementValueメソッドのみが
ちょっと特殊です。このメソッドは、自分自身ではなく
子要素の値を更新します。その際

  • 要素が存在する場合は、その要素の値を更新
  • 要素が存在しない場合は、新たに要素を作成
  • 値にnullを設定した場合は、子要素を削除

という動きになります。


以下、サンプルです。

  #region LinqSamples-61
  /// <summary>
  /// LINQ to XMLのサンプルです.
  /// </summary>
  /// <remarks>
  /// 要素更新系メソッドのサンプルです.
  /// </remarks>
  public class LinqSamples61 : IExecutable
  {
    public void Execute()
    {
      //
      // Value { get; set; } プロパティ
      //   対象の要素の値を取得・設定する.
      //   型がstringとなっているので、文字列に変換して設定する必要がある。
      //   nullを指定すると例外が発生する。(ArgumentNullException)
      //
      var root = BuildSampleXml();
      var elem = root.Descendants("Value").First();
      
      Console.WriteLine("[before] {0}", elem.Value);
      elem.Value = "updated";
      Console.WriteLine("[after] {0}", elem.Value);
      Console.WriteLine(root);
      
      try
      {
        elem.Value = null;
      }
      catch (ArgumentNullException argNullEx)
      {
        Console.WriteLine(argNullEx.Message);
      }
      
      // Valueプロパティはstringを受け付けるので、boolなどの場合は
      // 明示的に文字列にして設定する必要がある.
      elem.Value = bool.TrueString.ToLower();
      Console.WriteLine(root);
      
      Console.WriteLine("=====================================");
      
      //
      // SetValue(object)
      //   要素の値を設定する。
      //   型がobjectとなっているので、文字列以外の場合でもそのまま設定可能。
      //   内部で変換される.
      //   nullを指定すると例外が発生する。(ArgumentNullException)
      //
      root = BuildSampleXml();
      elem = root.Descendants("Value").First();
      
      Console.WriteLine("[before] {0}", elem.Value);
      elem.SetValue("updated");
      Console.WriteLine("[after] {0}", elem.Value);
      Console.WriteLine(root);
      
      try
      {
        elem.SetValue(null);
      }
      catch (ArgumentNullException argNullEx)
      {
        Console.WriteLine(argNullEx.Message);
      }
      
      // SetValueメソッドは、object型を受け付けるので
      // bool型などの場合でもそのまま設定できる。内部で変換される.
      elem.SetValue(true);
      Console.WriteLine(root);
      
      Console.WriteLine("=====================================");
      
      //
      // SetElementValue(XName, object)
      //   子要素の値を設定する。
      //     要素が存在しない場合: 新規追加
      //     要素が存在する場合: 更新
      //     nullを設定した場合: 削除
      //   となる。自分自身の値を設定するわけでは無いことに注意。
      //
      root = BuildSampleXml();
      elem = root.Elements("Child").First();
      
      // 要素が存在する場合: 更新
      elem.SetElementValue("Value", "updated");
      Console.WriteLine(root);
      
      // nullを指定した場合: 削除
      root = BuildSampleXml();
      elem = root.Elements("Child").First();
      elem.SetElementValue("Value", null);
      Console.WriteLine(root);
      
      // 要素が存在しない場合: 新規追加
      root = BuildSampleXml();
      elem = root.Elements("Child").First();
      elem.SetElementValue("Value2", "inserted");
      Console.WriteLine(root);
      
      Console.WriteLine("=====================================");
    }
    
    XElement BuildSampleXml()
    {
      return new XElement("Root",
                   new XElement("Child", 
                     new XAttribute("Id", 100),
                     new XElement("Value", "hoge")
                   )
                 );
    }
  }
  #endregion

実行すると以下のようになります。

  [before] hoge
  [after] updated
  
    
      updated
    
  
  値を Null にすることはできません。
  パラメーター名: value
  
    
      true
    
  
  =====================================
  [before] hoge
  [after] updated
  
    
      updated
    
  
  値を Null にすることはできません。
  パラメーター名: value
  
    
      true
    
  
  =====================================
  
    
      updated
    
  
  
    
  
  
    
      hoge
      inserted
    
  
  =====================================


以下、参考リソースです.

================================
過去の記事については、以下のページからご参照下さい。

サンプルコードは、以下の場所で公開しています。