web-dev-qa-db-ja.com

プログラムによるXML差分/ C#でのマージ

現在、私は複数のXML構成ファイルを持つソフトウェアを管理しています。新しいバージョンのソフトウェアがリリースされると、基本構成ファイルが変更されることがあります。現在、起動時にソフトウェア呼び出し KDiff があります。変更を検出すると、ユーザーに変更を選択するように求めます。

このアプローチの問題は、KDiffが行比較プログラムであり、XMLの方法(ノードなど)を認識していないことです。

理想的には、2つのXMLファイル(ソースXMLと現在動作中のXML)を差分できるC#のライブラリ(MSショップであるため)をプログラムで操作したいと思います。

次に、いくつかの簡単なルールを使用して2つをマージします。

  1. 現在の作業XMLに、ソースXMLにないノードがある場合は、それを削除します。
  2. ソースXMLに、現在の作業XMLにないノードがある場合は、それを追加します。
  3. 両方のノードが同じで値が異なる場合は、ソースXMLの値が「UseExistingValue」に設定されていない限り、ソースXMLの値を優先します。

たとえば、次の「ソース」XMLは次のとおりです。

<Configuration>
  <Items>
     <Item Id="1" Position="true">
       <Location X="UseExistingValue" Y="UseExistingValue" Z="UseExistingValue" />

       <Something/>
       <SomethingElse/>
     </Item>
   </Items>
 </Configuration>

そして、これが「現在の作業」XMLです。

<Configuration>
  <Items>
    <Item Id="1" Position="false">
      <Location X="123" Y="234" Z="345" />
      <Another/>
      <Something/>

    </Item>
  </Items>
</Configuration>

そして、マージされたバージョンは次のようになります。

<Configuration>
  <Items>
    <Item Id="1" Position="true">
      <Location X="123" Y="234" Z="345" />

      <Something/>
      <SomethingElse/>
    </Item>
  </Items>
</Configuration>

MS XML Diff and Patch Tool を見てきましたが、ファイルは確実にマージされますが、定義したいプログラムルールは許可されていません。

XMLUnit for Java devs は有望なようですが、.NETバージョンは未開発のようです。これは残念なことです。

スクリプト可能なXML差分/マージツールおよび/または.NETライブラリ(有料または無料)のいずれかについて何か提案がありますか?

ありがとう。

17
Pretzel

数日間いじり回した後、私は自分に合っていると思う解決策を見つけました。多分それは他の人にも役立つかもしれません。

MS XML差分およびパッチツール は実行可能なオプションでした。最初のファイルを2番目のファイルと比較すると、2つのXMLファイル間で検出された変更を一覧表示するXML「DiffGram」が作成されます。

上記の3つのルールすべてを処理するために、2つのファイルを一方向にDiffし、Linq-to-XMLを使用してDiffGramファイルを開き、すべての「追加」行と「削除」行を削除しました。

XNamespace xd = "http://schemas.Microsoft.com/xmltools/2002/xmldiff";
var doc = XDocument.Load(_diffGramFile);
doc.Root.DescendantsAndSelf(xd + "add").Remove();
doc.Root.DescendantsAndSelf(xd + "remove").Remove();

次に、この編集された差分グラムを最初のファイルにパッチ(マージ)して、部分的にマージされた一時ファイルを作成しました。これにより、ルール1と2が処理されます。

次に、部分的にマージされたファイルを、最初に使用されたファイルと比較しました。次に、新しいDiffGramを開き、「UseExistingValue」へのすべての変更参照を削除しました。

var newdoc = XDocument.Load(_diffGramFile);
newdoc.Root.DescendantsAndSelf(xd + "change")
      .Where(x => x.Value == "UseExistingValue").Remove();

そして、この編集されたDiffGramを、ルール3を処理する部分的にマージされたファイルに対してマージしました。これをXMLに保存すると、上記で定義されたルールに従ってマージされた最終的なXMLが生成されます。

うまくいけば、これは他の人々を助けることができます。

ヒント:XmlDiffPatchライブラリをインストールした後、XmlDiffPatch DLLはC:\ Windows\Assembly\GAC\XmlDiffPatch\1.0.8.28__b03f5f7f11d50a3a\XmlDiffPatch.dllにあります。

23
Pretzel