【问题标题】:XML comparison - with a slight twistXML 比较 - 略有不同
【发布时间】:2012-06-01 09:25:30
【问题描述】:

这是我要解决的问题。

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

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

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

【问题讨论】:

    标签: java xml xmlunit


    【解决方案1】:

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

    【讨论】:

    • 我喜欢校验和的想法。我没想到。什么是我创建文件校验和的快速方法?
    • 上次我这样做时,我的文件很小,所以我只是浏览它们,打开它们并手动进行校验和,但我处理的是接近 4,000 而不是 350,000 - 我可以想象那里是一个快速的 md5 库
    【解决方案2】:

    您需要按步骤进行。

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

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

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

    【讨论】:

    • 是的,第 1 点和第 2 点。第 3 点有一些问题。1.xml 实际上是 2.xml 的子集。 2.xml 中有几个节点在 1.xml 中不存在。我们只需要确保1.xml中的所有节点都存在于2.xml中。我正在努力让 XMLUnit 做到这一点。任何建议如何。
    【解决方案3】:

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

    【讨论】:

      【解决方案4】:

      首先要做的事情。让我继续记录并说 XMLUnit 是一个宝石。我爱它。如果您正在查看 XML 值/属性/结构等的一些单元测试。您很可能会找到使用 XMLUnit 的现成解决方案。 This is a good place to start from

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

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

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

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

      经过多次修补,我选择了一个低技术的解决方案。在使用 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++;
                  }
              }
          }
      

      希望这会有所帮助。

      【讨论】:

        猜你喜欢
        • 2016-11-01
        • 1970-01-01
        • 2023-03-21
        • 1970-01-01
        • 1970-01-01
        • 2020-09-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多