質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

88.04%

PowerShellの変数の扱いについて。(同じ"文字列"なのに動作が違う)

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 3,050

score 11

前提・実現したい事

XMLファイルの中から、任意のタグのみ抜き出したい。

【方法】
Excelに、抜き出したいタグを記入。(A1から下方向に向かって記入。A1~A10みたいな)
PowerShellを使用し、「XMLファイル」と「Excelファイル」を読み込み、Excelファイル中に記載されているタグを、別名付けて保存したいです。

【参照元XMLファイル】Original_XML.xml

<?xml version="1.0" encoding="utf-8"?>
<EXP_HogehogeWorkDataTable>
    <DocumentElement>

    <EXP_HogehogeWork id="EXP_HogehogeWork1">
        <RecordId>00000055643</RecordId>
        <Title>自己紹介1</Title>
        <Name>田中太</Name>
        <From>日本</From>
        <BloodType>A</BloodType>
        <Height>156cm</Height>
        <BodyWeight>120kg</BodyWeight>
        <LastUpdateDate>2015-04-20T11:13:59.000+09:00</LastUpdateDate>
    </EXP_HogehogeWork>

    <EXP_HogehogeWork id="EXP_HogehogeWork2">
        <RecordId>00000925544</RecordId>
        <Title>自己紹介2</Title>
        <Name>砂糖一</Name>
        <From>パリ</From>
        <BloodType>B</BloodType>
        <Height>185cm</Height>
        <BodyWeight>56kg</BodyWeight>
        <LastUpdateDate>2015-04-21T11:23:45.000+09:00</LastUpdateDate>
    </EXP_HogehogeWork>

    <EXP_HogehogeWork id="EXP_HogehogeWork3">
        <RecordId>00000007048</RecordId>
        <Title>自己紹介3</Title>
        <Name>関克也</Name>
        <From>ドイツ</From>
        <BloodType>O</BloodType>
        <Height>174cm</Height>
        <BodyWeight>76kg</BodyWeight>
        <LastUpdateDate>2015-04-21T20:12:02.000+09:00</LastUpdateDate>
    </EXP_HogehogeWork>

    <EXP_HogehogeWork id="EXP_HogehogeWork4">
        <RecordId>00001611089</RecordId>
        <Title>自己紹介4</Title>
        <Name>山田花子</Name>
        <From>イタリア</From>
        <BloodType>AB</BloodType>
        <Height>160cm</Height>
        <BodyWeight>67kg</BodyWeight>
        <LastUpdateDate>2015-04-23T13:23:08.000+09:00</LastUpdateDate>
    </EXP_HogehogeWork>

    </DocumentElement>
</EXP_HogehogeWorkDataTable>


