DOM4J 解析XML文件 (经典号码归属地案例)

Java 高级篇

笔记首页

序号内容链接地址
1IO流https://blog.csdn.net/weixin_44141495/article/details/108165699
2多线程https://blog.csdn.net/weixin_44141495/article/details/108277941
3网络编程https://blog.csdn.net/weixin_44141495/article/details/108190461
4Jsonhttps://blog.csdn.net/weixin_44141495/article/details/108285762
5Xmlhttps://blog.csdn.net/weixin_44141495/article/details/108285125
6反射https://blog.csdn.net/weixin_44141495/article/details/108291945
7注解https://blog.csdn.net/weixin_44141495/article/details/108293331
8枚举https://blog.csdn.net/weixin_44141495/article/details/108696056
9Java8新特性https://blog.csdn.net/weixin_44141495/article/details/108696123

XML

可扩展标记语言(eXtensible Markup Language)。

特性:

  1. xml具有平台无关性, 是一门独立的标记语言.

  2. xml具有自我描述性

应用场景

  1. 网络数据传输.

  2. 数据存储

  3. 配置文件

文件格式

  1. .XML文件是保存XML数据的一种方式

  2. XML数据也可以以其他的方式存在(如在内存中构建XML数据)。

  3. 不要将XML语言狭隘的理解成XML文件

解析方式

SAX解析

  • SAX(Simple API for XML)解析是按照 xml 文件的顺序一步一步的来解析。

DOM解析

  • 分析器将一个 XML 文档转换成一个对象模型的集合(通常称为 DOM 树),应用程序正是通过对这个对象模型的操作,来实现对 XML 文档数据的操作。

JDOM解析

  • JDOM 是一种使用 XML 的独特 Java 工具包,用于快速开发 XML 应用程序。JDOM 是一个开源项目,它基于树形结构,利用纯 Java 的技术对 XML 文档实现解析、生成、序列化及多种操作。

DOM4J解析

  • dom4j 是一个简单的开源库,用于处理 XML、 XPath 和 XSLT,它基于 Java 平台,使用 Java 的集合框架,全面集成了 DOM,SAX 和 JAXP。

区别

  • DOM

    优点:
    1、允许应用程序对数据和结构做出更改。
    2、访问是双向的,可以在任何时候在树中上下导航,获取和操作任意部分的数据。

    缺点:
    1、通常需要加载整个XML文档来构造层次结构,消耗资源大

  • SAX

    优点:
    1、不需要等待所有数据都被处理,分析就能立即开始。
    2、只在读取数据时检查数据,不需要保存在内存中。
    3、可以在某个条件得到满足时停止解析,不必解析整个文档。
    4、效率和性能较高,能解析大于系统内存的文档。

    缺点:
    1、需要应用程序自己负责TAG的处理逻辑(例如维护父/子关系等),使用麻烦。
    2、单向导航,很难同时访问同一文档的不同部分数据,不支持XPath。

那我们开发中使用哪种解析比较多呢?

答案是:DOM解析

  • DOM解析将一个XML文件当做一个对象,我们可以以操作一个对象的方法简单的操作XML,而且DOM解析有很多分支,DOM4J,JDOM有面向接口,支持XPATH,功能非常强大

  • DOM解析的缺点是消耗内存,而实际上开发中XML文件一般都是一些配置文件,大小都是几K,所以缺点忽略不计。


DOM4J常用方法

这是中国手机号归属地查询网址返回的结果,结果为XML,我们试着解析这个文件。

<?xml version="1.0" encoding="UTF-8" ?>
<root id="1">
    <success status="200" key="12sr">1</success>
    <result>
        <status>ALREADY_ATT</status>
        <phone>13800138000</phone>
        <area>010</area>
        <postno>100000</postno>
        <att>中国,北京</att>
        <ctype>中国移动138卡</ctype>
        <par>1380013</par>
        <prefix>138</prefix>
        <operators>中国移动</operators>
        <style_simcall>中国,北京</style_simcall>
        <style_citynm>中华人民共和国,北京市</style_citynm>
    </result>
</root>

DOM术语

image-20200828184257501


获取节点名

