はんなりと、ゆるやかに

アジャイル、スクラムが好きなITエンジニアが日々から学んだことをアウトプット

PowershellのGet-Contentを使ったXML読み込みで困ったこと

はじめに

XMLの読み書きをpowershellで行った時に困って解決したことをまとめました。
普段、powershell使わないのでつまってしまいました。

何に困ったのか

内部エンティティや外部エンティティ参照しているXMLを読み込んで一部書き換えて上書き保存した際、参照部分が展開されてしまいました。外部エンティティ参照に至っては記述が消えてしまいました。

環境

windows10
(windows7は問題なし)

内容

読み込み対象ファイル

Top.xml

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE root[
	<!ENTITY rootName "はんなりと">
	<!ENTITY sub SYSTEM "sub.xml">
]>

<root name="&rootName;">
    &sub;
</root>

sub.xml

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

<sub name="ゆるやかに" />

修正前の処理

読んで保存するだけ。

$xml = [XML](Get-Content -Encoding UTF8 root.xml)
$xml.Load("root.xml")
$xml.Save("root.xml")

修正前の結果

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE root[
	<!ENTITY rootName "はんなりと">
	<!ENTITY sub SYSTEM "sub.xml">
]>
<root name="はんなりと">
</root>

内部エンティティは展開され、外部エンティティは消えてしまいました。
読み込んで、保存しただけなので変化が無いことを期待したのですが期待した結果はではありませんでした。

修正後の処理

$xml= New-Object System.XML.XMLDocument
$xml.Load("root.xml")
$xml.Save("root.xml")

修正後の結果

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE root[
	<!ENTITY rootName "はんなりと">
	<!ENTITY sub SYSTEM "sub.xml">
]>
<root name="&rootName;">&sub;</root>

無事に意図通りの結果になりました。

まとめ

内部エンティティ、外部エンティティを使わなければ、Get-Content で問題ないのですが、使うと環境によっては問題が出るので気をつける必要がありました。