Java---XML的解析(1)-DOM解析

本文涉及的产品
云解析 DNS,旗舰版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
全局流量管理 GTM,标准版 1个月
简介: Java---XML的解析(1)-DOM解析

本章只讲DOM解析。接下来还会学习Dom4j和StAX 解析技术

DOM解析:

DOM解析一次将所有的元素全部加载到内存中:如有以下XML文档:


 

<user>
        <name>Jack</name>
        <age>30</age>
    </user>


由于DOM解析,一次性的将所有元素(包含属性和文本) 全部加载到内存中,所以不适用于解析大量的数据。

image.png

JAXP-DOM解析:


包:  

javax.xml.parse – 关键类DocumentBuilder,文档解析对像。  

org.w3c.dom – 关键类Document代表内存中的文档对像模型。

java.xml – 关键类Transformer,用于将内存中的文档保存到文件中。



image.png

image.png


users.xml:-在xml4文件夹下面

<?xml version="1.0" encoding="UTF-8" standalone="no"?><users>
    <user id="A001">
        <name>Tom</name>
        <age>23</age>
    </user>
    <user id="C001">
        <name>李四</name>
        <age>33</age>
    </user>
</users>
<!--添加进来了吧,为了演示而建立的简单xml文档-->

代码演示:

package cn.hncu.dom;
import java.io.File;
import java.io.IOException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.junit.Test;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
/**
 * @author 陈浩翔 2016-6-29
 */
