浅谈 Java 主流开源类库解析 XML

简介:

   在大型项目编码推进中,涉及到 XML 解析问题时,大多数程序员都不太会选用底层的解析方式直接编码。

   主要存在编码复杂性、难扩展、难复用....,但如果你是 super 程序员或是一个人的项目,也不妨一试。

   Jdom/Dom4j/Xstream... 基于底层解析方式重新组织封装的开源类库,简洁明了的 API,稳定高效的运行表现。

   Dom4j 基于 JAXP 解析方式,性能优异、功能强大、极易使用的优秀框架。想了解底层解析方式请翻看:浅谈 Java XML 底层解析方式

   Jdom 你细看内部代码,本质也是基于 JAXP 但包结构被重新组织, API 大量使用了 Collections 类,在性能上被 dm4j 压了好几个档次。

   Xstream 基于 xmlpull 的 OXMapping 技术,更加倾向于将 XML 解析后映射为 Java 世界中的对象,等会在代码中会看的很清楚。

   如果你是一名大型项目技术负责人,需求中涉及 XML 解析方面的要求,在程序员编码开始前你需要在充分了解需求的前提下。

   来拿捏 XML 解析解决方案所采用的技术,请收藏这篇博客,到时将会给你一些帮助和指导。

   实例 demo 地址:https://git.oschina.net/LanboEx/xml-parse-demo.git

   需要解析的还是上篇的中 demo.xml,中规中矩不复杂也不简单。

  demo.xml

1. Jdom

   Jdom 基于树处理 XML,需要将树加载到内存中,所以你懂的大于内存的 XML 文件,Jdom 其实是拒绝的。

   Jdom 具有 SAX 的 java 规则,可以使用推模型分析 XML,所以在一定程度上解析速度可以保证。

   Jdom 没有向下兼容的限制,所以比底层 dom 简单,但在表示文档逻辑模型时,不能保证每个字节真正变换。

   mvn 依赖:

        <dependency>
            <groupId>jdom</groupId>
            <artifactId>jdom</artifactId>
            <version>1.1</version>
        </dependency>

   实例 demo (将 demo.xml studentGridlbb 节点的值解析出来,组成业务实体对象) 。

复制代码
        String path = Thread.currentThread().getContextClassLoader().getResource("demo.xml").getPath();

        SAXBuilder jdomsaxBuilder = new SAXBuilder(false);
        Document doc = jdomsaxBuilder.build(path);
        Element rootElement = doc.getRootElement();

        List<StudentGridlb> studentGridlbList = new ArrayList<>();
        StudentGridlb studentGridlb;
        for (Object classGridlb : rootElement.getChildren("classGridlb")) {
            Element classGridlbEle = (Element) classGridlb;

            for (Object studentGrid : classGridlbEle.getChild("studentGrid").getChildren("studentGridlb")) {
                Element studentGridEle = (Element) studentGrid;
                studentGridlb = new StudentGridlb();
                studentGridlb.setStu_id(studentGridEle.getChildTextTrim("stu_id"));
                studentGridlb.setStu_age(Integer.parseInt(studentGridEle.getChildTextTrim("stu_age")));
                studentGridlb.setStu_name(studentGridEle.getChildTextTrim("stu_name"));
                DateFormat format = new SimpleDateFormat("yyyy-MM-dd");
                studentGridlb.setStu_birthday(format.parse(studentGridEle.getChildTextTrim("stu_birthday")));
                studentGridlbList.add(studentGridlb);
            }
        }
        XMLOutputter outputter = new XMLOutputter();
        outputter.output(doc, new FileOutputStream(path));
复制代码

