比较两个xml使用xmlunit忽略它们的顺序

时间:2016-02-01 05:53:18

标签: java xml xmlunit xmlunit-2

我有两个xml文件,我需要使用xmlunit

进行比较

除了订单

之外,这些xml文件的内容始终相同

例如:

 <report>
     <component name = "a">
         <component name = "b"/>
         <component name = "c"/>
     </component>
</report>

这里内部组件的顺序可能不同,如下所示

<report>
     <component name = "a">
         <component name = "c"/>
         <component name = "b"/>
     </component>
</report>

当我比较这两个xml时,我希望diff.similar()为真。

到目前为止我尝试的是

try(FileInputStream fileStream1 = new FileInputStream(expXMLPath)) {
        try(FileInputStream fileStream2 = new FileInputStream(genXMLPath)) {
            InputSource inputSource1 = new InputSource(fileStream1);
            InputSource inputSource2 = new InputSource(fileStream2);
            diff = new Diff(inputSource1, inputSource2);
            RegDiffListener ignorableElementsListener = new RegDiffListener(
                    ignorableXPathsRegex);
            diff.overrideDifferenceListener(ignorableElementsListener);
            diff.overrideElementQualifier(new ElementNameAndAttributeQualifier());
            diff.overrideElementQualifier(new MultiLevelElementNameAndTextQualifier(1, true));
            diff.overrideElementQualifier(new RecursiveElementNameAndTextQualifier());
            // diff.overrideElementQualifier(new
            // ElementNameAndTextQualifier());
            return diff;
        }

我尝试使用不同的overrideElementQualifier选项,但没有任何工作。请让我知道解决方案。

1 个答案:

答案 0 :(得分:0)

使用RC提到的解决方案XMLUnit将文档视为similar

如果您希望将它们视为identical,则一种解决方案可能是实现DifferenceListener,忽略这些节点的属性差异。在一个片段下方进行演示。

import java.io.FileInputStream;
import java.io.IOException;
import org.custommonkey.xmlunit.Diff;
import org.custommonkey.xmlunit.Difference;
import org.custommonkey.xmlunit.DifferenceConstants;
import org.custommonkey.xmlunit.DifferenceListener;
import org.custommonkey.xmlunit.ElementNameAndAttributeQualifier;
import org.w3c.dom.Node;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

public class IgnoreOrder {

    public static void main(String[] args) throws IOException, SAXException {
        try (FileInputStream fileStream1 = new FileInputStream("file1.xml");
                FileInputStream fileStream2 = new FileInputStream("file2.xml")) {
            InputSource inputSource1 = new InputSource(fileStream1);
            InputSource inputSource2 = new InputSource(fileStream2);
            Diff diff = new Diff(inputSource1, inputSource2);
            // to treat the files as identical
            diff.overrideDifferenceListener(new IgnoreAttributeDifference());
            // to treat the files as similar
            // diff.overrideElementQualifier(
            //     new ElementNameAndAttributeQualifier());
            System.out.println("identical: " + diff.identical());
            System.out.println("similar  : " + diff.similar());
        }
    }

    /**
     * Ignores attribute differences on node
     * "/report[\d+]/component[\d+]/component[\d+]/@name"
     */
    private static class IgnoreAttributeDifference 
        implements DifferenceListener {

        @Override
        public int differenceFound(Difference difference) {
            String xpathPattern = 
               "/report\\[\\d+\\]/component\\[\\d+\\]/component\\[\\d+\\]/@name";
            String controlXpath = difference.getControlNodeDetail()
                .getXpathLocation();
            String testXpath = difference.getTestNodeDetail()
                .getXpathLocation();
            if (difference.getId() == DifferenceConstants.ATTR_VALUE_ID
                    && controlXpath.matches(xpathPattern)
                    && testXpath.matches(xpathPattern)) {
                return RETURN_IGNORE_DIFFERENCE_NODES_IDENTICAL;
            } else {
                return RETURN_ACCEPT_DIFFERENCE;
            }
        }

        @Override
        public void skippedComparison(Node node, Node node1) {
            throw new UnsupportedOperationException("Not supported yet.");
        }
    }
}

使用diff.overrideElementQualifier(new ElementNameAndAttributeQualifier())

输出
identical: false
similar  : true

使用diff.overrideDifferenceListener(new IgnoreAttributeDifference())

输出
identical: true
similar  : true