Power Automate for DesktopでXMLの繰り返しデータを処理

Power Automate for Desktopを使って繰り返し要素が現れるデータを処理したので、それについて書いてみます。

(しらないうちに、Power Automate DesktopからPower Automate for Desktopに名前が変わっていたようです)


繰り返し処理が必要なXML

以前処理したXMLは一つのファイルに一つの名前の要素が存在していました。

Power Automate DesktopでDTDと名前空間があるXMLファイルを読む

今回は次のAreaやSiteのように繰り返し処理する必要がある複数の同じ名前の要素が存在しています。

<?xml version="1.0" encoding="utf-8" ?>
<CampSite>
<CampSiteName>Adatara</CampSiteName>
<Area>
<AreaName>A</AreaName>
<Site>
<SiteName>01</SiteName>
<Width>10</Width>
<Height>10</Height>
</Site>
<Site>
<SiteName>02</SiteName>
<Width>7</Width>
<Height>15</Height>
</Site>
</Area>
<Area>
<AreaName>B</AreaName>
<Site>
<SiteName>01</SiteName>
<Width>15</Width>
<Height>15</Height>
</Site>
</Area>
</CampSite>


For eachを使う方法

For eachを使って処理するという方法があります。

例えば次のようにXMLファイルを読み取って、Childrenを処理していく方法です。


1回目の表示

2回目の表示

For eachで取得したデータをさらにFor eachで処理して孫も見るようにします。

コードは次の通り(Power Automate Desktopにコピペできます)

XML.ReadFromFile File: $'''C:\\NKTemp\\CampSiteInfo.xml''' Encoding: XML.FileEncoding.DefaultEncoding XmlDocument=> XmlDocument
LOOP FOREACH CurrentItem IN XmlDocument.Children
    Display.ShowMessageDialog.ShowMessage Message: CurrentItem.Name Icon: Display.Icon.None Buttons: Display.Buttons.OK DefaultButton: Display.DefaultButton.Button1 IsTopMost: False ButtonPressed=> ButtonPressed
    LOOP FOREACH CurrentItem2 IN CurrentItem.Children
        Display.ShowMessageDialog.ShowMessage Message: CurrentItem2.Name Icon: Display.Icon.None Buttons: Display.Buttons.OK DefaultButton: Display.DefaultButton.Button1 IsTopMost: False ButtonPressed=> ButtonPressed
    END
END

以下は実行結果





同様にして、さらに深い階層まで処理するというのも一つです。

If や Case アクションを使って処理するとよいでしょう。


XPathを使う

For eachを使う方法でも処理することは可能ですが、深いところに処理したい要素があるときや、同じ階層に複数の別の名前の要素が含まれる時にはフローが冗長になります。

「XPath式を実行します」アクションを使うと、素早く欲しい階層の任意の要素を取得できます。

「解析するドキュメント」にはファイルから読み込むなどしたXML変数を指定します。

「XPathクエリ」には /CampSite/Areaを指定します。(ここでは/Campsiteとして/から始めて絶対パス指定にしていますが、CampSite/Areaと相対パス指定しても結果は同じです)

実行すると次の値が取得できます。

アクションで取得したXPathResultsをFor eachに指定します。

実行すると次の表示が二回行われます。

余分なデータを省いて、目的のデータを取得することができます。


要素の値を取得する

上の例では、要素の名前を表示しているだけですが、実際には値を取得する必要があります。次は値を取得する例です。

For eachの結果を uAreaに保存します。

「XML要素の値を取得します」アクションを使います。
「XMLドキュメント」にはFor eachで取得した uAreaを指定します。
「XPathクエリ」にはAreaNameを指定します。
「生成された変数」名には uAreaNameを指定します。

メッセージボックスでは、取得したuAreaNameを表示しています。

実行結果は次の通りです。


要素の値を取得できています。


XPathの順番を指定する

stack overflowに一番目の属性を取り出すにはどうすりゃいいの? という質問が投稿されていました。

これはXPathを使う事により容易に実現可能です。

例えば一番目のAreaNameを取り出したい場合には「XML要素の値を取得します」アクションに次のように指定します。

「XMLドキュメント」には Xmldocument を指定します。
「XPathクエリ」には CampSite/Area[1]/AreaName を指定します。

[1]で1番目の要素を指定しています。[2]を指定すれば2番目の要素です。

次のフローを実行すると

次のようにuAreaNameに「A」が代入されます。


属性についても大差がありません。
いずれ属性の例も追加してみたいと思います。
また、ノードとリストの違いについても説明したいと思います。


2022/4/17 追記

テキストデータをXMLに変換する方法を投稿してみました。


コメント

アクセス数の多い投稿

セキュリティ対策ソフトのノートンが詐欺ソフトまがいになってしまってショック

ZIPファイルを開こうとすると、展開を完了できません、と言われる

Windows セキュリティーのビックリマークが消えない

突然滅茶苦茶遅くなったPCがWindows Updateのキャッシュクリアで復活

Power Automate Desktopでブラウザでダウンロードしたファイルを処理する

NEC Aterm WX5400HP をセットアップ

Excel 2019 クエリが原因で日本語入力の一文字目が勝手に確定する

Excel VBAからODBCを使ってデータを簡単に取得する

Teamsで日本語入力すると左上に変換ウィンドウが出る

ChatGPTが日本語からVBAのコードを生成できてたまげる