2

我有两个 XML 文件。第一个 XML 有一堆节点,这些节点也应该出现在第二个 XML 中。第二个 XML 也可能有一些额外的节点。我需要一个可以自动执行此检查的基于 Java 的程序 - 即它应该告诉我给定两个 XML 文件,第一个文件的所有节点都存在于第二个 xml 中。

我在看 Java + XMLUnit。然而,XMLUnit 对此没有确切的解决方案。请帮忙。

谢谢。

4

2 回答 2

2

这是来自 xmlunit 的示例代码

一种方法实际上是比较两个XMLs 并找出差异。

 public void testCompareToSkeletonXML() throws Exception {
        String myControlXML = "<location><street-address>22 any street</street-address><postcode>XY00 99Z</postcode></location>";
        String myTestXML = "<location><street-address>20 east cheap</street-address><postcode>EC3M 1EB</postcode></location>";
        DifferenceListener myDifferenceListener = new IgnoreTextAndAttributeValuesDifferenceListener();
        Diff myDiff = new Diff(myControlXML, myTestXML);
        myDiff.overrideDifferenceListener(myDifferenceListener);
        assertTrue("test XML matches control skeleton XML " + myDiff, myDiff.similar());
    }

您可以将一个XML与另一个进行比较(将一个保留为 skeletal XML)以确定一个是否是另一个的子集。

如果这种方式不令人满意,还有另一种方法可以找到给定两个XMLs 之间的所有差异。

 public void testAllDifferences() throws Exception {
        String myControlXML = "<news><item id=\"1\">War</item>"
            + "<item id=\"2\">Plague</item><item id=\"3\">Famine</item></news>";
        String myTestXML = "<news><item id=\"1\">Peace</item>"
            + "<item id=\"2\">Health</item><item id=\"3\">Plenty</item></news>";
        DetailedDiff myDiff = new DetailedDiff(compareXML(myControlXML, myTestXML));
        List allDifferences = myDiff.getAllDifferences();
        assertEquals(myDiff.toString(), 0, allDifferences.size());
    }

有关更多信息,请参阅XMLUnit 的文档

于 2012-06-03T18:29:10.220 回答
1

第一件事。让我继续记录并说 XMLUnit 是一个宝石。我爱它。如果您正在查看 XML 值/属性/结构等的一些单元测试。您很可能会找到使用 XMLUnit 的现成解决方案。这是一个很好的起点

它是相当可扩展的。它已经带有身份检查(如在 XML 中具有相同的元素和属性以相同的顺序)或相似性检查(如在 XML 中具有相同的元素和属性而不管顺序)。

但是,就我而言,我正在寻找一种稍微不同的用法。我有一个很大的 XML(几百个节点)和一堆 XML 文件(大约 350,000 个)。我不需要比较可以用 XPATH 识别的某些特定节点。它们在 XML 中不一定总是处于相同的位置,但是有一些通用的方法可以用 XPATH 来识别它们。有时,某些节点将根据其他一些节点的值被忽略。只是给一些想法

  1. 这里的逻辑是在我想忽略的节点上,即价格。/书店/书[价格>35]/价格

  2. 这里的逻辑是在一个相对位置的节点上。我想根据价格的价值忽略作者。这两者是按位置相关的。/书店/书[价格=30]/./作者

经过大量修补后,我选择了一个低技术的解决方案。在使用 XMLUnit 比较文件之前,我使用 XPATH 来屏蔽要忽略的节点的值。

    public static int massageData(File xmlFile, Set<String> xpaths, String mask)
        throws JDOMException, IOException {
    logger.debug("Data massaging started for " + xmlFile.getAbsolutePath());
    int counter = 0;

    Document doc = (Document) new SAXBuilder().build(xmlFile
            .getAbsolutePath());

    for (String xpath : xpaths) {
        logger.debug(xpath);
        XPathExpression<Element> xpathInstance = XPathFactory.instance()
                .compile(xpath, Filters.element());
        List<Element> elements = xpathInstance.evaluate(doc);
        // element = xpathInstance.evaluateFirst(doc);
        if (elements != null) {
            if (elements.size() > 1) {
                logger.warn("Multiple matches were found for " + xpath
                        + " in " + xmlFile.getAbsolutePath()
                        + ". This could be a *potential* error.");
            }
            for (Element element : elements) {
                logger.debug(element.getText());
                element.setText(mask);
                counter++;
            }
        }
    }

希望这可以帮助。

于 2012-06-11T11:18:58.297 回答