0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

MySQL(mysqlコマンド)の実行結果をXMLにしてPowerShellで扱う

Last updated at Posted at 2025-02-20

この記事は、先日書いた以下の記事のMySQL(mysqlコマンド)版です。

まずは結果から

サンプルスクリプトは以下のGistに格納しました。
https://gist.github.com/noobow34/42384dc343f2df44793b3bff7261fc70

PS C:\> .\Get-MySqlXmlData.ps1                                                      
-----------行を指定して使用する-----------

SEQ2 SEQ
---- ---
3    2
-----------行と列を指定して使用する-----------
3
-----------ループで処理する場合-----------
1:2
2:3
3:4
4:5
5:6
6:7
7:8
8:9
9:10
10:11

やりかた

扱うデータ

Oracle版で使ったのと同じ結果になるSQLをChatGPTに作ってもらいました。

WITH RECURSIVE Numbers AS (
    SELECT 1 AS SEQ
    UNION ALL
    SELECT SEQ + 1 FROM Numbers WHERE SEQ < 10
)
SELECT SEQ, SEQ + 1 AS SEQ2 FROM Numbers;

image.png

PS C:\> @"
>> WITH RECURSIVE Numbers AS (
>>     SELECT 1 AS SEQ
>>     UNION ALL
>>     SELECT SEQ + 1 FROM Numbers WHERE SEQ < 10
>> )
>> SELECT SEQ, SEQ + 1 AS SEQ2 FROM Numbers;
>> "@ | mysql -u user
SEQ     SEQ2
1       2
2       3
3       4
4       5
5       6
6       7
7       8
8       9
9       10
10      11

mysqlの出力をXMLにする

なんとmysqlコマンドは--xmlオプションをつけるだけで出力がXMLになります。簡単じゃん!と思ったのですが、出力が以下のようになります。

PS C:\> @"
>> WITH RECURSIVE Numbers AS (
>>     SELECT 1 AS SEQ
>>     UNION ALL
>>     SELECT SEQ + 1 FROM Numbers WHERE SEQ < 10
>> )
>> SELECT SEQ, SEQ + 1 AS SEQ2 FROM Numbers;
>> "@ | mysql -u user --xml
<?xml version="1.0"?>

<resultset statement="WITH RECURSIVE Numbers AS (
    SELECT 1 AS SEQ
    UNION ALL
    SELECT SEQ + 1 FROM Numbers WHERE SEQ &lt; 10
)
SELECT SEQ, SEQ + 1 AS SEQ2 FROM Numbers" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <row>
        <field name="SEQ">1</field>
        <field name="SEQ2">2</field>
  </row>

  <row>
        <field name="SEQ">2</field>
        <field name="SEQ2">3</field>
  </row>

  <row>
        <field name="SEQ">3</field>
        <field name="SEQ2">4</field>
  </row>

  <row>
        <field name="SEQ">4</field>
        <field name="SEQ2">5</field>
  </row>

  <row>
        <field name="SEQ">5</field>
        <field name="SEQ2">6</field>
  </row>

  <row>
        <field name="SEQ">6</field>
        <field name="SEQ2">7</field>
  </row>

  <row>
        <field name="SEQ">7</field>
        <field name="SEQ2">8</field>
  </row>

  <row>
        <field name="SEQ">8</field>
        <field name="SEQ2">9</field>
  </row>

  <row>
        <field name="SEQ">9</field>
        <field name="SEQ2">10</field>
  </row>

  <row>
        <field name="SEQ">10</field>
        <field name="SEQ2">11</field>
  </row>
</resultset>

各列が列名のタグではなくfieldタグでname属性に列名という形なので、そのままXML型でPowerShellの変数に入れても$row.SEQの様に列名で扱うことができません。
そこで、簡単に列名で扱えるようにするためにカスタムオブジェクトに変換する関数をかませることにしました。この関数はChatGPTにサクッと作ってもらいました。

function Convert-XmlToCustomObject {
    param (
        [Parameter(ValueFromPipeline)] [xml]$xml
    )

    process {
         # すべての <row> 要素をカスタムオブジェクトに変換
        $rows = $xml.resultset.row | ForEach-Object {
            $properties = @{}
            
            # 各 <field> 要素の name 属性をプロパティ名に、#text の値をプロパティ値にする
            $_.field | ForEach-Object {
                $properties[$_.name] = $_.'#text'
            }

            # PSCustomObject に変換
            [PSCustomObject]$properties
        }
        return $rows
    }
}

mysqlコマンドの結果を上記の関数に渡せばカスタムオブジェクトの出来上がりです。

$xml = [xml]($execSql | mysql -u user --xml) | Convert-XmlToCustomObject

カスタムオブジェクトの扱い方

$xml自体が行の配列になっているので$xml[0]の様にインデックスを指定して扱います。あとは、$xml[0].SEQの様に列名をそのままプロパティとして扱えます。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?