0

我有两个 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 选项,但没有任何效果。请让我知道解决方案。

4

1 回答 1

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
于 2016-02-01T08:20:45.987 回答