2. Dom4j

   Dom4j 为了支持 XPath、XML Schema、基于事件处理大文档或流文档。

   Dom4j 为提供构建文档表示的选项,为可通过 Dom4j-API 和标准底层 dom-API 并行访问功能。

   为实现上述宏伟目标,Dom4j 使用接口和抽象基本类方法并大量使用 JDK 中 Collections 类。

   所以 Dom4j 有丰富的 API,在灵活性上面 Dom4j 更占有优势,性能方面也无可挑剔。

   声名在外的 Sun-JAXM,大名鼎鼎的 Hibernate 中XML 配置文件解析都使用的是 Dom4j。

   mvn 依赖:

复制代码
       <!--MetaStuff dom4j-->
        <dependency>
            <groupId>dom4j</groupId>
            <artifactId>dom4j</artifactId>
            <version>1.6.1</version>
            <exclusions>
                <exclusion>
                    <groupId>xml-apis</groupId>
                    <artifactId>xml-apis</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
复制代码

  剔除 xml-apis 的用意 JDK 中已经有对应的类,如不剔除在部署 weblogic 时会出现 Jar 冲突。

  实例 demo (将 demo.xml studentGridlbb 节点的值解析出来,组成业务实体对象) 。

复制代码
        String path = Thread.currentThread().getContextClassLoader().getResource("demo.xml").getPath();

        SAXReader reader = new SAXReader();
        Document document = reader.read(new File(path));

        List<StudentGridlb> studentGridlbList = new ArrayList<>();
        StudentGridlb studentGridlbVo;
        for (Object classGridlb : document.getRootElement().elements("classGridlb")) {
            Element classGridlbEle = (Element) classGridlb;

            for (Object studentGridlb : classGridlbEle.element("studentGrid").elements("studentGridlb")) {
                Element studentGridlbEle = (Element) studentGridlb;

                studentGridlbVo = new StudentGridlb();
                studentGridlbVo.setStu_id(studentGridlbEle.elementTextTrim("stu_id"));
                studentGridlbVo.setStu_age(Integer.parseInt(studentGridlbEle.elementTextTrim("stu_age")));
                studentGridlbVo.setStu_name(studentGridlbEle.elementTextTrim("stu_name"));
                DateFormat format = new SimpleDateFormat("yyyy-MM-dd");
                studentGridlbVo.setStu_birthday(format.parse(studentGridlbEle.elementTextTrim("stu_birthday")));
                studentGridlbList.add(studentGridlbVo);
            }
        }
复制代码

3. Xstream

   Xstream 为基于注解不需要其它辅助类或映射文件 的OXMapping 技术,如果你用过 hibernate 或 mybatis 之类的 ORM 框架就不难理解这里的 OXM。

   Xstream 可以将 JavaBean 序列化为 XML,或将 XML 反序列化为 JavaBean,使得XML序列化不再繁琐。

   Xstream 也可以将 JavaBean 序列化成 Json 或反序列化,使用非常方便。

   没有映射文件而且底层使用 xmlpull 推模型解析 XML,高性能、低内存占用,结合简洁明了的 API,上手基本是分分钟的事情。

   Xstream 同时也可以定制转换类型策略并配有详细的错误诊断,能让你快速定位问题。

   使用 Xstream 时,规范和合理的业务对象命名是关键,下面是针对 demo.xml 我抽象的几个业务实体。

  ClassGrid
  ClassGridlb
  StudentGrid
  StudentGridlb

   抽象好 XML 业务实体之后,接下来就很简单了,只需要三行代码。

        Xstream Xstream = new Xstream(new DomDriver());
        Xstream.processAnnotations(ClassGrid.class);
        ClassGrid classGrid = (ClassGrid) Xstream.fromXML(new File(Thread.currentThread().getContextClassLoader().getResource("demo.xml").getPath()));

4. 小结

   如果你看到过我上篇底层解析方式和这篇的开源类库对比下,封装优秀类库代码编写量会小很多,简洁的 API 使用起来很顺手。

   Dom4j/Jdom 都支持对 XML 文档的增删改查动作,毕竟是已树模型加载到内存中进行的操作。

   Xstream 专注于 XML 和业务对象之间的序列化和反序列化,删除和修改原 XML 文档实践起来相当困难。

   我个人的建议,在项目中同时引入 Dom4j 和 Xstream,在 XMl 复杂情况下,可以考虑使用 Dom4j 获取出感兴趣的部分。

   然后抽象出合适的业务实体,使用 Xstream 进行序列化, 进行系统逻辑后续处理。

