🗞️

Power Automate Desktop で「XML 要素の属性を取得」

2024/10/23に公開

XML ファイルの編集を PAD で自動化して楽したい

  1. Power Automate Desktop で XML ファイルの編集
  2. Power Automate Desktop で XML - XPath 式
  3. Power Automate Desktop テキストをハッシュ化

以前作成したフローで、次は 10 月実施といいました。で、結果めちゃくちゃ楽になりました。コピペで定義を作るような作業は自動化するに限りますね。

調子に乗って他のファイルも同じように楽したくなったので作りました。

同じような作業なのでフローをコピペしてちょっと変えただけ。流れはだいたい一緒。
とはいえ、 XML ファイルの構成がちょっと違うのでそこは修正しました。

今回の XML ファイルはこうなっています。

定義ファイル
<?xml version="1.0" encoding="utf-8"?>
<Filters>
  <Filter priority="1000" type="Regex" hitAction="Filtering" text=".*AAA.*" />
  <Filter priority="1001" type="Regex" hitAction="Filtering" text=".*BBB.*" />
  <Filter priority="1002" type="Regex" hitAction="Filtering" text=".*CCC.*" />
</Filters>
  • Point
    1. Priority が連番になっているので、要素を追加するときに数値を大きくします。
    2. Priority が何番まであるのか調べる必要があります。

最後の要素を取得したいときはlast()を指定します。
最後の Filter 要素を取得したいなら

XPath クエリ
//Filter[last()]

最後の Filter 要素の中から priority 属性を取得するには、以下のような Xpath クエリを使用します。

XPath クエリ
//Filter[last()]/@priority

XPath 式を実行します

[XPath 式を実行します]を使って取得した場合

値にpriority="1634"と入ってしまいます。数値だけ欲しいのでちょっと不便です。

XML 要素の属性を取得

[XML 要素の属性を取得]を使う

値に数値のみ入るので、その後のアクションで使いやすいです。

重複して追加しないように調べる

タイトルが既に存在するか調べて、あったら処理をスキップ。なかったら定義を追加するようにしたい。

以下のクエリでありかなしか調べることができます。

XPath クエリ
//Filter[contains(@text, "%タイトル%")]

他は前回と一緒です。

また何か思いついたらフローにして記事にします。


コード

FUNCTION Registration GLOBAL
    XML.ReadFromFile File: $'''%OneDrive%%MasterFile%''' Encoding: XML.FileEncoding.DefaultEncoding XmlDocument=> XmlDocument
    ON ERROR DirectoryNotFoundError
        SET ErrorMsg TO $'''ディレクトリが見つかりません。'''
        CALL Catch
        THROW ERROR
    ON ERROR FileNotFoundError
        SET ErrorMsg TO $'''ファイルが見つかりません。'''
        CALL Catch
        THROW ERROR
    ON ERROR ReadFileError
        SET ErrorMsg TO $'''ファイルを読み取れませんでした。'''
        CALL Catch
        THROW ERROR
    ON ERROR InvalidFileError
        SET ErrorMsg TO $'''ファイルに有効な XML ドキュメントが含まれていません。'''
        CALL Catch
        THROW ERROR
    END
    Cryptography.HashText HashAlgorithm: Cryptography.HashAlgorithm.SHA256 Encoding: Cryptography.EncryptionEncoding.Unicode TextToHash: XmlDocument HashedText=> HashedTextA
    XML.GetXmlElementAttribute.GetElementAttributeAsNumeric Document: XmlDocument XPathQuery: $'''//Filter[last()]''' AttributeName: $'''priority''' NumericValue=> Priority
    LOOP FOREACH タイトル IN 作品リスト
        CALL Now
        XML.ExecuteXPathQuery.ExecuteXPath XmlDocument: XmlDocument XPathQuery: $'''//Filter[contains(@text, \"%タイトル%\")]''' XPathResults=> XPathResults
        IF IsNotEmpty(XPathResults) THEN
            Text.AppendLine Text: Log LineToAppend: $'''%CurrentDateTime% INFO Skip %タイトル%''' Result=> Log
            NEXT LOOP
        END
        Text.AppendLine Text: Log LineToAppend: $'''%CurrentDateTime% INFO Set %タイトル%''' Result=> Log
        **REGION 定義ファイルに追加
        Variables.IncreaseVariable Value: Priority IncrementValue: 1
        XML.InsertElement Document: XmlDocument XPathQuery: $'''Filters''' Element: $'''<Filter priority=\"%Priority%\" type=\"Regex\" hitAction=\"Filtering\" text=\".*%タイトル%.*\"/>'''
        **ENDREGION
    END
    Cryptography.HashText HashAlgorithm: Cryptography.HashAlgorithm.SHA256 Encoding: Cryptography.EncryptionEncoding.Unicode TextToHash: XmlDocument HashedText=> HashedTextB
    IF HashedTextA <> HashedTextB THEN
        XML.WriteXmlToFile.WriteToFileFormatted File: $'''%OneDrive%%MasterFile%''' Xml: XmlDocument Encoding: XML.FileEncoding.UTF8 Indentation: 2
        ON ERROR REPEAT 3 TIMES WAIT 15
        END
    END
END FUNCTION

設定ファイル

AppConfig
{
    "AppSettings": {
        "StoreLog": "\\fslog.txt",
        "MasterFile": "\\hogehoge\\filter.xml"
    }
}

Discussion