使用xmlunit自定义输出消息进行XML比较



嗨,我正在尝试使用xmlunit比较两个xml文件的内容
这是我的输入xmls

reference.xml

<?xml version="1.0" encoding="UTF-8"?>
<books>
    <book>
        <name>abc</name>
        <isbn>9971-5-0210-0</isbn>
        <author>abc</author>
        <category></category>
    </book>
    <book>
        <name>def</name>
        <isbn>9971-5-0222-0</isbn>
        <author>def</author>
    </book>
</books>

compare.xml

<?xml version="1.0" encoding="UTF-8"?>
    <books>
        <book>
            <name>abc</name>
            <isbn>9971-5-0210-0</isbn>
            <author>abc</author>
            <category></category>
        </book>
        <book>
            <name>def</name>
            <isbn>9971-5-0222-0</isbn>
            <author>def</author>
        </book>
        <book>
            <name>ghi</name>
            <isbn>9971-5-0222-0</isbn>
            <author>test authora</author>
        </book>
    </books>

在这里我们可以观察到,在compare.xml中有3个图书节点。

我正在打印总差异,并将其计算为以下

 DetailedDiff detDiff = new DetailedDiff(diff);
    List differences = detDiff.getAllDifferences();
    System.out.println("Total differences:-->"+differences.size());
    for (Object object : differences) {
        Difference difference = (Difference)object;
        System.out.println("***********************");
        System.out.println(difference);
        System.out.println("***********************");
    }

输出:

**Total differences:-->4

子节点的数目应为"5",但实际为"7"-在/books[1]处与在/books[1]处进行比较



期望的文本值''但是''-比较在/books[1]/text()[3]到在/books[1]/text()[3]



应存在子节点"null",但为"book"-在null处与在/books[1]/book[3]处进行比较



应存在子节点"null",但为"#text"-在null处与在/books[1]/text()[4]


相反,有没有任何方法可以让我将更改视为只有1(因为我认为只添加了一个图书节点,忽略了里面的内部标签),并将输出自定义为我们的自定义消息

第一步是忽略元素内容空白,这将消除第二个和第四个差异。

XMLUnit.setIgnoreWhitespace(true);

为了抑制其他两个差异中的一个,您需要覆盖DifferenceListener并显式忽略其中一个。根据您的描述,您希望只看到CHILD_NODE_NOT_FOUND的差异。

    detDiff.overrideDifferenceListener(new DifferenceListener() {
            @Override
            public int differenceFound(Difference difference) {
                return difference.getId() == DifferenceConstants.CHILD_NODELIST_LENGTH_ID
                    ? RETURN_IGNORE_DIFFERENCE_NODES_IDENTICAL
                    : RETURN_ACCEPT_DIFFERENCE;
            }
            @Override
            public void skippedComparison(Node control, Node test) { }
        });

一种解决方案可能是将xml文件解析为java对象,然后进行比较。

在这个例子中,我没有使用xmlunit,它是基于xstream的,我希望它能帮助你:

图书类

    public class Book {
        private String  name;
        private String  isbn;
        private String  author;
        private String  category;
        public String getName() {
            return name;
        }
        public void setName(final String name) {
            this.name = name;
        }
        public String getIsbn() {
            return isbn;
        }
        public void setIsbn(final String isbn) {
            this.isbn = isbn;
        }
        public String getAuthor() {
            return author;
        }
        public void setAuthor(final String author) {
            this.author = author;
        }
        public String getCategory() {
            return category;
        }
        public void setCategory(final String category) {
            this.category = category;
        }
        @Override
        public int hashCode() {
            final int prime = 31;
            int result = 1;
            result = prime * result + (author == null ? 0 : author.hashCode());
            result = prime * result + (category == null ? 0 : category.hashCode());
            result = prime * result + (isbn == null ? 0 : isbn.hashCode());
            result = prime * result + (name == null ? 0 : name.hashCode());
            return result;
        }
        @Override
        public boolean equals(final Object obj) {
            if (this == obj) {
                return true;
            }
            if (obj == null) {
                return false;
            }
            if (getClass() != obj.getClass()) {
                return false;
            }
            final Book other = (Book) obj;
            if (author == null) {
                if (other.author != null) {
                    return false;
                }
            } else if (!author.equals(other.author)) {
                return false;
            }
            if (category == null) {
                if (other.category != null) {
                    return false;
                }
            } else if (!category.equals(other.category)) {
                return false;
            }
            if (isbn == null) {
                if (other.isbn != null) {
                    return false;
                }
            } else if (!isbn.equals(other.isbn)) {
                return false;
            }
            if (name == null) {
                if (other.name != null) {
                    return false;
                }
            } else if (!name.equals(other.name)) {
                return false;
            }
            return true;
        }
        @Override
        public String toString() {
            return "Book [name=" + name + ", isbn=" + isbn + ", author=" + author + ", category=" + category + "]";
        }
    }

Boks类(带主方法):

    public class Books {
        private final List<Book>    books;
        public Books() {
            books = new ArrayList<Book>();
        }
        public void add(final Book b) {
            books.add(b);
        }
        public List<Book> getBooks() {
            return books;
        }
        @Override
        public String toString() {
            return books.toString();
        }
        public static void main(final String[] args) {
            final XStream xstream = new XStream();
            xstream.alias("books", Books.class);
            xstream.alias("book", Book.class);
            xstream.addImplicitCollection(Books.class, "books");
            final Books ref = (Books) xstream.fromXML(Book.class.getClassLoader().getResourceAsStream("reference.xml"));
            final Books compare = (Books) xstream.fromXML(Book.class.getClassLoader().getResourceAsStream("compare.xml"));
            System.out.println(ref);
            System.out.println(compare);
            final List<Book> rbooks = new ArrayList<Book>(ref.getBooks());
            final List<Book> cbooks = new ArrayList<Book>(compare.getBooks());
            rbooks.removeAll(cbooks);
            System.out.println("Missing books in compare : " + rbooks);
            rbooks.clear();
            rbooks.addAll(ref.getBooks());
            cbooks.removeAll(rbooks);
            System.out.println("Extra books in compare : " + cbooks);
        }
    }

最新更新