使用DOM进行xml文档的crud(增删改查)操作<操作详解>
很多朋友对DOM有感冒,这里我花了一些时间写了一个小小的教程,这个能看懂,会操作了,我相信基于DOM的其它API(如JDOM,DOM4J等)一般不会有什么问题。
后附java代码,也可以下载(可点击这里入下载)导入到Eclipse或MyEclipse。
Node和Element的关系
- Element是Node的子接口,所以Element的方法要比Node方法要多,这样的话使用起来比较方便,一般情况我们都把节点转换成元素(或者叫标签,即Element);
- Element是Node的子类型:
比如我们运行实例中的readByNode(Node node)方法,如果把类型断码if (node.getNodeType()==node.ELEMENT_NODE)注释掉,你会发现会输出以下内容:
节点名:#document
节点类型:9
节点值:null
节点名:students
节点类型:1
节点值:null
节点名:#text
节点类型:3
节点值: 节点名:student
节点类型:1
节点值:null
节点名:#text
节点类型:3
节点值: ------部分控制台内容已省略------
输出内容包括文本类型(DOM会把空格也当做类型)和document类型及元素类型,如果只查找Element类型,可以使用判断Node类型,这个我们一定要注意!
我们从结果可以看出来 Element实际上是”<>”内的值。
节点类型常量字段值可对照Java API文档的Node”常量字段值“查看:
修改xml后需要使用Transformer更新到xml文件中
因为DOM修改是在内存中修改,要更新到xml文件中,必须使用Transformer写入。除读以外,其它的增、删、改这些更新数据的操作必须Transformer更新到xml文件。
什么时候使用item(0)?
当我们使用通过getElementsByTagName得到的是子元素的集合,如果这个子元素集合中只有一个元素时我们可以使用item(0),当然我们指定item(0),因为item(0)是第一个元素集合中的第一个元素。
如何删除节点?
首先要获得要删除的节点,然后再得到其父节点,再使用父节点的removeChild方法删除要删除节点,所以删除是不能“自杀”。
如何创建节点?
首先使用DOM的createElement方法创建各个元素,然后通过appendChild方法让各个之间建立父子关系,这个关系不一定要从根节点开始,要看你如何增加,是否准确的找到插入位置就可以了。
-----------------------------------以下为xml代码-----------------------------------
<?xml version="1.0" encoding="utf-8" ?>
<students>
<student id="001" sex="男">
<name>周星驰</name>
<age>23</age>
<intro>这是一位成绩很好的学生</intro>
</student>
<student id="002" sex="男">
<name>刘德华</name>
<age>32</age>
<intro>他综合能力很优秀</intro>
</student>
<student id="003" sex="女">
<name>周惠敏</name>
<age>31</age>
<intro>长得漂亮</intro>
</student>
<student id="004" sex="男">
<name>王五</name>
<age>37</age>
<intro>成绩有点差</intro>
</student>
<student id="005" sex="男">
<name>张三丰</name>
<age>26</age>
<intro>经常逃课</intro>
</student>
</students>
-----------------------------------以下为java代码-----------------------------------
package com.xmltest; 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.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult; // 注意不要导错包了
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; /**
* <b>项目:</b>使用DOM进行xml文档的crud(增删改查)操作<br />
* <b>文件名:</b> Xml_Crud.java<br />
* <b>类名:</b> Xml_Crud<br />
* <b>包:</b> com.xmltest<br />
* <b>描述:</b> 一个xml简单的crud操作<br />
* <hr />
* <div align="left"><font color="#FF0000"><strong>xml的crud增删改查操作</strong></font></div>
* <hr />
* <b>时间:</b> 2014-12-1 上午9:45:45<br />
* <b>Copyright:</b> 2014<br />
* @author javalittleman
* @version V1.0
*/
public class Xml_Crud {
public static void main(String[] args) throws ParserConfigurationException, SAXException, IOException, TransformerException {
File file = new File("src/student.xml");
Document doc=doc(file);
// 以下为【增\删\改\查】操作
// 【查】一:通过node遍历
// readByNode(doc);
// 【查】二:通过传入第几个学生获得该学生下的所有信息
// read(doc, 1);
/* 【查】三:
* 通过传入的学生姓名获得该学生的所有信息
* 传入的为name元素的文本值
*/
// read(doc,"刘德华");
// 【删】一:通过序号删除
// delete(doc, 1);
// 【删】二:通过学生姓名删除
// delete(doc, "张三丰");
// 【增】:向xml中增加一个学生
// creat(doc, "赵五", "男", "007", "21", "成绩一般,上课不太专心");
// 【改】一:根据student的id属性修改xml文件
updata(doc, "003", "周小明");
} public static void readByNode(Node node){
// 遍历时会把所有的text节点都输出
// 加上node.getNodeType()==node.ELEMENT_NODE可输出元素节点
if (node.getNodeType()==node.ELEMENT_NODE) {
System.out.println("节点名:" + node.getNodeName());
System.out.println("节点类型:" + node.getNodeType());
System.out.println("节点值:" + node.getNodeValue());
}
NodeList nodeList=node.getChildNodes();
for (int i = 0; i < nodeList.getLength(); i++) {
Node n = nodeList.item(i);
readByNode(n);
}
} /**
* <b>标题:</b> doc 方法 <br />
* <b>描述:</b>生成DOM树的方法 <br />
* <b>返回类型:</b>Document<br />
*
* @param file
* 传入一个文件,在本实例中使用xml文件传
* @return 返回一个DOM树
* @throws ParserConfigurationException
* 抛出解析配置错误异常
* @throws SAXException
* 抛出SAX异常
* @throws IOException
* 招聘IO异常
*/
public static Document doc(File file) throws ParserConfigurationException, SAXException, IOException{
// 创建解析工厂
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
// 创建解析器
DocumentBuilder db = dbf.newDocumentBuilder();
// 创建xml文件,得到一个DOM树
Document doc = db.parse(file);
// 返回DOM树
return doc;
} /**
* <b>标题:</b> tran 方法 <br />
* <b>描述:</b>用于将内存中的DOM写入xml文件中 <br />
* <b>返回类型:</b>void<br />
* @param doc 内存中的DOM树
* @param file 目标文件
* @throws TransformerException 抛出转换异常
*/
public static void tran(Document doc,File file) throws TransformerException{
TransformerFactory tff = TransformerFactory.newInstance();
Transformer tf = tff.newTransformer();
tf.setOutputProperty(OutputKeys.ENCODING, "utf-8");
DOMSource xmlSource = new DOMSource(doc);
StreamResult streamresult = new StreamResult(file);
tf.transform(xmlSource, streamresult);
} /**
* <b>标题:</b> 【查】一:read 方法一 <br />
* <b>描述:</b>通过学生的序号读出学生信息 <br />
* <b>返回类型:</b>void<br />
* @param doc DOM树
* @param itemNum 传入的第itemNum个学生
* @throws 无
*/
public static void read(Document doc,int itemNum){
//获取第itemNum-1个student元素,比如itemNum为我设1,那么就是第0个元素
Element student=(Element) doc.getElementsByTagName("student").item(itemNum-1);
if (student!=null) {
// 获得其id属性值
String id=student.getAttribute("id");
// 获得其sex属性值
String sex=student.getAttribute("sex");
// 分别获得第itemNum-1个元素下的name、age、intro的文本值
// 因为第itemNum-1个student下只有一个name元素,所以使用item(0),age和intro亦然
String name = (String) student.getElementsByTagName("name").item(0).getTextContent();
String age = (String) student.getElementsByTagName("age").item(0).getTextContent();
String intro = (String) student.getElementsByTagName("intro").item(0).getTextContent();
// 分别打印id、sex、name、intro值
System.out.println(id + " " + name + " " + sex + " " + age + "岁 "+intro);
}else {
System.out.println("第“"+itemNum+"位”学生不存在");
}
} /**
* <b>标题:</b> 【查】二: read 方法二 <br />
* <b>描述:</b>通过给出的学生姓名读取xml <br />
* <b>返回类型:</b>void<br />
* @param doc DOM树
* @param studentNmae 传入学生姓名
* @throws 无
*/
public static void read(Document doc, String studentNmae) {
//首先获得student元素
NodeList student = doc.getElementsByTagName("student");
/*
* 遍历所有student节点下,找出其下的name元素
* 是否有与传入studentName相同
* 如果有就获取其id、sex、name、age、intro
* --------思路--------
* 从遍历中获得name的文本为对应给出的studentName值后,取得name文本值
* 再获得其父节点,然后才得到id、sex、age、intro的文本值
*/
boolean isFund = false;
String name=null;
String sex=null;
String id=null;
String age=null;
String intro=null;
for (int i = 0; i < student.getLength(); i++) {
Element ele = (Element) student.item(i);
Element name_ele=(Element) ele.getElementsByTagName("name").item(0);
name=name_ele.getTextContent();
if (studentNmae.equals(name_ele.getTextContent())) {
// 如果找到我们要找的学生姓名就取得其父元素,即student元素
Element me=(Element) name_ele.getParentNode();
sex=me.getAttribute("sex");
id=me.getAttribute("id");
// 因为每个student下只有一个age和intro元素,所以采用item(0)
age= me.getElementsByTagName("age").item(0).getTextContent();
intro=me.getElementsByTagName("intro").item(0).getTextContent();
isFund=true;
break;
}
}
if (isFund) {
System.out.println(id + " " + name + " " + sex + " " + age + "岁 " + intro);
} else {
System.out.println("没有找到“" + studentNmae + "”这个学生");
}
} /**
* <b>标题:</b>【删】一: delete 方法一 <br />
* <b>描述:</b>根据传入的第几个元素进行删除 <br />
* <b>返回类型:</b>void<br />
* @param doc 传入的DOM树
* @param studentNum 传入的第几个学生,也就是第几个元素
* @throws TransformerException 抛出转换异常
*/
public static void delete(Document doc,int studentNum) throws TransformerException{
Element ele = (Element) doc.getElementsByTagName("student").item(studentNum-1);
if (ele != null) {
ele.getParentNode().removeChild(ele);
System.out.println("删除成功");
} else {
System.out.println("该第" + studentNum + "位不存在,不能删除");
}
tran(doc, new File("src/student.xml"));
} /**
* <b>标题:</b>【删】二: delete 方法二 <br />
* <b>描述:</b>给出某个学生姓名进行删,即根据文本值删除 <br />
* <b>返回类型:</b>void<br />
* @param doc
* @param studentName
* @throws TransformerException
* @throws 无
*/
public static void delete(Document doc,String studentName) throws TransformerException{
NodeList nodelist = doc.getElementsByTagName("name");
boolean isFund=false;
Element ele=null;
for (int i = 0; i < nodelist.getLength(); i++) {
ele = (Element) nodelist.item(i);
if (studentName.equals(ele.getTextContent())) {
isFund=true;
break;
}
}
if (isFund) {
ele.getParentNode().getParentNode().removeChild(ele.getParentNode());
tran(doc, new File("src/student.xml"));
System.out.println("已经删除“"+studentName+"”这位同学的信息");
} else {
System.out.println("找不到“" + studentName + "”这位学生,不能删除");
}
} /**
* <b>标题:</b>【增】 updata 方法 <br />
* <b>描述:</b>向xml文件中增加信息 <br />
* <b>返回类型:</b>void<br />
* @param doc 传入的DOM树
* @param name 姓名标签
* @param sex student标签的性别属性
* @param id student标签的id属性
* @param age 年龄标签
* @param intro 介绍标签
* @throws TransformerException
*/
public static void creat(Document doc,String name,String sex,String id,String age,String intro) throws TransformerException{
// 找到根节点,根节点只有一个所以使用item(0)
Element root=(Element) doc.getElementsByTagName("students").item(0);
// 创建各个节点
Element ele_student=doc.createElement("student");
ele_student.setAttribute("id", id);
ele_student.setAttribute("sex", sex);
Element ele_name=doc.createElement("name");
ele_name.setTextContent(name);
Element ele_age=doc.createElement("age");
ele_age.setTextContent(age);
Element ele_intro=doc.createElement("intro");
ele_intro.setTextContent(intro);
// 使用appenChild方法增加父子关系
root.appendChild(ele_student);
ele_student.appendChild(ele_name);
ele_student.appendChild(ele_age);
ele_student.appendChild(ele_intro);
// 写入xml文件
tran(doc, new File("src/student.xml"));
System.out.println("“"+name+"”同学的信息已经增加成功!");
} /**
* <b>标题:</b>【改】: updata 方法<br />
* <b>描述:</b>根据标签的属性值修改xml文件 <br />
* 根据标签的文本值去修改其文本值这里就省略了<br />
* <b>返回类型:</b>void<br />
* @param doc 传入DOM树
* @param id 传入student的id属性值
* @param newName 传入新学生姓名
* @throws TransformerException 抛出转换异常
*/
public static void updata(Document doc,String id,String newName) throws TransformerException{
boolean isFund=false;
// 获得student节点集合
NodeList stu=doc.getElementsByTagName("student");
// 遍历student集合,并从中获得其id属性为传入的id值的元素,然后修改其元素下的name的文本值
for (int i = 0; i < stu.getLength(); i++) {
Element ele_stu=(Element) stu.item(i);
if (id.equals(ele_stu.getAttribute("id"))) {
ele_stu.getElementsByTagName("name").item(0).setTextContent(newName);
isFund=true;
break;
}
}
if (isFund) {
// 写入xml文件
tran(doc, new File("src/student.xml"));
System.out.println("修改成功");
} else {
System.out.println("不存在这个“" + id + "”ID属性值,修改失败!!!");
}
}
}
转载请注意出处或作者,谢谢!
使用DOM进行xml文档的crud(增删改查)操作<操作详解>的更多相关文章
- mongodb内嵌文档的javaapi,增删改查
数据结构: {"_id" : "000000001", //Mongodb默认主键 "UID" : "000000001&quo ...
- 多测师讲解接口 _需求文档(用户增删改查)_高级讲师肖sir
首先连接Duoceshi_new网络 密码为Duoceshi_new,因为接口项目部署在Duoceshi_new网段中. 测试工具:postman域名:http://192.168.1.2:8081/ ...
- DOM生成XML文档与解析XML文档(JUNIT测试)
package cn.liuning.test; import java.io.File; import java.io.IOException; import javax.xml.parsers.D ...
- PHP中利用DOM创建xml文档
DOM创建xml文档 用dom创建如下文档: <booklist> <book id="1"> <title>天龙八部</title> ...
- 使用DOM解析XML文档
简单介绍一下使用DOM解析XML文档,解析XML文件案例: <?xml version="1.0" encoding="UTF-8"?> -< ...
- 精讲 org.w3c.dom(java dom)解析XML文档
org.w3c.dom(java dom)解析XML文档 位于org.w3c.dom操作XML会比较简单,就是将XML看做是一颗树,DOM就是对这颗树的一个数据结构的描述,但对大型XML文件效果可能会 ...
- 使用ASP.NET Core MVC 和 Entity Framework Core 开发一个CRUD(增删改查)的应用程序
使用ASP.NET Core MVC 和 Entity Framework Core 开发一个CRUD(增删改查)的应用程序 不定时更新翻译系列,此系列更新毫无时间规律,文笔菜翻译菜求各位看官老爷们轻 ...
- 前端的CRUD增删改查的小例子
前端的CRUD增删改查的小例子 1.效果演示 2.相关代码: <!DOCTYPE html> <html lang="en"> <head> & ...
- 【JAVA与DOM4J实现对XML文档的CRUD操作】
一.简介 1.网上下载DOM4J 1.6.1压缩包,解压开之后,发现几个目录和一个jar文件,jar文件是必须的文件其它目录: docs目录:帮助文档的目录,单击index.html: Quick s ...
随机推荐
- HTML&CSS基础学习笔记1.28-给网页添加一个css样式
CSS是什么? 当HTML配合CSS一起使用时,我们发现页面变得好看了很多.那么CSS到底是什么呢? CSS指层叠样式表 (Cascading Style Sheets),它主要是用于定义HTML标签 ...
- laravel框架——上传、下载文件
文件上传 在config文件夹下新建一个 项目名.php return [ 'title' => 'My Test', 'posts_per_page' => 5, 'uploads' = ...
- mongodb 教程三
mongodb 实际上是保存json的数据的结构.当查询 是修改时 key 是可以用''保存. mongodb 插入语句 db.weixin.insert({name:'zhangfeng',age ...
- 《30天自制操作系统》读书笔记(2)hello, world
让系统跑起来 要写一个操作系统,我们首先要有一个储存系统的介质,原版书似乎是06年出版的,可惜那时候没有电脑,没想到作者用的还是软盘,现在的电脑谁有软驱?不得已我使用一张128M的SD卡来代替,而事实 ...
- ExtJS5_自定义菜单1
顶部和底部区域已经作好,在顶部区域有一个菜单的按钮,这一节我们设计一个菜单的数据结构,使其可以展示出不同样式的菜单.由于准备搭建的是一个系统模块自定义的系统,因此菜单也是自定义的,在操作员系统登录的时 ...
- 信号量 sem_t 进程同步
sem_t分为有名和无名.有名的sem_t通过sem_open来创建, 而无名的sem_t通过sem_init的初始化. 用有名的sem_t来进程间同步是件很容易的事情,百度上一搜很多想相关的例子. ...
- javascript book
我们很欣喜地看到,在设计模式领域,<JavaScript设计模式>(JavaScript Design Patterns)和<JavaScript编程模式>(JavaScrip ...
- 【转】Java生成对应字符串的MD5密码模块
原文网址:http://www.cnblogs.com/xudong-bupt/archive/2013/05/10/3070899.html (1)一般使用的数据库中都会保存用户名和密码,其中密码不 ...
- Ubuntu14.04 安装QQ国际版wine-qqintl
Ubuntu14.04安装qq国际版方式: 首先下载,链接为: https://pan.baidu.com/s/1boPitVD 密码:jp1j 也可去Ubuntu中文的Kylin(优麒麟)官网下载 ...
- http 400 错误的请求怎么解决
HTTP400是个错误的统称 你将IE选项-高级中的显示HTTP友好错误信息前面的勾去掉. 然后在开这个页,,把错误代码复制出来 .其实有时是网页本身已经不可用了,你先关掉浏览器稍等一会再登陆网页也是 ...