Como ignoro certos elementos ao comparar XML?

Eu tenho uma mensagem XML assim:

 something something else yet another thing  

Eu quero comparar uma mensagem deste tipo produzida por um método em teste para uma mensagem esperada, mas eu não me importo com elementA . Então, eu gostaria que a mensagem acima fosse considerada igual a:

  something different something else yet another thing  

Estou usando a versão mais recente do XMLUnit .

Eu estou imaginando que a resposta envolve a criação de um DifferenceListener personalizado; Eu só não quero reinventar a roda se houver algo pronto para usar lá fora.

Sugestões que usam uma biblioteca diferente do XMLUnit são bem-vindas.

As coisas mudaram muito para XMLUnit desde que esta pergunta foi respondida.

Agora você pode ignorar facilmente um nó ao usar um DiffBuilder :

 final Diff documentDiff = DiffBuilder .compare(expectedSource) .withTest(actualSource) .withNodeFilter(node -> !node.getNodeName().equals(someName)) .build(); 

Se você chamar os nós documentDiff.hasDifferences() adicionados ao filtro, eles serão ignorados.

Acabei de implementar um DifferenceListener que leva uma lista de nomes de nós (com namespaces) para ignorar diferenças textuais para:

 public class IgnoreNamedElementsDifferenceListener implements DifferenceListener { private Set blackList = new HashSet(); public IgnoreNamedElementsDifferenceListener(String ... elementNames) { for (String name : elementNames) { blackList.add(name); } } public int differenceFound(Difference difference) { if (difference.getId() == DifferenceConstants.TEXT_VALUE_ID) { if (blackList.contains(difference.getControlNodeDetail().getNode().getParentNode().getNodeName())) { return DifferenceListener.RETURN_IGNORE_DIFFERENCE_NODES_IDENTICAL; } } return DifferenceListener.RETURN_ACCEPT_DIFFERENCE; } public void skippedComparison(Node node, Node node1) { } } 

Eu usaria o XSLT e a transformação de identidade para filtrar os elementos que desejo ignorar e comparar os resultados.

Veja XSL: como copiar uma tree, mas removendo alguns nós? anteriormente em SO.

Agora você pode tentar ${xmlunit.ignore} no XMLUnit 2.6.0 (adicionar xmlunit-placeholders de dependência). Exemplo de código é como abaixo.

 Diff diff = DiffBuilder .compare(expectedXML) .withTest(actualXML) .withDifferenceEvaluator(new PlaceholderDifferenceEvaluator()) .build(); 

XML esperado:

  ${xmlunit.ignore} something else yet another thing  

XML real:

  anything something else yet another thing  

Observe que atualmente o $ {xmlunit.ignore} suporta apenas ignorância de nó de texto e valor de atributo, como pode ser visto nos testes de unidade .

 public class IgnoreNamedElementsDifferenceListener implements DifferenceListener { private Set blackList = new HashSet(); public IgnoreNamedElementsDifferenceListener(String ... elementNames) { for (String name : elementNames) { blackList.add(name); } } public int differenceFound(Difference difference) { if (difference.getId() == DifferenceConstants.TEXT_VALUE_ID) { if (blackList.contains(difference.getControlNodeDetail().getNode().getParentNode().getNodeName())) { return DifferenceListener.RETURN_IGNORE_DIFFERENCE_NODES_IDENTICAL; } } return DifferenceListener.RETURN_ACCEPT_DIFFERENCE; } public void skippedComparison(Node node, Node node1) { } } 

Como invocar esta própria implementação para o meu método para ver as diferenças após o nó específico ignorado para a comparação.