public static void main(String[] args) throws FileNotFoundException, DocumentException {
    //创建DOM4J解析工具
    SAXReader reader = new SAXReader();
    Document doc = reader.read(new FileInputStream(new File("E:\\Phone.xml")));
    //获取根节点
    Element rootElement = doc.getRootElement();
    System.out.println("根节点:"+rootElement.getName());
    //获取根节点的所有子节点的数组
    List<Element> elements = rootElement.elements();
    //遍历数组
    for (Element element : elements) {
        System.out.println("子节点:"+element.getName());
    }
    //通过标签名获得子节点
    Element result = rootElement.element("result");
    System.out.println("result: "+result.getName());
}

结果

根节点:root
子节点:success
子节点:result
result: result

获取属性值

public static void main(String[] args) throws FileNotFoundException, DocumentException {
    //创建DOM4J解析工具
    SAXReader reader = new SAXReader();
    Document doc = reader.read(new FileInputStream(new File("Phone.xml")));
    //获取根节点
    Element rootElement = doc.getRootElement();
    //获取根节点的ID属性值
    String id = rootElement.attributeValue("id");
    System.out.println("id="+id);
    Element success = rootElement.element("success");
    List<Attribute> attributes = success.attributes();
    for (Attribute attribute : attributes) {
        System.out.println(attribute.getName()+": "+attribute.getValue());
    }
}

结果

id=1
status: 200
key: 12sr

获取文本内容

public static void main(String[] args) throws FileNotFoundException, DocumentException {
    //创建DOM4J解析工具
    SAXReader reader = new SAXReader();
    Document doc = reader.read(new FileInputStream(new File("Phone.xml")));
    //获取根节点
    Element rootElement = doc.getRootElement();
    //获取result节点的内容
    Element result = rootElement.element("result");
    //获取result节点的子节点数组
    List<Element> elements = result.elements();
    //遍历打印result所有子节点的文本内容
    for (Element element : elements) {
        System.out.println(element.getName()+": "+element.getText());
    }
}

结果

status: ALREADY_ATT
phone: 13800138000
area: 010
postno: 100000
att: 中国,北京
ctype: 中国移动138卡
par: 1380013
prefix: 138
operators: 中国移动
style_simcall: 中国,北京
style_citynm: 中华人民共和国,北京市

创建一个XML

直接上代码

 public static void main(String[] args) {
        File file = new File("E:\\ideaProjects\\study\\KaiKeBa\\src\\com\\kaikeba\\course03pro\\createXmlFile.xml");
        createDom4j(file);
    }

    public static void createDom4j(File file) {
        try {
            // 创建一个Document实例
            Document doc = DocumentHelper.createDocument();

            // 添加根节点
            Element root = doc.addElement("root");

            // 在根节点下添加第一个子节点
            Element oneChildElement= root.addElement("person").addAttribute("attr", "root noe");
            oneChildElement.addElement("people")
                    .addAttribute("attr", "child one")
                    .addText("person one child one");
            oneChildElement.addElement("people")
                    .addAttribute("attr", "child two")
                    .addText("person one child two");

            // 在根节点下添加第一个子节点
            Element twoChildElement= root.addElement("person").addAttribute("attr", "root two");
            twoChildElement.addElement("people")
                    .addAttribute("attr", "child one")
                    .addText("person two child one");
            twoChildElement.addElement("people")
                    .addAttribute("attr", "child two")
                    .addText("person two child two");

            // xml格式化样式
            // OutputFormat format = OutputFormat.createPrettyPrint(); // 默认样式

            // 自定义xml样式
            OutputFormat format = new OutputFormat();
            format.setIndentSize(2);  // 行缩进
            format.setNewlines(true); // 一个结点为一行
            format.setTrimText(true); // 去重空格
            format.setPadText(true);
            format.setNewLineAfterDeclaration(false); // 放置xml文件中第二行为空白行

            // 输出xml文件
            XMLWriter writer = new XMLWriter(new FileOutputStream(file), format);
            writer.write(doc);
            System.out.println("dom4j CreateDom4j success!");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

运行结果

<?xml version="1.0" encoding="UTF-8"?>
<root>
  <person attr="root noe">
    <people attr="child one">person one child one</people>
    <people attr="child two">person one child two</people>
  </person>
  <person attr="root two">
    <people attr="child one">person two child one</people>
    <people attr="child two">person two child two</people>
  </person>
</root>

使用代码创建XML文件还是比较麻烦的,在XML体比较少的情况下,还是推荐人肉输入。如果XML用于存储大量内容,要用很多循环嵌套输出,那么就用DOM4J进行解析。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值