jaxp实现对xml文档的增,删,改,查操作(附源码)浅析

时间:2021-07-30 02:44:00

jaxp,属于javase中的一部分。是对xml进行解析的一个工具类;

既然说到这里,还是讲全一点,讲讲上面说到的xml的解析技术。

xml的一个标记型文档。

在html的层级结构中,它会在内存中分配一个树形结构,会把html中的标签,属性,文本等都封装成一个个对象:

列如:document对象,element对象,属性对象,文本对象,Node节点对象。为啥讲html了呢?因为在html中js使用dom解析标记型文档。当然html这次就不说了,咱们重点说一说xml中的解析方式及具体的解析过程

在xml中的解析技术中,主要有两种技术:dom和sax

那么这两种解析技术,有什么区别呢?

1.dom:

(1)解析原理:更加xml的层级结构,在内存中分配一个树形结构,把xml的标签,属性,文本都封装成一个个对象。

(2)优缺点:首先,因为对于它的解析方式,它会一次性把所有的层级结构全部解析,那么构造出来的树形结构都会全部加载在内存中,所以它如果面对大型的xml文档进行解析,就会出现OOM(内存溢出)现象。优点呢?也正是它的树形结构方式,所以开发中对于它的增删改查操作就比较容易了,它的优点也就是在此。

2.sax:

(1)解析原理:采用事件驱动方式,在读取的时候,一边解析。自上而下的,逐步解析,解析到某一个xml的标签或者属性或者文本等对象,然后就把对象名称返回。

(2)优缺点:优点呢,就是和dom相反,不会造成内存溢出。因为他的解析方式,自上而下。缺点呢,不能实现增删改操作。

这次先说dom解析过程:

DocumentBuilder:解析器类,

  • 定义从XML文档获取DOM文档实例的API。 使用这个类,应用程序员可以从XML获得一个Document

jaxp实现对xml文档的增,删,改,查操作(附源码)浅析

这个类是一个抽象类,所以不能构造对象,所以我们只有从它的具体实现类中寻找突破口

DocumentBuilderFactory中的newDocumentBuilder()方法获取

返回的是document是一个接口,父节点是Node。

那么在document中有些方法在我们等等要执行的增删改查操作,所以我们先声明一下。

1.得到标签,得到一个集合NodeList:getElementByTagName(String tagName)

2.创建一个标签:createElement(String tagName)

3.创建文本:createTextNode(String data)

4.在标签中添加文本:appendChild(Node newChild)

5.通过父节点删除节点:removeChild(Node oldChild)

6.获取父节点:getParentNode()

7.获取集合的长度:getLength()

8.获取下标具体的值:item(int index)

9.获取标签里面的内容:getTextContent()

===================================================

那么了解了初步的准备,我们准备一个具体的demo来,这样会更加形象的了解运用

首先定义一个xml文件:dog.xml

<?xml version="1.0" encoding="UTF-8" standalone="no"?>

<dog>

<dog1>

<name>Tom</name>

<color>write</color>

</dog1>

<dog1>

<name>Jack</name>

<color>blue</color>

</dog1>

</dog>

创建一个类:TestJaxp

首先实现增:我们在dog1标签下面添加<age>12</age>

/** 

* 1.创建解析器工厂
* 2.根据解析器工厂创建解析器
* 3.解析xml返回document
* 4.得到第一个dog1元素
* 5.创建age标签createElement
* 6.创建文本createTextNode
* 7.把文本添加到age下面appendChild()

* 8.把age添加到第一个dog1下面


* 9.回写xml

*/

public static void createTag() throws

ParserConfigurationException, SAXException,

IOException, TransformerException{

//创建解析器工厂
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
//创建解析器
DocumentBuilder db = dbf.newDocumentBuilder();
//解析xml返回document
Document document = db.parse("src/dog.xml");
//得到第一个dog1元素
Node dog1= document.getElementsByTagName("dog1").item(0);
//创建age标签
Node age1= document.createElement("age");
//创建文本
Text test1 = document.createTextNode("12");
//age1标签添加text1
age1.appendChild(test1);
//dog1添加age1
dog1.appendChild(sex1);

//回写xml
TransformerFactory tf = TransformerFactory.newInstance();
Transformer t = tf.newTransformer();
t.transform(new DOMSource(document), new StreamResult("src/dog.xml"));

}

实现删:我们把刚刚创建的age标签删除

思路:/*
 * 1、创建解析器工厂
 * 2、根据解析器工厂创建解析器
 * 3、解析xml,返回document 
 * 
 * 4、获取age元素
 * 5、获取age的父节点 
 * 6、删除使用父节点删除 removeChild方法
 * 
 * 7、回写xml
 * */