public class DomDemo1 {
    @Test
    // 需求:把第一个user节点的name的值取出来
    public void getDom() throws SAXException, IOException,
            ParserConfigurationException {
        // 第一步,通过DocumentBuilderFactory类中的工厂方法等到一个dbf对象
        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
        // 第二步,通过dbf对象创建出一个DocumentBuilder对象
        DocumentBuilder db = dbf.newDocumentBuilder();
        // 第三步,通过db对象创建出一个Document对象
        Document dom = db.parse("xml4/users.xml");
        // db.parse( new File("xml4/users.xml") );//也可以
        System.out.println(dom);// [#document: null]
        Node root = dom.getFirstChild();// 这个是根节点
        System.out.println("root:" + root);// root:[users: null]
        System.out.println(root.getNodeName());// users
        System.out.println(root.getFirstChild().getNodeName());// #text
        // 上面一句的输出是:#text ----dom中把空白符也看成是一个Node,这种情况对我们的解析通常会造成很大的麻烦
        // ※※为解决上面的问题,我们以后解析时尽量不要用Node,而要用Element。
        // 因为Element是元素它不包含属性和文字内容(包括空白符),因此可避开空白符的干扰
        Element eRoot = (Element) root;
        NodeList list = eRoot.getElementsByTagName("user");
        System.out.println("user元素的数量:" + list.getLength());
        System.out.println("第2个user元素" + list.item(1));
        Node user1Node = list.item(0);
        Element eUser1 = (Element) user1Node;// 要把Node强转成Element,因为Element是子接口,里面有getElementBy*等方法,而Node没有(只能采用childNodes的方式,这种方式会受空白符的干扰)
        NodeList listNames = eUser1.getElementsByTagName("name");
        String nm = listNames.item(0).getNodeName();// name--标签名
        String nmVal = listNames.item(0).getTextContent();// 标签内部所包含的文本内容----相当于JavaScript中的innerText
        System.out.println(nm + "," + nmVal);
    }
    @Test //需求:把第二个user节点的age值取出来
    public void getAge()throws Exception{
        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
        DocumentBuilder db = dbf.newDocumentBuilder();
        Document dom = db.parse(new File("xml4/users.xml"));
        Element root = (Element)dom.getFirstChild();
        Element user2 = (Element)root.getElementsByTagName("user").item(1);
        Element eAge = (Element)user2.getElementsByTagName("age").item(0);
        String age = eAge.getTextContent();
        System.out.println("age:"+age);
    }
    //用java对xml文档进行CRUD---创建,遍历,更新,删除
    //创建---需求:添加一个新的user
    @Test
    public void create() throws Exception{
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        DocumentBuilder db = factory.newDocumentBuilder();
        Document dom = db.parse(new File("xml4/users.xml"));
        Element root = (Element) dom.getFirstChild();
        //创建一个新的user元素
        Element eUserNode = dom.createElement("user");
        eUserNode.setAttribute("id", "C001");//给元素添加属性
        //创建name和age子元素
        Element eName = dom.createElement("name");
        eName.setTextContent("李四");//设置name标签容器中包含的文字
        Element eAgeNode = dom.createElement("age");
        eAgeNode.setTextContent("33");
        //把所创建的元素组装成一颗子树,添加到整颗dom树上
        eUserNode.appendChild(eName);
        eUserNode.appendChild(eAgeNode);
        root.appendChild(eUserNode);
        //再把当前内存中的dom对象存储进xml文件
        TransformerFactory tf = TransformerFactory.newInstance();
        Transformer trans = tf.newTransformer();
        trans.transform(new DOMSource(dom), new StreamResult("xml4/users.xml"));
    }
    //遍历---查找
    @Test
    public void query() throws Exception{
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        DocumentBuilder db = factory.newDocumentBuilder();
        Document dom = db.parse("xml4/users.xml");
        Element root = (Element) dom.getFirstChild();//得到根节点
        NodeList list = root.getElementsByTagName("user");//这个user是xml文档中的元素
        for(int i=0;i<list.getLength();i++){//循环遍历
            Element user = (Element) list.item(i);
            String id = user.getAttribute("id");
            String name = user.getElementsByTagName("name").item(0).getTextContent();
            String age = user.getElementsByTagName("age").item(0).getTextContent();
            System.out.println("id:"+id+",name:"+name+",age:"+age);
            System.out.println("---------------------------------");
        }
    }
    //更新---要求:把最后一个user的年龄+10
    @Test
    public void update() throws Exception{//为了方便,就只抛这个异常了,如果是以后搞项目,一定要详细才行的
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        DocumentBuilder db = factory.newDocumentBuilder();
        Document dom = db.parse( new File("xml4/users.xml") );
        Element root = (Element) dom.getFirstChild();
        NodeList list = root.getElementsByTagName("user");
        Element eUser = (Element) list.item( list.getLength()-1 );
        String  sAge = eUser.getElementsByTagName("age").item(0).getTextContent();
        int age = Integer.parseInt(sAge)+10;
        System.out.println("age:"+eUser.getElementsByTagName("age").item(0).getTextContent());
        eUser.getElementsByTagName("age").item(0).setTextContent(""+age);
        System.out.println(eUser.getElementsByTagName("age").item(0).getTextContent());
        //把内存中的当前dom对象存储到xml文件中
        TransformerFactory tf = TransformerFactory.newInstance();
        Transformer trans = tf.newTransformer();
        trans.transform(new DOMSource(dom), new StreamResult("xml4/users.xml"));
        //把xml源输出到目标---如果目标存在则是更新,否则就是创建
    }
    //删除---需求:删除最后一个元素
    @Test
    public void delete() throws Exception{
        // 第一步,通过DocumentBuilderFactory类中的工厂方法等到一个dbf对象
        DocumentBuilderFactory foctory = DocumentBuilderFactory.newInstance();
        // 第二步,通过dbf对象创建出一个DocumentBuilder对象
        DocumentBuilder db =foctory.newDocumentBuilder();
        // 第三步,通过db对象创建出一个Document对象
        Document dom = db.parse("xml4/users.xml");
        //获取根节点
        Element root =(Element)dom.getFirstChild();
        //获取将要删除的元素
        NodeList list = root.getElementsByTagName("user");
        Element e = (Element)list.item( list.getLength()-1 );
        e.getParentNode().removeChild(e);
        //在内存中已经移除了。
        //把当前内存中的dom对象存储到xml文件中
        TransformerFactory tf = TransformerFactory.newInstance();
        Transformer trans = tf.newTransformer();
        trans.transform(new DOMSource(dom), new StreamResult( "xml4/users.xml" ));
    }
}

小知识点:

注意:子类才可以当父类用。

父类的话,如果你确定那个类一定是这个父类的某个子类了,才可以强转为子类!!!

