一 简介

在Java中,可以使用多种方式来解析

(1)DOM

DOM是用与平台和语言无关的方式表示

因此在使用DOM这种方式来解析

优点: 整个文档树在内存中,便于操作;支持删除、修改、重新排列等多种操作

缺点: 将整个文档调入内存(包括无用的节点),浪费时间和内存,如果

(2)SAX

由于DOM解析

SAX解析

优点:不用事先载入整个文档,占用资源(内存)少;使用SAX方式解析编写的代码要比使用DOM解析编写的代码少

缺点:不是持久的;事件过后,若没保存数据,那么数据就丢了;无状态性;从事件中只能得到文本,但不知该文本属于哪个元素

(3)JDOM

使用JDOM来解析

优点:开源项目;比DOM容易理解

缺点:JDOM自身不包含解析器。它通常使用SAX2解析器来解析和验证输入

(4)DOM4J

DOM4J 是一个非常非常优秀的Java

由于DOM4J无论在性能方面还是代码编写方面都是很强大的,特别是当

优点:

开源项目

DOM4J是JDOM的一种智能分支,它合并了需要超出基本

具有性能优异、灵活性好、简单易用等特点

二 DOM解析

(1)在进行代码编写测试之前,需要准备一个

demo1.

登录后复制

(2)代码实例:

package cn.zifangsky.
登录后复制

从上面的代码可以看出,在使用DOM来解析

创建一个文档构建器工厂(DocumentBuilderFactory)实例

通过上面的DocumentBuilderFactory生成一个新的文档构建器(DocumentBuilder)

使用上面的DocumentBuilder解析(parse)一个

通过Document获取指定id的节点或根据节点名获取所有符合条件的节点集合

遍历每个节点,可以获取该节点的属性、属性值等相关参数

如果该节点还存在子节点,可以根据上面的方式继续遍历它的所有子节点

(3)上面的代码输出如下:

登录后复制

三 SAX解析

在进行本次测试时,并不引入其他

由于SAX解析

(1)解析处理器SAXParseHandler.java:

package cn.zifangsky. 0){
            System.out.println("元素'" + qName + "'的属性是:");
             
            for(int i=0;i
登录后复制

关于上面代码的一些含义我这里就不再做解释了,可以自行参考注释内容

(2)测试:

SAXParseTest.java文件:

package cn.zifangsky.
登录后复制

从上面的代码可以看出,使用SAX解析

(3)上面测试的输出如下:

SAX解析开始
元素'user'的属性是:
    属性名:id,属性值: 1
 
登录后复制

ii)同时准备一个Java实体类,恰好跟上面的

User.java:

package cn.zifangsky. ownPet;
 
    public String getName() {
        return name;
    }
 
    public void setName(String name) {
        this.name = name;
    }
 
    public String getSex() {
        return sex;
    }
 
    public void setSex(String sex) {
        this.sex = sex;
    }
 
    public int getAge() {
        return age;
    }
 
    public void setAge(int age) {
        this.age = age;
    }
 
    public String getContact() {
        return contact;
    }
 
    public void setContact(String contact) {
        this.contact = contact;
    }
 
    protected List getOwnPet() {
        return ownPet;
    }
 
    protected void setOwnPet(List ownPet) {
        this.ownPet = ownPet;
    }
 
    @Override
    public String toString() {
        return "User [name=" + name + ", sex=" + sex + ", age=" + age
                + ", contact=" + contact + ", ownPet=" + ownPet + "]";
    }
}
登录后复制

iii)测试代码:

package cn.zifangsky. ownPet = new ArrayList();
         
        SAXReader saxReader = new SAXReader();
        try {
            Document document = saxReader.read(new File( children = rootElement.elements();  //获取根节点的子节点
            //遍历
            for(Element child : children){
                String elementName = child.getName();  //节点名
                String elementValue = child.getStringValue();  //节点值
                switch (elementName) {
                case "name":
                    user.setName(elementValue);
                    break;
                case "sex":
                    user.setSex(elementValue);
                    break; 
                case "age":
                    user.setAge(Integer.valueOf(elementValue));
                    break;
                case "contact":
                    user.setContact(elementValue);
                    break; 
                case "ownPet":
                    ownPet.add(elementValue);
                    break; 
                default:
                    break;
                }
     
            }
            user.setOwnPet(ownPet);
 
        } catch (Exception e) {
            e.printStackTrace();
        }
        return user;
    }
     
    public static void main(String[] args) {
        
登录后复制

经过前面的分析之后,上面这个代码也是很容易理解的:通过遍历节点,如果节点名跟Java类中的某个属性名相对应,那么就将节点值赋值给该属性

iv)上面的代码输出如下:

User [name=zifangsky, sex=男, age=100, contact=https://www.zifangsky.cn, ownPet=[旺财, 九头猫妖]]
登录后复制

(3)解析一个

DOM4JTest2:

package cn.zifangsky. elementList = element.elements(); // 当前节点的子节点List
 
        // 空格
        StringBuffer spacebBuffer = new StringBuffer("");
        for (int i = 0; i < level; i++)
            spacebBuffer.append("    ");
        String space = spacebBuffer.toString();
 
        // 输出开始节点及其属性值
        System.out.print(space + " attributes = element.attributes();
        for (Attribute attribute : attributes)
            System.out.print(" " + attribute.getName() + "=\""
                    + attribute.getText() + "\"");
 
        // 有子节点
        if (elementList.size() > 0) {
            System.out.println(">");
            // 遍历并递归
            for (Element child : elementList) {
                print(child, level + 1);
            }
            // 输出结束节点
            System.out.println(space + "");
 
        } else {
            // 如果节点没有文本则简化输出
            if (element.getStringValue().trim().equals(""))
                System.out.println(" />");
            else
                System.out.println(">" + element.getStringValue() + "");
        }
 
    }
 
    public static void main(String[] args) {
        DOM4JTest2 test2 = new DOM4JTest2();
        test2.parse("src/cn/zifangsky/
登录后复制

这段代码同样没有什么新的东西,原理就是利用递归来不断进行解析输出,注意一下不同层次的节点的缩进即可。刚开始测试时建议用一些结构比较简单的代码,如上面的demo1.

demo3.

登录后复制

为什么我在标题上说的是尽可能原样输出,其原因就是上面那段解析代码在碰到下面这种



登录后复制

这段



登录后复制


09-18 02:07