2009-08-06 2 views
27

У меня есть сообщение об XML следующим образом:Как игнорировать некоторые элементы при сравнении XML?

<root> 
    <elementA>something</elementA> 
    <elementB>something else</elementB> 
    <elementC>yet another thing</elementC> 
</root> 

Я хочу, чтобы сравнить сообщение такого типа, полученного методом испытуемой к ожидаемому сообщению, но я не забочусь о elementA. Итак, я хотел бы выше сообщение считается равным:

<root> 
    <elementA>something different</elementA> 
    <elementB>something else</elementB> 
    <elementC>yet another thing</elementC> 
</root> 

Я использую последнюю версию XMLUnit.

Я представляю, что ответ включает создание пользовательского DifferenceListener; Я просто не хочу изобретать велосипед, если есть что-то готовое к использованию там.

Предложения, которые используют библиотеку, отличную от XMLUnit, приветствуются.

ответ

10

Все изменилось много для XMLUnit, так как этот вопрос был дан ответ.

Теперь вы можете легко игнорировать узел при использовании DiffBuilder:

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

Если вы затем вызвать documentDiff.hasDifferences() узлы добавлены в фильтр будет игнорироваться.

8

Я бы использовал XSLT и identity transform, чтобы отфильтровать элементы, которые я хочу игнорировать, и сравните результаты.

См. XSL: how to copy a tree, but removing some nodes ? ранее на SO.

+0

Это также действительный подход к проблеме. Спасибо за предложение. –

38

я завелся реализации DifferenceListener, которая принимает список имен узлов (с пространствами имен), чтобы игнорировать текстуальные различия для:

public class IgnoreNamedElementsDifferenceListener implements DifferenceListener { 
    private Set<String> blackList = new HashSet<String>(); 

    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) { 

    } 
} 
+13

Я удивлен, что это сложный вопрос - неутешительно, если xmlunit не имеет чего-то встроенного для игнорирования определенных элементов? – bacar

+0

Это решение довольно устарело. По-видимому, новая модель программирования xmlunit использует [ComparisonListener] (http://www.xmlunit.org/api/java/2.4.0/org/xmlunit/diff/ComparisonListener.html), а не DifferenceListener. – Cheeso

-1

открытый класс IgnoreNamedElementsDifferenceListener реализует 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) { 

} 

}

Как вызвать эту собственную реализацию в мой метод, чтобы увидеть различия после конкретного узла проигнорировано для Comparision.?

+0

Похоже, вы задаете новый вопрос в качестве ответа. Если у вас есть новый вопрос, задайте его как вопрос, а не как ответ на существующий вопрос. – Cheeso

Смежные вопросы