Java解析XML的实践

2023-02-16 09:59:51 浏览数 (1)

最近写个程序,其中要解析XML格式的文件,XML的好处都很清楚,

(1)便于不同应用程序之间通信。

(2)便于不同平台之间通信。

(3)便于不同平台之间数据共享。

通过Java解析XML,通常有四种方式,DOM、SAX、DOM4J和JDOM。

DOM的优点,

形成了树结构,直观,容易理解,代码更容易编写。

解析过程中树结构保存在内存中,方便修改。

缺点,

当xml文件较大时,对内存的耗费比较大,容易影响解析的性能,造成内存溢出。

SAX的优点,

采用事件驱动的模式,对内存的耗费比较小。

适用于只需要处理XML中数据时。

缺点,

不易编码。

很难同时访问同一个XML中的多处不同数据。

JDOM

仅使用具体累而不使用接口。

API大量使用了Collections类。

DOM4J

是JDOM的一种智能分支,合并了很多超出基本XML文档表示的功能。

DOM4J使用接口和抽象基本类方法,是一个优秀的Java XML API。

具有性能优异、灵活性好、功能强大和极端易用实用的特点。

开放源代码。

根据实际需求,选择了JDOM作为解析工具。

首先,引入jdom的三方包,

代码语言:javascript复制
<dependency>
  <groupId>org.jdom</groupId>
  <artifactId>jdom</artifactId>
  <version>1.1</version>
</dependency>

测试的XML文件,如下所示,

代码语言:javascript复制
<?xml version="1.0" encoding="UTF-8"?>
<studentInfo>
  <student id="1">
    <name>小明</name>
    <age>28</age>
    <birthday>19920114</birthday>
    <home>河南</home>
  </student>
  <student id="2">
    <name>小刚</name>
    <age>29</age>
    <birthday>19911114</birthday>
    <home>湖北</home>
  </student>
  <student id="3">
    <name>小红</name>
    <age>28</age>
    <birthday>19920115</birthday>
    <home>湖南</home>
  </student>
</studentInfo>

测试的代码,如下所示,

代码语言:javascript复制
import org.jdom.Attribute;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.input.SAXBuilder;


import java.io.FileInputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;


publicclass ReadXmlJdomService {
    public static void main(String[] args){
        System.out.println("readXmlByJdom start:");
        readXmlByJdom();
        System.out.println("readXmlByJdom end.");
    }


    //jdom方式
    private static void readXmlByJdom(){
        List<Student> bList = new ArrayList<Student>();
        try {
            // 创建一个SAXBuilder对象
            SAXBuilder builder = new SAXBuilder();
            // 创建一个输入流
            InputStream in = new FileInputStream("/test/test.xml");


            // 处理乱码情况
            InputStreamReader isr = new InputStreamReader(in, "UTF-8");


            // 通过build方法,将输入流加载到SAXBuilder中
            Document doc = builder.build(isr);
            // 通过Document对象获取根节点
            Element foo= doc.getRootElement();
            // 获取根节点下子节点名
            List<Element> allChildren = foo.getChildren();
            // 进行解析
            for (Element student : allChildren) {


                Student b = new Student();


                System.out.println("开始解析第" (allChildren.indexOf(student) 1) "个同学");
                // 解析student属性集合
                List<Attribute> attrList = student.getAttributes();
                // 遍历(针对不清楚节点下属性名)
                for (Attribute attr : attrList) {
                    System.out.println("属性名:" attr.getName()  " -- 属性值:" attr.getValue());
                    if("id".equals(attr.getName())){
                        b.setId(attr.getValue());
                    }
                }


                // 清楚知道属性名获取属性值
                String v = student.getAttributeValue("id");
                System.out.println("清楚知道属性名" v);


                // 对student节点子节点的节点名和节点值进行遍历
                List<Element> studentChiles = student.getChildren();
                for (Element element : studentChiles) {
                    System.out.println("属性名:" element.getName()  " -- 属性值:" element.getValue());


                    if("name".equals(element.getName())){
                        b.setName(element.getValue());
                    }elseif("age".equals(element.getName())){
                        b.setAge(element.getValue());
                    }elseif("home".equals(element.getName())){
                        b.setHome(element.getValue());
                    }elseif("birthday".equals(element.getName())){
                        b.setBirthday(element.getValue());
                    }elseif("id".equals(element.getName())){
                        b.setId(element.getValue());
                    }
                }
                System.out.println("结束解析第" (allChildren.indexOf(student) 1) "个同学");
                bList.add(b);
                b = null;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

打印的解析过程,如下所示,

代码语言:javascript复制
readXmlByJdom start:
开始解析第1个同学
属性名:id -- 属性值:1
清楚知道属性名1
属性名:name -- 属性值:小明
属性名:age -- 属性值:28
属性名:birthday -- 属性值:19920114
属性名:home -- 属性值:河南
结束解析第1个同学
开始解析第2个同学
属性名:id -- 属性值:2
清楚知道属性名2
属性名:name -- 属性值:小刚
属性名:age -- 属性值:29
属性名:birthday -- 属性值:19911114
属性名:home -- 属性值:湖北
结束解析第2个同学
开始解析第3个同学
属性名:id -- 属性值:3
清楚知道属性名3
属性名:name -- 属性值:小红
属性名:age -- 属性值:28
属性名:birthday -- 属性值:19920115
属性名:home -- 属性值:湖南
结束解析第3个同学
readXmlByJdom end.

通过这段代码,重点是需要理解他的解析过程,就可以根据实际用到的XML格式,写出对应的解析逻辑。

盯着这些代码,不一定能做大举一反三,动起来才能做到更深入地理解,因此,不能光纸上谈兵,实践很重要。

0 人点赞