主に ASP.NET アプリケーションの Web.config 変換で使われている XML Document Transform (XDT) ですが、個人的にはあれを手書きするのはかなり嫌いでした。
XML の差分を持っているだけなので、自動生成できるのではないかと長い間思ってましたが、最近 FatAntelope というまさに待ち望んでいたライブラリが公開されました。
Ever need to create an XDT transform given the source and resulting xml file? Try out https://t.co/FOz9UY8xFy from @CameronWills.
— Sayed I. Hashimi (@sayedihashimi) 2015年11月25日
2 つの XML を指定すると、自動的に差分を取って XDT として書き出してくれます。最高ですね。コマンドラインツールやライブラリの形で公開されているので、簡単に使い方の紹介をしておきます。
XDT を生成する
FatAntelope のコマンドラインツールは GitHub で公開されているので最新版をダウンロードしてきます。
今回はサンプルとして Web.config っぽいものを適当に用意しました。開発時に使うものになります。
<?xml version="1.0" encoding="utf-8"?> <configuration> <connectionStrings> <add name="DefaultConnection" connectionString="Data Source=.\SQLEXPRESS;Initial Catalog=DevelopmentDB;Integrated Security=True" providerName="System.Data.SqlClient" /> </connectionStrings> <system.web> <compilation debug="true" targetFramework="4.6" /> <httpRuntime targetFramework="4.6" /> </system.web> </configuration>
そしてこっちが本番用の Web.config になります。内容としては接続文字列を本番向けにして、リリースビルドを行うというものです。
<?xml version="1.0" encoding="utf-8"?> <configuration> <connectionStrings> <add name="DefaultConnection" connectionString="Server=tcp:***.database.windows.net,1433;Database=ProductionDB;User ID=***;Password=***;Trusted_Connection=False;Encrypt=True;Connection Timeout=30;" providerName="System.Data.SqlClient" /> </connectionStrings> <system.web> <compilation targetFramework="4.6" /> <httpRuntime targetFramework="4.6" /> </system.web> </configuration>
この 2 つのファイルを FatAntelope に与えると、XDT が生成されます。生成された XDT はひとまず Web.Release.config とでも名前を付けて保存するようにします。
FatAntelope Web.config Production.config Web.Release.config
コマンドを実行すると、コンソールにメッセージが出るのでエラーにならなければ成功です。
そして出力された XDT が以下のようになります。ちゃんと差がある部分だけを抽出してくれています。
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform"> <connectionStrings> <add connectionString="Server=tcp:***.database.windows.net,1433;Database=ProductionDB;User ID=***;Password=***;Trusted_Connection=False;Encrypt=True;Connection Timeout=30;" xdt:Transform="SetAttributes(connectionString)" /> </connectionStrings> <system.web> <compilation xdt:Transform="RemoveAttributes(debug)" /> </system.web> </configuration>
手書きの場合と比較すると xdt:Locator が無かったりと、少し違和感があるかもしれませんが、XDT の仕様としてはこれで問題はありません。XML 宣言は何故か付かないので、後で追加しましょう。
C# から XDT を生成する
FatAntelope は NuGet でライブラリが公開されているので、API には多少癖がありますが、自分のアプリケーションなどに簡単に組み込むことが可能です。
当然ながら NuGet を使って FatAntelope をインストールする必要があります。
Install-Package FatAntelope
FatAntelope の API は多少癖があるので、最低限の XDT 生成を行うコードを紹介しておきます。
using System; using System.Xml; using FatAntelope; using FatAntelope.Writers; namespace ConsoleApplication17 { class Program { static void Main(string[] args) { // 元になる XML var baseXml = new XmlDocument(); baseXml.Load(@"C:\Users\shibayan\Downloads\FatAntelope.v0.2.3\Web.config"); // 新しい XML var newXml = new XmlDocument(); newXml.Load(@"C:\Users\shibayan\Downloads\FatAntelope.v0.2.3\Production.config"); // XmlDocument から XTree を作成しておく var baseTree = new XTree(baseXml); var newTree = new XTree(newXml); // XDiff を使って差分を計算し、newTree に格納 XDiff.Diff(baseTree, newTree); // 差分が格納された XTree を元に XDT として書き出し var patch = new XdtDiffWriter().GetDiff(newTree); patch.Save(Console.Out); Console.WriteLine(); } } }
XDiff.Diff を呼び出した結果がイマイチな感じですね。これを実行すると XDT がコンソールに出力されます。
生成された XDT をどのように使うかはお任せします。MSBuildTask などにしてしまうのも手だと思います。
おまけ:XDT を XML に反映させる
完全におまけですが、元になる XML と XDT を使って、差分が反映された XML を生成する方法も紹介しておきます。ちなみにこちらは Microsoft 純正のライブラリが提供されています。
XDT (XML Document Transform) released on codeplex.com | ASP.NET Blog
ライブラリは NuGet で公開されているので、FatAntelope と同じようにサクッと使えます。
基本的に XmlDocument を継承したクラスを使って XML に対して XDT を適用する形になります。こちらもサンプルコードを紹介しておきます。
using System; using Microsoft.Web.XmlTransform; namespace ConsoleApplication17 { class Program { static void Main(string[] args) { // 変換元の XML を読み込む var source = new XmlTransformableDocument(); source.Load(@"C:\Users\shibayan\Downloads\FatAntelope.v0.2.3\Web.config"); // XDT を読み込んで Apply で反映させる var xdt = new XmlTransformation(@"C:\Users\shibayan\Downloads\FatAntelope.v0.2.3\Web.Release.config"); xdt.Apply(source); source.Save(Console.Out); Console.WriteLine(); } } }
実行すると XDT の内容が反映された XML がコンソールに出力されます。
これまでは XDT を適用するという一方向のみの対応でしたが、FatAntelope のリリースによって XML から XDT を作成するという、双方向の変換が可能になりました。
個人的には Web.config 変換を書きやすくするための Visual Studio 拡張を作りたいですね。