documents:proglang:powershell:powershell-008
文書の過去の版を表示しています。
目次
XML整形
2026-04-28 コピペ用
事前の知識
Chat-GPTさん情報で、PowerShell 5.1系はスクリプトを UTF-8 BOM付 で保存しておく。こうしておかないとスクリプトのパースに失敗する事があるそうだ。
※今回 xmlupdate.ps1 で実際に喰らった
XML整形
powershell 5.x シリーズ用
- xmlformatter.ps1
## powershell -NoProfile -ExecutionPolicy Bypass -File xmlformatter.ps1 XMLファイル名 param( [Parameter(Mandatory = $true)] [string] $InputPath ) if (Test-Path $InputPath) { $dir = (Get-Location).Path $base = [System.IO.Path]::GetFileNameWithoutExtension($InputPath) $OutputPath = [System.IO.Path]::Combine($dir, ($base + ".new.xml")) } else { Write-Host "ファイルなし" exit } ## 整形用にインデントを指示 $settings = New-Object System.Xml.XmlWriterSettings $settings.Indent = $true ## XML読み込み $xmldoc = New-Object System.Xml.XmlDocument $xmldoc.Load($InputPath) ## XML整形結果書き出し $writer = [System.Xml.XmlWriter]::Create($OutputPath, $settings) $xmldoc.Save($writer) $writer.Close()
powershell 7.x シリーズ用
- xmlformatter.ps1
## pwsh -NoProfile -ExecutionPolicy Bypass -File xmlformatter.ps1 XMLファイル名 param( [Parameter(Mandatory = $true)] [string] $InputPath ) Add-Type -AssemblyName System.Xml.Linq if (Test-Path $InputPath) { $dir = (Get-Location).Path $base = [System.IO.Path]::GetFileNameWithoutExtension($InputPath) $OutputPath = [System.IO.Path]::Combine($dir, ($base + ".new.xml")) } else { Write-Host "ファイルなし" exit } ## 整形用にインデントを指示 $settings = [System.Xml.Linq.SaveOptions]::None ## XML読み込み $xmldoc = [System.Xml.Linq.XDocument]::Load($InputPath) ## XML整形結果書き出し $xmldoc.Save($OutputPath, $settings)
入力サンプルXML
- sample.xml
<?xml version="1.0" encoding="UTF-8"?> <root> <items><item id="001">アイテム1</item><item id="005RD">アイテム5赤</item> <item id="003BK">アイテム3黒</item></items> </root>
実行コマンドライン
PowerShell 5.x系
G:\sandbox\xmlformatter>powershell -NoProfile -ExecutionPolicy Bypass -File xmlformatter.ps1 sample.xml
PowerShell 7.x系
G:\sandbox\xmlformatter>pwsh -NoProfile -ExecutionPolicy Bypass -File xmlformatter.ps1 sample.xml
実行結果(整形結果)
- sample.new.xml
<?xml version="1.0" encoding="utf-8"?> <root> <items> <item id="001">アイテム1</item> <item id="005RD">アイテム5赤</item> <item id="003BK">アイテム3黒</item> </items> </root>
XML更新
powershell 5.x シリーズ用
- xmlupdate.ps1
## powershell -NoProfile -ExecutionPolicy Bypass -File xmlupdate.ps1 XMLファイル名 param( [Parameter(Mandatory = $true)] [string] $InputPath ) if (Test-Path $InputPath) { $dir = (Get-Location).Path $base = [System.IO.Path]::GetFileNameWithoutExtension($InputPath) $OutputPath = [System.IO.Path]::Combine($dir, ($base + ".new.xml")) } else { Write-Host "ファイルなし" exit } ## 整形用にインデントを指示 $settings = New-Object System.Xml.XmlWriterSettings $settings.Indent = $true ## XML読み込み $xmldoc = New-Object System.Xml.XmlDocument $xmldoc.Load($InputPath) ## ノード修正 $node = $xmldoc.SelectSingleNode("/root/items/item[@id='005RD']") if ($node -ne $null) { $node.InnerText="アイテムX" $node.SetAttribute("id", "005X") } ## ノード追加 $node = $xmldoc.SelectSingleNode("/root/items") if ($node -ne $null) { $itemdoc = $xmldoc.CreateElement("item") $itemdoc.InnerText="アイテム7Z" $itemdoc.SetAttribute("id","007Z") [void] $node.AppendChild($itemdoc) } ## 修正結果書き出し $writer = [System.Xml.XmlWriter]::Create($OutputPath, $settings) $xmldoc.Save($writer) $writer.Close()
powershell 7.x シリーズ用
- xmlupdate.ps1
## pwsh -NoProfile -ExecutionPolicy Bypass -File xmlupdate.ps1 XMLファイル名 using namespace System.Xml.Linq using namespace System.Xml.XPath param( [Parameter(Mandatory = $true)] [string] $InputPath ) if (Test-Path $InputPath) { $dir = (Get-Location).Path $base = [System.IO.Path]::GetFileNameWithoutExtension($InputPath) $OutputPath = [System.IO.Path]::Combine($dir, ($base + ".new.xml")) } else { Write-Host "ファイルなし" exit } # SaveOptions の明示的生成 $saveOptions = [System.Xml.Linq.SaveOptions]::None ## XML読み込み $xmldoc = [System.Xml.Linq.XDocument]::Load($InputPath) ## ノード修正 $node = [System.Xml.XPath.Extensions]::XPathSelectElement($xmldoc, "/root/items/item[@id='005RD']") if ($node -ne $null) { $node.Value = "アイテムX" $node.SetAttributeValue("id", "005X") } ## ノード追加 $node = [System.Xml.XPath.Extensions]::XPathSelectElement($xmldoc, "/root/items") if ($node -ne $null) { $itemdoc = [System.Xml.Linq.XElement]::new("item","") $itemdoc.Value = "アイテム7Z" $itemdoc.SetAttributeValue("id","007Z") [void] $node.Add($itemdoc) } ## 修正結果書き出し $xmldoc.Save($OutputPath, $saveOptions)
入力サンプルXML
- sample2.xml
<?xml version="1.0" encoding="utf-8"?> <root> <items> <item id="001">アイテム1</item> <item id="005RD">アイテム5赤</item> <item id="003BK">アイテム3黒</item> </items> </root>
実行コマンドライン
PowerShell 5.x系
G:\sandbox\xmlformatter>powershell -NoProfile -ExecutionPolicy Bypass -File xmlupdate.ps1 sample2.xml
PowerShell 7.x系
G:\sandbox\xmlformatter>pwsh -NoProfile -ExecutionPolicy Bypass -File xmlupdate.ps1 sample2.xml
実行結果(更新結果)
- sample2.new.xml
<?xml version="1.0" encoding="utf-8"?> <root> <items> <item id="001">アイテム1</item> <item id="005X">アイテムX</item> <item id="003BK">アイテム3黒</item> <item id="007Z">アイテム7Z</item> </items> </root>
documents/proglang/powershell/powershell-008.1778241636.txt · 最終更新: by k896951