目录
相关文章
|
8天前
|
人工智能 自然语言处理 Java
FastExcel:开源的 JAVA 解析 Excel 工具,集成 AI 通过自然语言处理 Excel 文件,完全兼容 EasyExcel
FastExcel 是一款基于 Java 的高性能 Excel 处理工具,专注于优化大规模数据处理,提供简洁易用的 API 和流式操作能力,支持从 EasyExcel 无缝迁移。
63 9
FastExcel:开源的 JAVA 解析 Excel 工具,集成 AI 通过自然语言处理 Excel 文件,完全兼容 EasyExcel
|
16天前
|
存储 缓存 Java
Java 并发编程——volatile 关键字解析
本文介绍了Java线程中的`volatile`关键字及其与`synchronized`锁的区别。`volatile`保证了变量的可见性和一定的有序性,但不能保证原子性。它通过内存屏障实现,避免指令重排序,确保线程间数据一致。相比`synchronized`,`volatile`性能更优,适用于简单状态标记和某些特定场景,如单例模式中的双重检查锁定。文中还解释了Java内存模型的基本概念,包括主内存、工作内存及并发编程中的原子性、可见性和有序性。
Java 并发编程——volatile 关键字解析
|
13天前
|
Java 数据库连接 Spring
反射-----浅解析(Java)
在java中,我们可以通过反射机制,知道任何一个类的成员变量(成员属性)和成员方法,也可以堆任何一个对象,调用这个对象的任何属性和方法,更进一步我们还可以修改部分信息和。
|
1月前
|
Java 编译器
Java 泛型详细解析
本文将带你详细解析 Java 泛型,了解泛型的原理、常见的使用方法以及泛型的局限性,让你对泛型有更深入的了解。
52 2
Java 泛型详细解析
|
2月前
|
缓存 监控 Java
Java线程池提交任务流程底层源码与源码解析
【11月更文挑战第30天】嘿,各位技术爱好者们,今天咱们来聊聊Java线程池提交任务的底层源码与源码解析。作为一个资深的Java开发者,我相信你一定对线程池并不陌生。线程池作为并发编程中的一大利器,其重要性不言而喻。今天,我将以对话的方式,带你一步步深入线程池的奥秘,从概述到功能点,再到背景和业务点,最后到底层原理和示例,让你对线程池有一个全新的认识。
58 12
|
1月前
|
存储 算法 Java
Java内存管理深度解析####
本文深入探讨了Java虚拟机(JVM)中的内存分配与垃圾回收机制,揭示了其高效管理内存的奥秘。文章首先概述了JVM内存模型,随后详细阐述了堆、栈、方法区等关键区域的作用及管理策略。在垃圾回收部分,重点介绍了标记-清除、复制算法、标记-整理等多种回收算法的工作原理及其适用场景,并通过实际案例分析了不同GC策略对应用性能的影响。对于开发者而言,理解这些原理有助于编写出更加高效、稳定的Java应用程序。 ####
|
1月前
|
存储 监控 算法
Java虚拟机(JVM)垃圾回收机制深度解析与优化策略####
本文旨在深入探讨Java虚拟机(JVM)的垃圾回收机制,揭示其工作原理、常见算法及参数调优方法。通过剖析垃圾回收的生命周期、内存区域划分以及GC日志分析,为开发者提供一套实用的JVM垃圾回收优化指南,助力提升Java应用的性能与稳定性。 ####
|
1月前
|
Java 数据库连接 开发者
Java中的异常处理机制:深入解析与最佳实践####
本文旨在为Java开发者提供一份关于异常处理机制的全面指南,从基础概念到高级技巧,涵盖try-catch结构、自定义异常、异常链分析以及最佳实践策略。不同于传统的摘要概述,本文将以一个实际项目案例为线索,逐步揭示如何高效地管理运行时错误,提升代码的健壮性和可维护性。通过对比常见误区与优化方案,读者将获得编写更加健壮Java应用程序的实用知识。 --- ####
|
2月前
|
数据采集 存储 Web App开发
Java爬虫:深入解析商品详情的利器
在数字化时代,信息处理能力成为企业竞争的关键。本文探讨如何利用Java编写高效、准确的商品详情爬虫,涵盖爬虫技术概述、Java爬虫优势、开发步骤、法律法规遵守及数据处理分析等内容,助力电商领域市场趋势把握与决策支持。
|
2月前
|
存储 缓存 监控
Java中的线程池深度解析####
本文深入探讨了Java并发编程中的核心组件——线程池,从其基本概念、工作原理、核心参数解析到应用场景与最佳实践,全方位剖析了线程池在提升应用性能、资源管理和任务调度方面的重要作用。通过实例演示和性能对比,揭示合理配置线程池对于构建高效Java应用的关键意义。 ####

推荐镜像

更多