Juntar documentos XML [fechados]
preciso de "fundir" dois documentos XML, sobrepondo os atributos e elementos sobrepostos. Por exemplo, se eu tiver documento1:
<mapping>
<key value="assigned">
<a/>
</key>
<whatever attribute="x">
<k/>
<j/>
</whatever>
</mapping>
E documento2:
<mapping>
<key value="identity">
<a/>
<b/>
</key>
</mapping>
Quero fundir os dois assim:
<mapping>
<key value="identity">
<a/>
<b/>
</key>
<whatever attribute="x">
<k/>
<j/>
</whatever>
</mapping>
eu prefiro Java ou XSLT-soluções em ant vai fazer bem, mas se há uma maneira fácil de fazer isso no Rake, Ruby ou Python por favor, não seja tímido :-)
editar: na verdade eu acho que eu prefiro usar uma ferramenta/script automatizado, mesmo escrevendo-o por mim mesmo, porque a junção manual de cerca de 30 arquivos XML é um pouco pesado... :-(
5 answers
Se gostas de XSLT, há um bom script de fusão que já usei antes em: Página XSLT do Oliver
Sei que este é um tópico antigo, mas projecto: Merge pode fazer isto por ti. Ele pode juntar dois arquivos XML juntos, e pode ser executado a partir da linha de comando, para que você possa agrupar tudo junto, executá-lo e apenas resolver quaisquer conflitos (como o valor de atributo de mudança de 'chave' em seu exemplo acima) manualmente com alguns cliques. (Você pode dizer-lhe para correr silenciosamente desde que não haja conflitos.)
Pode efectuar comparações bidirecionais e bidirecionais de ficheiros XML e bidirecionais e funde-se a três. (Onde uma operação de três vias assume que os dois arquivos que estão sendo comparados / mesclados têm um ancestral comum.)
Check XmlCombiner que é uma biblioteca Java que implementa a junção XML exactamente desta forma. Ele é vagamente baseado em uma funcionalidade similar oferecida pela biblioteca plexus-utils .
A Convenção default do XmlCombiner é sobrepor os atributos e elementos sobrepostos. Mas o comportamento exato de fusão pode ser alterado usando combinação especial .self ' e ' combine.atributos de children ' .
Utilização:
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);
Disclaimer: eu sou o autor.
(também usando os XSLT stlyesheets do Oliver)
A junção XSLT do 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)
Usando 'Saxão vulgar':
java -jar saxon9he.jar .\FileA.xml .\merge.xslt with=FileB.xml replace=true
Não sabe se quer fazer isto programaticamente ou não.
Editar: Ah, eu postei isso antes da edição. Não pareço um idiota agora? ;)
Se só quiser juntar dois ficheiros, a IBM tem um XML e uma ferramenta de junção , e há também o DiffDog do Altova.