2008-09-17 2 views
19

Мне нужно «объединить» два документа XML, перезаписав наложенные атрибуты и элементы. Например, если у меня есть Document1:Объединить XML-документы

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

и документ2:

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

Я хочу, чтобы объединить эти два так:

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

Я предпочитаю Java или XSLT - так lutions, муравей будет делать хорошо, но если есть простой способ сделать это в Rake, Руби или Python, пожалуйста, не стесняйтесь :-)

EDIT: на самом деле я считаю, Я бы предпочел использовать автоматизированный инструмент/скрипт, даже writing it by myself, потому что вручную слияние около 30 XML-файлов немного громоздко ... :-(

+0

вы можете быть немного более конкретную информацию о правилах, которые вы хотите применять? Всегда ли будет только один элемент с тем же именем? Вы углубляетесь в дерево, чтобы сравнить дочерние элементы, когда оба документа имеют один и тот же элемент (с идентичными атрибутами)? – 2008-09-17 16:56:04

+0

Кстати, ваш пример не является корректным («все» не закрыто). – 2008-09-17 16:56:51

ответ

6

Если вам нравится XSLT, есть хороший сценарий слияния я использовал до этого на: Oliver's XSLT page

-1

Не уверен, хотите ли вы сделать это программно или нет.

Редактировать: Ах, я разместил это перед Редактированием. Разве я не выгляжу теперь как идиот! ;)

Если вы просто хотите объединить два файла вместе, у IBM есть XML Diff and Merge Tool, а также есть DiffDog от Altova.

+0

Ничего, я был немного неуклюжим и разместил вопрос до того, как текст был завершен ... кто же теперь выглядит как идиот? ;-) Что касается вашего ответа: большое спасибо, я изучаю инструменты, которые вы предложили, и я дам вам знать, сохранили ли они мой ... bacon :-) – 2008-09-17 07:11:01

3

Я знаю, что это старая нить, но Project: Merge может сделать это для вас. Он может объединить два XML-файла вместе и может быть запущен из командной строки, поэтому вы можете объединить все вместе, запустить его и разрешить любые конфликты (например, изменение значения атрибута «ключ» в приведенном выше примере) вручную с помощью несколько кликов. (Вы можете сказать, что он работает тихо, при условии, что конфликтов нет.)

Он может выполнять двусторонние и трехсторонние сравнения файлов XML, а также двухсторонние и трехсторонние слияния. (Там, где трехсторонняя операция предполагает, что два файла, которые сравниваются/объединены, имеют общего предка.)

0

Проверить XmlCombiner, который является библиотекой Java, которая реализует слияние XML именно таким образом. Он основан на аналогичной функциональности, предлагаемой библиотекой plexus-utils.

По умолчанию соглашение XmlCombiner заключается в том, чтобы перезаписать перекрывающиеся атрибуты и элементы. Но точное слияние может быть изменено с использованием специальных атрибутов 'combine.self' and '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); 

Отказ от ответственности: я являюсь автором.

0

(также с использованием Oliver's XSLT stlyesheets)

XSLT слияния с PowerShell:

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) 

Используя 'простой ол' Saxon:

java -jar saxon9he.jar .\FileA.xml .\merge.xslt with=FileB.xml replace=true 
Смежные вопросы