2016-06-11

PowerShellでxmlファイルを操作する - 書き込み(保存)編 -

PowerShellでは、ユーザーの好みに合わせて、独自にフォームを作成することができます。

今回は「PowerShellでユーザーフォームを作る - 設定ファイル 書き込み(保存)編 -」です。

以前の記事で設定ファイルを読み込む方法をご紹介致しました。
PowerShellでユーザーフォームを作る - 設定ファイル 読み込み編 -

しかし、設定ファイルの内容は読み込むばかりではなく、書き込んでナンボですね。

よって、今回は「読み込み編」で使用したものを流用し、新しい内容を書き込み(保存)まで行う方法をご紹介していきます。

使用するxmlファイルの内容は前回と同じく下記の通りです。

 [ setting.xml ]
<?xml version="1.0" encoding="utf-8"?>
<root>
    <name>山田太郎</name>
    <userid>t_yamada</userid>
    <path>C:\Users\t_yamada\Desktop</path>
    <color>lightblue</color>
</root>
 続いてスクリプトを記述していきます。


# PowerShellでユーザーフォームを作る - 設定ファイル 書き込み(保存)編 -

# xmlの事前処理 = = = = = = = = = = = = = = = = = = = = = = = = = #
#xmlファイルのパス
$xmlPath = "setting.xml"

#xmlファイルの読み込み
$xml = [XML](Get-Content $xmlPath)

#それぞれを取得し、変数に格納しておく
$AAA = $xml.root.name
$BBB = $xml.root.userid
$CCC = $xml.root.path
# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = #

#アセンブリのロード
Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName System.Drawing

#フォームの作成
$form = New-Object System.Windows.Forms.Form
$form.Size = "380,200"
$form.startposition = "centerscreen"
$form.text = "設定"

#「名前」- - - - - - - - - - - - - - - - - - - - - - - - - - - - -
$NameLabel = New-Object System.Windows.Forms.Label
$NameLabel.Location = "10,10"
$NameLabel.Size = "100,20"
$NameLabel.Text = "名前"

$Name = New-Object System.Windows.Forms.TextBox
$Name.Location = "10,30"
$Name.Size = "250,20"
$Name.Text = $AAA

#「アカウントID」- - - - - - - - - - - - - - - - - - - - - - - - -
$IDLabel = New-Object System.Windows.Forms.Label
$IDLabel.Location = "10,60"
$IDLabel.Size = "100,20"
$IDLabel.Text = "アカウントID"

$ID = New-Object System.Windows.Forms.TextBox
$ID.Location = "10,80"
$ID.Size = "250,20"
$ID.Text = $BBB

#「パス」- - - - - - - - - - - - - - - - - - - - - - - - - - - - -
$PathLabel = New-Object System.Windows.Forms.Label
$PathLabel.Location = "10,110"
$PathLabel.Size = "100,20"
$PathLabel.Text = "パス"

$Path = New-Object System.Windows.Forms.TextBox
$Path.Location = "10,130"
$Path.Size = "250,20"
$Path.Text = $CCC

# 設定保存ボタン- - - - - - - - - - - - - - - - - - - - - - - - -
$SaveButton = New-Object System.Windows.Forms.Button
$SaveButton.Location = "280,120"
$SaveButton.Size = "80,30"
$SaveButton.Text = "設定保存"
$SaveButton.FlatStyle = "Flat"
$SaveButton.BackColor = "lightblue"

