본문 바로가기
Java

Java 에서 XML 두개의 파일 비교 하기 - XMLUnit

by Jo__y 2023. 4. 6.

XML 파일 두개를 비교해야 하는 일이 있어서 찾아보니 XMLUnit 이라는 라이브러리가 있었다.
그리고 XML 파일 내용 중에서도 특정 속성(Attribute) 값은 제외하고 비교해야 했다.
처음에 찾았을때는 1.* 버전으로 확인해서 내가 원하는 기능을 찾을 수 없었고,
DocumentBuilder 로 DOM 으로 만들어서 비교해야 하나 고민하고 있을때
Apache 에서 제공하는 XMLUnit 의 2.* 버전이 있다는 것을 알았고, 바로 문제를 해결 할 수 있었다.
Maven dependency 는 다음과 같다.

<!-- https://mvnrepository.com/artifact/org.xmlunit/xmlunit-core -->
<dependency>
    <groupId>org.xmlunit</groupId>
    <artifactId>xmlunit-core</artifactId>
    <version>2.9.0</version>
    <scope>test</scope>
</dependency>

첫번째 테스트 코드는 다음과 같다.

@Test
    public void xmlUnitTest() {
        String source = "<employees> " +
                            "<employee id='1'> " +
                                "<name>James</name> " +
                                "<department>Sales</department> " +
                            "</employee> " +
                            "<employee id='2'> " +
                                "<name>James</name> " +
                                "<department>Sales</department> " +
                            "</employee> " +
                        "</employees>";
        String target = "<employees> " +
                            "<employee id='3'> " +
                                "<name>James</name> " +
                                "<department>Sales</department> " +
                            "</employee> " +
                            "<employee id='4'> " +
                                "<name>James</name> " +
                                "<department>Sales</department> " +
                            "</employee> " +
                        "</employees>";

        Diff myDiff = DiffBuilder.compare(source).withTest(target)
                .checkForSimilar()
                .withNodeMatcher(new DefaultNodeMatcher(ElementSelectors.byName))
                .ignoreWhitespace()
                // id 속성은 제외하고 비교
                .withAttributeFilter(a -> "attributeName".equals("id"))
                .build();

        List<Difference> differences = (List<Difference>) myDiff.getDifferences();
        System.out.println("size : "+ differences.size());
        for (Difference difference : differences) {
            System.out.println(difference);
        }
    }

첫번째로 두개의 xml 내용은 같고, id 만 다를경우 돌려 보았다.

size : 0

id 속성은 무시하고 내용만 그 외의 내용을 비교하여 Difference 값이 0 으로 나왔다.

두번째 테스트 코드는 다음과 같다.

@Test
    public void xmlUnitTest() {
        String source = "<employees> " +
                            "<employee id='1'> " +
                                "<name>James</name> " +
                                "<department>Sales</department> " +
                            "</employee> " +
                            "<employee id='2'> " +
                                "<name>James</name> " +
                                "<department>Sales</department> " +
                            "</employee> " +
                        "</employees>";
        String target = "<employees> " +
                            "<employee id='3'> " +
                                "<name>David</name> " +
                                "<department>Sales</department> " +
                            "</employee> " +
                            "<employee id='4'> " +
                                "<name>James</name> " +
                                "<department>Sales</department> " +
                            "</employee> " +
                        "</employees>";

        Diff myDiff = DiffBuilder.compare(source).withTest(target)
                .checkForSimilar()
                .withNodeMatcher(new DefaultNodeMatcher(ElementSelectors.byName))
                .ignoreWhitespace()
                // id 속성은 제외하고 비교
                .withAttributeFilter(a -> "attributeName".equals("id"))
                .build();

        List<Difference> differences = (List<Difference>) myDiff.getDifferences();
        System.out.println("size : "+ differences.size());
        for (Difference difference : differences) {
            System.out.println(difference);
        }
    }

첫번째와 다른점은 id 가 3인 곳의 name 을 David 로 변경 하였다.
그리고 테스트 할 경우

size : 1
Expected text value 'James' but was 'David' - comparing ...

list 사이즈가 1 이고 James 를 예상했지만 David 값을 가지고 있다고 출력 되었다.

XMLUnit 덕분에 소스가 간결해졌다.

댓글