web-dev-qa-db-ja.com

XMLドキュメントをマージする

2つのXMLドキュメントを「マージ」して、重複する属性と要素を上書きする必要があります。たとえば、document1がある場合:

<mapping>
    <key value="assigned">
        <a/>
    </key>
    <whatever attribute="x">
        <k/>
        <j/>
    </whatever>
</mapping>

およびdocument2

<mapping>
    <key value="identity">
        <a/>
        <b/>
    </key>
</mapping>

次のように2つをマージしたいと思います。

<mapping>
    <key value="identity">
        <a/>
        <b/>
    </key>
    <whatever attribute="x">
        <k/>
        <j/>
    </whatever>
</mapping>

Javaまたは[〜#〜] xslt [〜#〜]ベースのソリューションでは、antで問題ありませんが、RakeRubyまたはPythonしないでください '恥ずかしがり屋:-)

編集:実際には私は自動ツール/スクリプトを使用したいと思っています 自分で書いても 、手動でマージしているため約30のXMLファイルは少し扱いに​​くい... :-(

22
Manrico Corazzi

XSLTが好きなら、私が以前に使った素敵なマージスクリプトがあります: OliverのXSLTページ

7
Craig.Nicol

チェック= XmlCombiner これは、Javaライブラリーであり、XMLマージをこの方法で正確に実装します。これは、大まかに plexus-utils)が提供する同様の機能に基づいています ライブラリ。

XmlCombinerのデフォルトの規則は、重複する属性と要素を上書きすることです。ただし、正確なマージ動作は、特別な 'combine.self'および 'combine.children' 属性を使用して変更できます。

使用法:

import org.atteo.xmlcombiner.XmlCombiner;

// create combiner
XmlCombiner combiner = new XmlCombiner();
// combine files
combiner.combine(firstFile);
combiner.combine(secondFile);
// store the result
combiner.buildDocument(resultFile);

免責事項:私は著者です。

4
Sławek

私はこれが古いスレッドであることを知っていますが、 Project:Merge がこれを行うことができます。 2つのXMLファイルをマージし、コマンドラインから実行できるため、すべてをまとめて実行し、競合(上記の例での 'key'の属性値の変更など)を手動で解決できます。数回のクリック。 (競合がなければ、サイレントに実行するように指示できます。)

XMLファイルの2者間および3者間比較と、2者間および3者間マージを実行できます。 (3者間操作では、比較またはマージされる2つのファイルに共通の祖先があると想定されます。)

4
user420442

これをプログラムで実行するかどうか不明です。

編集:ああ、編集の前に投稿しました。今バカみたいになってはいけない! ;)

2つのファイルをマージするだけの場合、IBMには XML Diff and Merge Tool があり、Altovaの DiffDog もあります。

1
moobaa

(また OliverのXSLT stlyesheets を使用)

PowerShellからのXSLTマージ:

param(
[Parameter(Mandatory = $True)][string]$file1,
[Parameter(Mandatory = $True)][string]$file2,
[Parameter(Mandatory = $True)][string]$path
)

# using only abs paths .. just to be safe
$file1 = Join-Path $(Get-Location) $file1
$file2 = Join-Path $(Get-Location) $file2
$path = Join-Path $(Get-Location) $path

# awesome xsl stylesheet from Oliver Becker
# http://web.archive.org/web/20160502194427/http://www2.informatik.hu-berlin.de/~obecker/XSLT/merge/merge.xslt
$xsltfile = Join-Path $(Get-Location) "merge.xslt"

$XsltSettings = New-Object System.Xml.Xsl.XsltSettings
$XsltSettings.EnableDocumentFunction = 1

$xslt = New-Object System.Xml.Xsl.XslCompiledTransform;
$xslt.Load($xsltfile , $XsltSettings, $(New-Object System.Xml.XmlUrlResolver))

[System.Xml.Xsl.XsltArgumentList]$al = [System.Xml.Xsl.XsltArgumentList]::new()
$al.AddParam("with", "", $file2)
$al.AddParam("replace", "", "true")

[System.Xml.XmlWriter]$xmlwriter = [System.Xml.XmlWriter]::Create($path)
$xslt.Transform($file1, $al, $xmlwriter)

'プレーンOL'サクソンの使用:

Java -jar saxon9he.jar .\FileA.xml .\merge.xslt with=FileB.xml replace=true
1
mwallner