Como posso diferenciar dois arquivos XML?

63

No Linux, como eu poderia gerar um diff entre dois arquivos XML?

Idealmente, gostaria de poder configurá-lo para algumas coisas estritas ou soltar algumas coisas, como espaço em branco ou ordem de atributo.

Eu sempre me importo que os arquivos sejam funcionalmente os mesmos, mas o diff, por si só, seria chato de usar, especialmente se o arquivo XML não tiver muitas quebras de linha.

Por exemplo, o seguinte deve ser realmente bom para mim:

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

<tag att2="two" att1="one">
  content
</tag>
    
por qedi 07.12.2009 / 17:27

8 respostas

69

Uma abordagem seria transformar os dois arquivos XML em XML canônico e comparar os resultados usando diff . Por exemplo, o xmllint pode ser usado para canonizar o XML.

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

Ou como um verso.

$ diff <(xmllint --c14n one.xml) <(xmllint --c14n two.xml)
    
por 09.12.2009 / 21:06
15

A resposta de Jukka não funcionou para mim, mas apontou para o XML canônico. Nem - c14n nem - c14n11 classificou os atributos, mas eu encontrei o - exc-c14n switch fez classificar os atributos. - exc-c14n não está listado na página man, mas é descrito na linha de comando como "formato canônico exclusivo do 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)

Atenção - exc-c14n retira o cabeçalho xml enquanto o --c14n preenche o cabeçalho xml se não estiver lá.

    
por 04.03.2014 / 13:51
14

Tentou usar a resposta de @Jukka Matilainen, mas teve problemas com o espaço em branco (um dos arquivos era um enorme one-liner). Usar --format ajuda a ignorar as diferenças de espaço em branco.

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

Nota: use o comando vimdiff para comparação lado-a-lado dos xmls.

    
por 08.08.2012 / 11:58
4

O Diffxml obtém a funcionalidade básica correta, embora não pareça oferecer muitas opções de configuração.

    
por 07.12.2009 / 17:57
3

Se você deseja também ignorar a ordem dos elementos filhos, eu escrevi uma ferramenta python simples para isso chamada xmldiffs :

Compare two XML files, ignoring element and attribute order.

Usage: xmldiffs [OPTION] FILE1 FILE2

Any extra options are passed to the diff command.

Obtenha o link

    
por 23.03.2017 / 00:59
0

Eu uso Beyond Compare para comparar todos os tipos de arquivos baseados em texto. Eles produzem versões para Windows e Linux.

    
por 07.12.2009 / 17:30
-1

Nosso SD Smart Differencer compara documentos baseados em estrutura em oposição ao layout real.

Existe um Diferenciador Inteligente XML. Para XML, isso significa corresponder a ordem das tags e do conteúdo. Deve-se notar que a string de texto no fragmento específico que você indicou era diferente. Atualmente, não entende a noção XML de atributos de tag indicando se espaço em branco é normalizado vs. significativo.

    
por 23.05.2010 / 07:01
-1

Não tenho certeza se (a dependência de) uma ferramenta on-line conta como uma solução, mas, pelo que vale a pena, obtive um bom resultado nessa ferramenta de comparação de XML online . Simplesmente funciona.

    
por 08.08.2017 / 20:24

Tags