【问题标题】:Meaningful XML comparison有意义的 XML 比较
【发布时间】:2015-10-07 20:48:38
【问题描述】:

我正在尝试实现有意义的 XML 比较。我想比较两个不同的 XML 以了解它们是否“有意义”相等。

示例 XML 1:

    <?xml version="1.0" encoding="UTF-8"?>
    <al:moAttribute>
         <al:name>impiId</al:name>
         <al:value>616731935012345678</al:value>
    </al:moAttribute>

    <al:moAttribute>
          <al:name>impuId</al:name>
          <al:value>tel:+16167319350</al:value>
    </al:moAttribute> 

XML 2:

    <?xml version="1.0" encoding="UTF-8"?>
    <al:moAttribute>
          <al:name>impuId</al:name>
          <al:value>tel:+16167319350</al:value>
    </al:moAttribute>
    <al:moAttribute>
         <al:name>impiId</al:name>
         <al:value>616731935012345678</al:value>
    </al:moAttribute>

在此示例中,两个 XML 都“有意义”相同,但仅在元素顺序上有所不同。我想比较他们两个,看看他们是否几乎相等。

我试过这个解决方案:

Best way to compare 2 XML documents in Java

我试过了:

XMLUnit.setIgnoreWhitespace(true);
diff.identical (...);
diff.similar (...);

但如果 XML 的顺序不同,则 XML 比较返回 false。

有什么建议吗?

【问题讨论】:

  • 使用重写的 equals 方法将数据存储在自定义类型中。假设它们都具有相同类型的信息?
  • mentioned的问题有很多解决方案。看起来您在 xmlunit 方面取得了一些进展。请分享完整代码,有人会帮助..

标签: java xml xmlunit


【解决方案1】:

您可以使用 jaxb 来实现您的目标(例如 http://www.mkyong.com/java/jaxb-hello-world-example/

1 使用 jaxb 从给定的两个 xml 文件构造两个 java 对象

每个java对象中有2个,每个xml文件都有一个al:values列表(你只关心这个)

3 比较这两个列表请参考Simple way to find if two different lists contain exactly the same elements?

通过这样做,您将克服订单问题

【讨论】:

    【解决方案2】:

    您可能会发现 xmlunit 的 RecursiveElementNameAndTextQualifier 在这里很有用。这是一个sn-p

    XMLUnit.setIgnoreWhitespace(true);
    XMLUnit.setIgnoreComments(true);
    XMLUnit.setIgnoreAttributeOrder(true);
    
    Document docx1 = XMLUnit.buildDocument(..);
    Document docx2 = XMLUnit.buildDocument(..);
    
    Diff diff = new Diff(docx1, docx2);
    DifferenceEngine engine = new DifferenceEngine(diff);
    
    ElementQualifier qualifier = new RecursiveElementNameAndTextQualifier();
    diff = new Diff(docx1, docx2, engine, qualifier);
    diff.overrideDifferenceListener(new DifferenceListener()
    {
        @Override public int differenceFound(Difference difference)
        {
             //do something with difference
             // return processDiff(difference);
    
        }
    
        @Override public void skippedComparison(Node node, Node node1)
        {
            //no op
        }
    });
    
    //check diff.identical() || diff.similar();
    

    【讨论】:

      【解决方案3】:

      任何 XML 级别的工具都会假定元素的顺序很重要。如果您知道在您的特定词汇表中,元素的顺序并不重要,那么您需要一个能够理解您的词汇表的工具。因此,您最好的选择是编写一个规范化转换(通常在 XSLT 中),从文档中删除不相关的差异(例如,通过在某个合适的键上对元素进行排序),以便在使用标准 XML 工具(可能在 XML 之后)进行比较时,它们比较相等规范化)。

      【讨论】:

        【解决方案4】:

        伙计们,这对我来说绝对完美。 无论变化在哪里,它都会显示出差异。

        import java.io.File;
        import java.io.FileNotFoundException;
        import java.io.FileReader;
        import java.io.IOException;
        import java.net.URL;
        import java.util.List;
        
        import javax.xml.parsers.DocumentBuilder;
        import javax.xml.parsers.DocumentBuilderFactory;
        import javax.xml.parsers.ParserConfigurationException;
        
        import org.custommonkey.xmlunit.DetailedDiff;
        import org.custommonkey.xmlunit.Diff;
        import org.custommonkey.xmlunit.Difference;
        import org.custommonkey.xmlunit.XMLUnit;
        import org.w3c.dom.Document;
        import org.xml.sax.SAXException;
        
        public class Xmlreader {
             public static void main(String[] args) throws SAXException, IOException, ParserConfigurationException {
                 XMLUnit.setIgnoreWhitespace(true);
                 XMLUnit.setIgnoreComments(true);
                 XMLUnit.setIgnoreAttributeOrder(true);
                 DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
                 dbf.setNamespaceAware(true);
                 dbf.setCoalescing(true);
                 dbf.setIgnoringElementContentWhitespace(true);
                 dbf.setIgnoringComments(true);
                 DocumentBuilder db = dbf.newDocumentBuilder();
        
             Document doc1 = db.parse(new File("C:/Users/sravanlx/Desktop/base.xml"));
             doc1.normalizeDocument();
        
             Document doc2 = db.parse(new File("C:/Users/sravanlx/Desktop/base2.xml"));
               /* URL url1 = Xmlreader.class.getResource("C:/Users/sravanlx/Desktop/base.xml");
                URL url2 = Xmlreader.class.getResource("C:/Users/sravanlx/Desktop/base2.xml");
                FileReader fr1 = null;
                FileReader fr2 = null;
                try {
                    fr1 = new FileReader("C:/Users/username/Desktop/base.xml");
                    fr2 = new FileReader("C:/Users/username/Desktop/base2.xml");
                } catch (FileNotFoundException e) {
                    e.printStackTrace();
                }*/
        
                Diff diff = new Diff(doc1, doc2);
                System.out.println("Similar? " + diff.similar());
                System.out.println("Identical? " + diff.identical());
        
                DetailedDiff detDiff = new DetailedDiff(diff);
                List differences = detDiff.getAllDifferences();
                for (Object object : differences) {
                    Difference difference = (Difference)object;
                    System.out.println("***********************");
                    System.out.println(difference);
                    System.out.println("***********************");
                }
            } }
        

        【讨论】:

          【解决方案5】:

          我已经使用 XSLT 解决了这个问题,它在我的 github 中使用了无序树比较。基本上它会输出任何两个 xml 文件的匹配和不匹配,以及它相对于树根的位置。 例如:

          <a>
           <c/>
           <e/>
          </a>
          

          还有:

          <a>
           <e/>
           <c/>
          </a>
          

          将被平等对待。 您只需修改工作表顶部的文件变量以选择要比较的 XML 文件。 https://github.com/sflynn1812/xslt-diff-turbo

          从效率的角度来看,任何树比较算法的速度都是由两棵树中差异的数量决定的。

          目前要将其应用到您的示例中,我建议先去除 xml 命名空间,因为目前不支持。

          【讨论】:

            猜你喜欢
            • 2016-01-03
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2021-08-16
            • 1970-01-01
            • 1970-01-01
            • 2012-03-02
            • 1970-01-01
            相关资源
            最近更新 更多