public static void delectTag() throws Exception {
//创建解析器工厂
DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
//创建解析器
DocumentBuilder builder = builderFactory.newDocumentBuilder();
//得到document
Document document = builder.parse("src/dog.xml");
//得到age元素
Node age1= document.getElementsByTagName("age").item(0);
//得到age1父节点
Node dog1= age1.getParentNode();
//删除操作
dog1.removeChild(age1);
//回写xml
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
transformer.transform(new DOMSource(document), new StreamResult("src/dog.xml"));

}

实现改操作://修改第一个dog1下面的<name>Tom</name>为<name>LiLi</name>

思路:/*
* 1.创建解析器工厂
* 2.根据解析器工厂创建解析器
* 3.解析xml返回document

* 4.得到第一个name元素 item方法

* 5.修改name中的文本   setTextContent方法

* 6.回写xml
*

*/

public static void updateTextNode() throws TransformerException,

ParserConfigurationException, SAXException, IOException{

DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
Document document = db.parse("src/dog.xml");
Node name1 = document.getElementsByTagName("name").item(0);
//System.out.println(name1);
name1.setTextContent("LiLi");

TransformerFactory tf = TransformerFactory.newInstance();
Transformer t = tf.newTransformer();
t.transform(new DOMSource(document), new StreamResult("src/dog.xml"));

}

实现查操作,查操作中,可以具体到查询某一个元素的值,也可遍历所以同一个元素名称的值

也可以将所有元素名称打印出来:

(1)那么我先查询某一个元素的值,查询第一个name下的值,输出到控制台

思路: /**
* 1.创建解析器工厂
* 2.根据解析器工厂创建解析器
* 3.解析xml返回document
* 4.得到第一个name元素
* 5.得到第一个name元素的值

*/

public static void selectSin() throws SAXException, IOException, ParserConfigurationException {
//创建工厂
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
//创建解析器
DocumentBuilder db = dbf.newDocumentBuilder();
//解析xml返回docuemnt
Document document = db.parse("src/dog.xml");
//得到第一个name元素
Node name1 = document.getElementsByTagName("name").item(0);//得到第一个name元素
//得到第一个name元素里面的值
String str1 = name1.getTextContent();
System.out.println(str1);

}

实现对所有name标签中的值查询只需要增加一个循环结构,就可以将所有的遍历出来

思路: /*
* 1.创建解析器工厂
* 2.根据解析器工厂创建解析器
* 3.解析xml返回document

* 4.得到所有的name元素
* 5.返回集合,遍历集合,得到每一个name元素
*

*/

private static void selectAll() throws ParserConfigurationException, SAXException, IOException {
/*
* 1.创建解析器工厂
* 2.根据解析器工厂创建解析器
* 3.解析xml返回document

* 4.得到所有的name元素
* 5.返回集合,遍历集合,得到每一个name元素

*/

//创建解析器工厂
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
//创建解析器
DocumentBuilder db = dbf.newDocumentBuilder();
//解析xml返回document
Document document = db.parse("src/dog.xml");
//得到name元素
NodeList list = document.getElementsByTagName("name");

//遍历集合
for (int i = 0; i < list.getLength(); i++) {
Node name1 = list.item(i);//得到每一个name元素
//得到name元素里面的值
String str = name1.getTextContent();
System.out.println(str);
}

}

最后一个,遍历节点,把所有的元素名称都获取到,也可属于查的一部分吧:

思路:

/*

* 1、创建解析器工厂
* 2、根据解析器工厂创建解析器
* 3、解析xml,返回document 


* ===递归实现
* 4.得到根节点(打印node.getNodeName())
* 5.得到根节点子节点
* 6.得到根节点子节点的子节点

*/

所以在这个方法里面需要先写一个递归输出的方法

//递归遍历的方法
private static void list1(Node node) {
//判断是元素的时候才打印
if (node.getNodeType() == node.ELEMENT_NODE) {
System.out.println(node.getNodeName());
}
NodeList list = node.getChildNodes();
//遍历list
for (int i = 0; i < list.getLength(); i++) {
//得到每一个节点
Node node1 = list.item(i);
list1(node1);
}

}

public static void listElement() throws SAXException, IOException, ParserConfigurationException{
//创建解析器工厂
DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
//创建解析器
DocumentBuilder builder = builderFactory.newDocumentBuilder();
//得到document
Document document = builder.parse("src/dog.xml");

list1(document);

}

所以在xml中的DOM解析操作中,增删改查就这样了。