# 設定保存ボタンのクリックイベント
$Save = {
        # 配列を作成
        $array = ("name", "userid", "path") # 変更箇所
        $new_text = ($Name.Text, $ID.Text, $Path.Text) # 新しい要素
        
        # XpathNavigatorの作成
        $Navi = [XML.Xpath.XpathNavigator] $xml.CreateNavigator()    

        For ( $a = 0 ; $a -lt $array.Count ; $a++ )
        {
            # 変更する場所
            $position = $array[$a]

            # 新しい要素
            $text = $new_text[$a]

            # 変更する場所を指定
            $Nodes = $Navi.Select("/root/$position")

            # 値を変更
            while ( $Nodes.MoveNext() )
            {
                $Nodes.Current.SetValue("$text")
            }
        }

        # xmlファイルを上書き保存
        $xmlSetting = New-Object System.Xml.XmlWriterSettings
        $xmlSetting.Indent = $True
        $xmlWriter = [System.Xml.XmlWriter]::Create($xmlPath,$xmlSetting)
        $Navi.MoveToRoot()
        $Navi.WriteSubtree($xmlWriter)
        $xmlWriter.Close()

    [System.Windows.Forms.MessageBox]::Show("保存されました", "保存完了")
}
$SaveButton.Add_Click($Save)

$form.Controls.AddRange(@($NameLabel,$Name,$IDLabel,$ID,$PathLabel,$Path,$SaveButton))
$Form.Showdialog()

上記内容をコピーし、PowerShell ISEに貼り付け後、実行すると上の画像と同じものが表示されるはずです。

続いて解説をしていきます。

※過去の記事で解説した部分については割愛致します。  内容をご確認いただきたい場合は【ユーザーフォーム - 基礎編 -】をご覧ください。

*****解説***********************************************************
今回の内容は、上記スクリプト中のクリックイベント内の記述が対象ですので、その部分に絞って解説を行います。
# XpathNavigatorの作成
$Navi = [XML.Xpath.XpathNavigator] $xml.CreateNavigator() 
ここではXpathNavigatorクラスを使用することで、XMLファイルを操作しやすくします。
XpathNavigatorクラスについては長くなってしまうので、より深く知りたい場合は各自で調査をお願いします。
とりあえず今は「XMLファイルを編集するための準備」と思っておけば差し支えありません。

For ( $a = 0 ; $a -lt $array.Count ; $a++ )
{
    # 変更する場所
    $position = $array[$a]

    # 新しい要素
    $text = $new_text[$a]

    # 変更する場所を指定
    $Nodes = $Navi.Select("/root/$position")

    # 値を変更
    while ( $Nodes.MoveNext() )
    {
        $Nodes.Current.SetValue("$text")
    }
}
ここでは事前に作成しておいた配列の数だけForループを行い、要素を書き換えています。
手順としては、変更する場所を指定し、新しい要素を指定します。
while文内のSetValueの部分で要素を書き換えています。

# xmlファイルを上書き保存
$xmlSetting = New-Object System.Xml.XmlWriterSettings
$xmlSetting.Indent = $True
$xmlWriter = [System.Xml.XmlWriter]::Create($xmlPath,$xmlSetting)
$Navi.MoveToRoot()
$Navi.WriteSubtree($xmlWriter)
$xmlWriter.Close()
最後にXMLファイルを保存して終了です。
今回はインデントをつけるため、IndentプロパティをTrueにしていますが、必要ない場合は記述しなくても大丈夫です。
最後に必ず$xmlWriterを閉じるのを忘れないようにしてください。
********************************************************************

解説は以上となります。
今回はあまり解説になっていなくて申し訳ありません。

PowerShellでは、xmlファイルの読み込みは簡単なのですが、書き込みは面倒で、長くて、スマートではありません。
正直な話、xmlファイルの操作を私自身も完璧に覚えているかと言われると、答えは「No」です。毎回コピペですw
しかし、設定ファイルを扱う上で、書き込み処理は絶対に必要となりますので、知っておいて損はないと思います。

=============================================================
本投稿に関する疑問や質問には可能な限りお答えさせていただきます。
お気軽にコメントやメールをお送りください。
(リクエストも歓迎します)
メール:tkk-powershell@gmail.com
また、間違いのご指摘・アドバイス等も歓迎いたします。
=============================================================
Google+、Twitterで更新情報をお届けしています!
ぜひフォローをお願い致します!
=============================================================
スポンサーリンク


0 件のコメント:

コメントを投稿

疑問・質問・リクエスト お気軽にどうぞ (^O^)/