it-swarm.dev

Come posso diff due file XML?

Su Linux, come posso generare una differenza tra due file XML?

Idealmente, mi piacerebbe poterlo configurare su alcune cose rigorose, o allentare alcune cose, come lo spazio bianco o l'ordine degli attributi.

Mi preoccupo spesso che i file funzionino allo stesso modo, ma diff da solo, sarebbe fastidioso da usare, specialmente se il file XML non ha molte interruzioni di riga.

Ad esempio, il seguente dovrebbe essere davvero ok per me:

<tag att1="one" att2="two">
  content
</tag>

<tag att2="two" att1="one">
  content
</tag>
73
qedi

Un approccio sarebbe quello di trasformare prima entrambi i file XML in Canonical XML , e confrontare i risultati usando diff. Ad esempio, xmllint può essere usato per canonicalizzare XML.

$ xmllint --c14n one.xml > 1.xml
$ xmllint --c14n two.xml > 2.xml
$ diff 1.xml 2.xml

O come one-liner.

$ diff <(xmllint --c14n one.xml) <(xmllint --c14n two.xml)
84

La risposta di Jukka non ha funzionato per me, ma ha puntato su XML canonico. Né - c14n - c14n11 ha ordinato gli attributi, ma ho trovato il - exc-c14n switch ha ordinato gli attributi. - exc-c14n non è elencato nella pagina man, ma descritto sulla riga di comando come "Formato canonico esclusivo W3C".

$ xmllint --exc-c14n one.xml > 1.xml
$ xmllint --exc-c14n two.xml > 2.xml
$ diff 1.xml 2.xml

$ xmllint | grep c14
    --c14n : save in W3C canonical format v1.0 (with comments)
    --c14n11 : save in W3C canonical format v1.1 (with comments)
    --exc-c14n : save in W3C exclusive canonical format (with comments)

$ rpm -qf /usr/bin/xmllint
libxml2-2.7.6-14.el6.x86_64
libxml2-2.7.6-14.el6.i686

$ cat /etc/system-release
CentOS release 6.5 (Final)

Warning - exc-c14n rimuove l'intestazione xml mentre il --c14n antepone l'intestazione xml se non là.

21
rjt

Ho cercato di usare la risposta di @Jukka Matilainen, ma ho avuto problemi con lo spazio bianco (uno dei file era un enorme liner). Usare --format aiuta a saltare le differenze tra spazi bianchi.

xmllint --format one.xml > 1.xml  
xmllint --format two.xml > 2.xml  
diff 1.xml 2.xml  

Nota: utilizzare il comando vimdiff per il confronto side-by-side degli xmls.

17
GuruM

Diffxml ottiene le funzionalità di base corrette, sebbene non sembri offrire molte opzioni per la configurazione.

Modifica: Project Diffxml è stato migrato a GitHub dal 2013.

6
dsolimano

Se vuoi anche ignorare l'ordine degli elementi figli, ho scritto un semplice strumento python per questo chiamato xmldiffs:

Confronta due file XML, ignorando l'ordine degli elementi e degli attributi.

Utilizzo: xmldiffs [OPTION] FILE1 FILE2

Eventuali opzioni extra vengono passate al comando diff.

Prendi il https://github.com/joh/xmldiffs

4
joh

Io uso Beyond Compare per confrontare tutti i tipi di file basati su testo. Producono versioni per Windows e Linux.

0
Alan