【タグ一覧Excelファイル】XML_TagList.xlsx
![Excelの中身

実際のソースコード

<# 変数宣言 #>
$XmlFilePath    = "C:\powershell\Original_XML.xml"  # "XML" 参照先
$XmlSavePath    = "C:\powershell\Create_XML.xml"    # "XML" 保存先
$ExcelFilePath  = "C:\powershell\XML_TagList"       # "Excel" 参照先
$sheet_No       = 1                                 # シート番号
$ex_GyouNo      = 1                                 # 取得対象:開始行番
$ex_RetsuNo     = 1                                 # 取得対象:開始列番
$ex_Alphabet    = "A"                               # "Excel" の「列A」を指定
$TagName        = $null                             # 初期化

<# 処理開始 #>
try {
    # Excelオブジェクト作成
    $excel          = New-Object -ComObject Excel.Application
    $excel.Visible  = $false

    # 参照先Excel指定
    $book           = $excel.Workbooks.Open($ExcelFilePath)

    # シート名指定(番号で指定)
    $sheet          = $excel.Worksheets.Item($sheet_No)

    # 処理回数取得(A列より取得)
    $rows           = $sheet.UsedRange.Rows.Count
    foreach ( $max in $ex_Alphabet ) {
        $col = $excel.WorksheetFunction.CountIf($sheet.Range($max + "1:" + $max + $rows), "<>") -1
    }

    # 項目取得
    for ($i = 0; $i -lt $col; $i++) {
        $TagName += '"' + $sheet.Cells.Item($i + $ex_GyouNo, $ex_RetsuNo).Text + '"'

        <# 最後のタグ文字を取得したら終了 #>
        if ($i -eq $col -1) {       # 最後のループ処理か判断
            break                   # break:ループ処理終了
        }
        else {
            $TagName += "`,"        # タグ文字の最後にカンマ追加
        }
    }

    # Excelを閉じる
    $excel.Quit()
}
catch {
    write-host "info: $($_.Exception.Message)" -foregroundcolor red

} finally {
    # null
    $excel, $book, $sheet | ForEach-Object{$_ = $null}

    # オブジェクトの破棄
    [System.Runtime.Interopservices.Marshal]::ReleaseComObject($excel)
    [System.Runtime.Interopservices.Marshal]::ReleaseComObject($sheet)
    [System.GC]::Collect()
}

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

<#========== 問題部分 ==========#>

# XMLタグ抜き出し
$CustomXML = $xml.EXP_HogehogeWorkDataTable.DocumentElement |
    ForEach-Object {
        $_[$TagName].OuterXml
    }
<#========== 問題部分 ==========#>

# ファイル出力
$CustomXML | Out-File $XmlSavePath

ソースの説明としては、
①XML_TagList.xlsx から、タグ名を「変数:$TagName」に、【"RecordId","Name","From"】の形で取得。
②XMLファイルを読み込み、先程Excelから取得したタグ名を「変数:$TagName」指定し、取得。

発生している問題・Error Message

上記ソースコードを実行すると、エラーも出ず、別名でファイル保存が出来るのですが、作成したファイルを見てみると何も書かれていませんでした。

問題部分 と囲ったコード部分を、

<#========== 処理成功例 ==========#>

# XMLタグ抜き出し Pattern1
$CustomXML = $xml.EXP_HogehogeWorkDataTable.DocumentElement |
    ForEach-Object {
        $_["RecordId"].OuterXml
        $_["Name"].OuterXml
        $_["From"].OuterXml
    }

# -------------------------------------------------------- #

# XMLタグ抜き出し Pattern2
$TagName = "RecordId","Name","From"
$CustomXML = $xml.EXP_HogehogeWorkDataTable.DocumentElement |
    ForEach-Object {
        $_[$TagName].OuterXml
    }

# -------------------------------------------------------- #

# XMLタグ抜き出し Pattern3
$CustomXML = $xml.EXP_HogehogeWorkDataTable.DocumentElement |
    ForEach-Object {
        $_["RecordId","Name","From"].OuterXml
    }
<#========== 処理成功例 ==========#>


の様に書くと正常に取得出来ます。

  • パターン1では、タグ名を手入力により指定。
  • パターン2では、変数にタグ名を入れ、変数を指定。
  • パターン3では、パターン1の様に1ずつ記載では無く、まとめて指定。

試した事

「変数に文字列を代入した場合」 と 「Excelから取得した値(文字)」 は、型が変わるのかと思い

[string]$TagName  # 文字型指定
$TagName = @()      # 配列指定


の様に、文字型指定してもダメでした。

  パターン2の様に、変数に文字列を代入した場合は取得が出来、
Excelから取得した場合は失敗する理由が分かりません。
どなたか、ご教示頂ければと思います。
よろしくお願い致します。

補足情報(言語/FW/ツール等のVersion)

・PowerShell ver5.0
・Windows 7
・Excel拡張子(主に扱うのは、".xls" と ".xlsx")

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

check解決した方法

0

for ($i = 0; $i -lt $col; $i++) {
        $TagName += $sheet.Cells.Item($i + $ex_GyouNo, $ex_RetsuNo).Text
    }

Excelから値を取得する際に、「文字列」では無く、【配列】にした所出来ました。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 88.04%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る