jaxp实现对xml文档的增,删,改,查操作(附源码)浅析的更多相关文章

  1. 【JAVA与DOM4J实现对XML文档的CRUD操作】

    一.简介 1.网上下载DOM4J 1.6.1压缩包,解压开之后,发现几个目录和一个jar文件,jar文件是必须的文件其它目录: docs目录:帮助文档的目录,单击index.html: Quick s ...

  2. XMLHelper类 源码&lpar;XML文档帮助类&comma;静态方法&comma;实现对XML文档的创建&comma;及节点和属性的增、删、改、查&rpar;

    以下是代码: using System; using System.Collections.Generic; using System.Linq; using System.Web; using Sy ...

  3. 怎样从C&num;中打开数据库并进行 增 删 改 查 操作

    首先 在C#中引用数据库的操作! (因为我们用的是SQLserver数据库,所以是SqlClient) using System.Data.SqlClient; 1:要实现对数据库的操作,我们必须先登 ...

  4. 好用的SQL TVP~~独家赠送&lbrack;增-删-改-查&rsqb;的例子

    以前总是追求新东西,发现基础才是最重要的,今年主要的目标是精通SQL查询和SQL性能优化.  本系列主要是针对T-SQL的总结. [T-SQL基础]01.单表查询-几道sql查询题 [T-SQL基础] ...

  5. iOS FMDB的使用&lpar;增&comma;删&comma;改&comma;查&comma;sqlite存取图片&rpar;

    iOS FMDB的使用(增,删,改,查,sqlite存取图片) 在上一篇博客我对sqlite的基本使用进行了详细介绍... 但是在实际开发中原生使用的频率是很少的... 这篇博客我将会较全面的介绍FM ...

  6. iOS sqlite3 的基本使用&lpar;增 删 改 查&rpar;

    iOS sqlite3 的基本使用(增 删 改 查) 这篇博客不会讲述太多sql语言,目的重在实现sqlite3的一些基本操作. 例:增 删 改 查 如果想了解更多的sql语言可以利用强大的互联网. ...

  7. django ajax增 删 改 查

    具于django ajax实现增 删 改 查功能 代码示例: 代码: urls.py from django.conf.urls import url from django.contrib impo ...

  8. 使用dom4j技术对xml文档进行增删改练习(一)

    整个流程如下面代码所以,并对一些重要代码意义做出详细解释: import java.io.File; import java.io.FileOutputStream; import org.dom4j ...

  9. ADO&period;NET 增 删 改 查

    ADO.NET:(数据访问技术)就是将C#和MSSQL连接起来的一个纽带 可以通过ADO.NET将内存中的临时数据写入到数据库中 也可以将数据库中的数据提取到内存*程序调用 ADO.NET所有数据访 ...

随机推荐

  1. sqlalchemy入门记录

    前言 发现翻译全文时间比较久,所以先整个简单的使用说明吧 安装SQLAlchemy pip install sqlalchemy 查看SQLAlchemy版本 In [1]: import sqlal ...

  2. VS2010遇到fatal error C1083&colon; 无法打开预编译头文件&colon;&OpenCurlyDoubleQuote;xxx&period;pch”&colon; No such file or directory

    对C++和VS2010非常不熟悉,但是无奈赶着项目,只能看了点基础就上手,然后就碰到这个问题了. 原因分析: http://bbs.csdn.net/topics/340191697?page=1 编 ...

  3. android 简单打jar包

    先建议一个moduel,先写一个下载图片代码: public class LoadTest extends AsyncTask<Void,Void,byte[]>{ public stat ...

  4. CSS 在IE6&comma; IE7 和IE8中的差别&sol;&sol;&sol;&sol;&sol;&sol;&sol;&sol;&sol;&sol;&sol;&sol;&sol;&sol;&sol;&sol;z

    CSS 在IE6, IE7 和IE8中的差别 关于浏览器的最离奇的统计结果之一就是Internet Explorer 版本6,7和8共存.截至本文,Internet Explorer各个版本总共占据了 ...

  5. 【转】apache与tomcat的区别

    Apache 和 Tomcat 都是web网络服务器,两者既有联系又有区别,在进行HTML.PHP.JSP.Perl等开发过程中,需要准确掌握其各自特点,选择最佳的服务器配置. Apache是web服 ...

  6. WinForm实现跨进程通信的方法

    public class WinMessageHelper { private struct COPYDATASTRUCT { public IntPtr dwData; public int cbD ...

  7. Codeforces Beta Round &num;9 &lpar;Div&period; 2 Only&rpar;D

    短小精悍的代码 dp[i][j] +=dp[k][j-1]*[i-k-1][j-1] i个结点 J层 #include <iostream> #include<cstdio> ...

  8. RAC 的一些概念性和原理性的知识(转)

    一 集群环境下的一些特殊问题 1.1 并发控制 在集群环境中, 关键数据通常是共享存放的,比如放在共享磁盘上. 而各个节点的对数据有相同的访问权限, 这时就必须有某种机制能够控制节点对数据的访问. O ...

  9. java&lowbar;web学习&lpar;九&rpar; PreparedStatement动态参数的引入

    一.PreparedStatement 概述 在数据库的操作过程中,PreparedStatement 对象是一个很不起眼但是记为重要的接口对象,它继承 于Statement,并与之在两方面有所不同: ...

  10. SpringBoot的Web开发

    一.创建Web项目 创建的时候勾选对应web选项即可,会自动引入相应的starter,pom如下: <dependency> <groupId>org.springframew ...