1

这是我要解决的问题。

  1. 我有两个包含 XML 文件的文件夹。
  2. 一个文件夹 - 可以说是“源”文件夹 - 包含大约 350,000 个 XML 文件。
  3. 另一个文件夹 - 可以说是“比较”文件夹 - 包含相同的 350,000 个 XML 文件和更多。
  4. 两者中存在的 350,000 个文件具有相同的名称。完全一样的。
  5. 但是,“source”中的文件与“compare”中的文件略有不同。比较中的文件可能(也可能没有)有一些额外的节点。
  6. 我需要比较“源”和“比较”中的“同名文件”。如果 - 对于“源”中的每个文件 - “源”文件中存在的所有节点都存在于“比较”文件中 - 我需要生成一个好的报告。
  7. 如果不是,即
  8. “源”中有一些文件在“比较”中不存在
  9. 在“源”的任何文件中,都有一些节点不存在于“比较”的相应文件中
  10. 然后我需要创建一个错误报告,其中包含缺少的详细信息。

我目前正在为这个问题寻求 Java + XMLUnit,但不确定是否可以解决它。即使是这样,我也绝对不确定这是否是最佳的工具选择。

任何帮助/建议将不胜感激。

4

4 回答 4

2

就个人而言,我只会对整个文件夹进行文件比较,然后当我找到具有相同名称但校验和大小不同的文件时,然后检查节点。如果文件具有相同的名称、相同的大小和相同的校验和,则检查文件是没有意义的。

于 2012-06-01T09:31:15.587 回答
1

您需要按步骤进行。

  1. 列出您的 350,000 个文件。“比较”文件夹中的这些额外文件与您的问题无关。
  2. 通过考虑完全相同的文件来缩小要比较的文件数量。您可以简单地加载它们并比较生成的字符串,就像 Stirng 使用哈希码进行比较一样。
  3. 比较两个文件夹中的 xml 文件的实例。我认为最好的方法是使用 XMLUnit。应该看起来像:

    Diff diff = new Diff(sourceXml, compareXml); if (diff.identical()) { // whatever you want to do }

当然,如果您的文件不是太大,这种方法效果最好。

于 2012-06-01T09:46:30.730 回答
1

看看 DeltaXML 产品;它可能比自己编写代码便宜。

于 2012-06-01T12:59:57.937 回答
0

第一件事。让我继续记录并说 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:14:58.143 回答