本文转自Orson博客园博客,原文链接:http://www.cnblogs.com/java-class/p/6901910.html,如需转载请自行联系原作者

相关文章
|
9天前
|
Java
Java中ReentrantLock释放锁代码解析
Java中ReentrantLock释放锁代码解析
25 8
|
11天前
|
XML JavaScript 前端开发
xml文件使用及解析
xml文件使用及解析
|
3天前
|
Java API 数据库
深入解析:使用JPA进行Java对象关系映射的实践与应用
【4月更文挑战第17天】Java Persistence API (JPA) 是Java EE中的ORM规范,简化数据库操作,让开发者以面向对象方式处理数据,提高效率和代码可读性。它定义了Java对象与数据库表的映射,通过@Entity等注解标记实体类,如User类映射到users表。JPA提供持久化上下文和EntityManager,管理对象生命周期,支持Criteria API和JPQL进行数据库查询。同时,JPA包含事务管理功能,保证数据一致性。使用JPA能降低开发复杂性,但需根据项目需求灵活应用,结合框架如Spring Data JPA,进一步提升开发便捷性。
|
5天前
|
存储 缓存 Java
线程同步的艺术:探索 JAVA 主流锁的奥秘
本文介绍了 Java 中的锁机制,包括悲观锁与乐观锁的并发策略。悲观锁假设多线程环境下数据冲突频繁,访问前先加锁,如 `synchronized` 和 `ReentrantLock`。乐观锁则在访问资源前不加锁,通过版本号或 CAS 机制保证数据一致性,适用于冲突少的场景。锁的获取失败时,线程可以选择阻塞(如自旋锁、适应性自旋锁)或不阻塞(如无锁、偏向锁、轻量级锁、重量级锁)。此外,还讨论了公平锁与非公平锁,以及可重入锁与非可重入锁的特性。最后,提到了共享锁(读锁)和排他锁(写锁)的概念,适用于不同类型的并发访问需求。
35 2
|
7天前
|
Java
Java 15 神秘登场:隐藏类解析未知领域
Java 15 神秘登场:隐藏类解析未知领域
12 0
|
7天前
|
安全 Java 编译器
接口之美,内部之妙:深入解析Java的接口与内部类
接口之美,内部之妙:深入解析Java的接口与内部类
25 0
接口之美,内部之妙:深入解析Java的接口与内部类
|
11天前
|
XML JSON JavaScript
Java中XML和JSON的比较与应用指南
本文对比了Java中XML和JSON的使用,XML以自我描述性和可扩展性著称,适合结构复杂、需验证的场景,但语法冗长。JSON结构简洁,适用于轻量级数据交换,但不支持命名空间。在Java中,处理XML可使用DOM、SAX解析器或XPath,而JSON可借助GSON、Jackson库。根据需求选择合适格式,注意安全、性能和可读性。
23 0
|
17天前
|
XML JSON JavaScript
使用JSON和XML:数据交换格式在Java Web开发中的应用
【4月更文挑战第3天】本文比较了JSON和XML在Java Web开发中的应用。JSON是一种轻量级、易读的数据交换格式,适合快速解析和节省空间,常用于API和Web服务。XML则提供更强的灵活性和数据描述能力,适合复杂数据结构。Java有Jackson和Gson等库处理JSON,JAXB和DOM/SAX处理XML。选择格式需根据应用场景和需求。
|
26天前
|
Java 程序员 C#
静态构造方法解析,Java新手必看技能
静态构造方法解析,Java新手必看技能
8 0
|
29天前
|
XML Java 数据格式
使用java解析XML文件的步骤
使用java解析XML文件的步骤
10 0

推荐镜像

更多