工作中遇到了一个需求,需要对比两个xml文件,并记录差异位置及差异内容,以实现类似于git diff的效果。经过调研,发现了现成的轮子:java-diff-utils,它是基于Myers Diff 差分算法来实现的,这里就不记录算法的细节了,仅记录用例,方便以后抄作业。

一. 添加依赖

<!--对比工具依赖-->
<dependency>
     <groupId>io.github.java-diff-utils</groupId>
     <artifactId>java-diff-utils</artifactId>
     <version>4.11</version>
</dependency>

<dependency>
     <groupId>commons-io</groupId>
     <artifactId>commons-io</artifactId>
     <version>2.11.0</version>
</dependency>

二. 代码实现

这里我就把项目的pom文件复制两份简单做了改动,用作测试用例

import com.github.difflib.patch.AbstractDelta;
import com.github.difflib.patch.Patch;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.List;

public class XmlCompare {

    public static void main(String[] args) {
        String originalFilePath = "D:\\test\\xml\\pom1.xml";
        String revisedFilePath = "D:\\test\\xml\\pom2.xml";
        compareXml(originalFilePath, revisedFilePath);
    }

    private static void compareXml(String originalFilePath, String revisedFilePath) {
        //原始文件
        List<String> original = null;
        //对比文件
        List<String> revised = null;
        File originalFile = new File(originalFilePath);
        File revisedFile = new File(revisedFilePath);
        try {
            original = Files.readAllLines(originalFile.toPath());
            revised = Files.readAllLines(revisedFile.toPath());
        } catch (IOException e) {
            e.printStackTrace();
        }
        //两文件的不同点
        Patch<String> patch = com.github.difflib.DiffUtils.diff(original, revised);
        List<AbstractDelta<String>> patchDeltas = new ArrayList<>(patch.getDeltas());
        for (AbstractDelta delta: patchDeltas) {
            //此处根据自己的业务需求对delta进行处理,这里就简单打印看下效果
            System.out.println("修改类型为:"+delta.getType());
            System.out.println("源文件位置:"+delta.getSource().getPosition());
            System.out.println("源文件内容:"+delta.getSource().getLines());
            System.out.println("对比文件位置:"+delta.getTarget().getPosition());
            System.out.println("对比文件内容:"+delta.getTarget().getLines());
        }
    }

}

三. 执行效果

可以看到,能够准确获得两个xml文件的差异及差异类型。

四. 扩展

以上示例属于非常原始和基础的使用方式,我在调研的时候发现有大佬文章记录了非常完善的用例,这里做个转载记录:

类似svn git的功能,如何实现找出文件的差异 ? - 程序员-老虎的回答 - 知乎

最终实现效果:

Logo

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。

更多推荐