zoukankan      html  css  js  c++  java
  • 使用DOM进行xml文档的crud(增删改查)操作<操作详解>

    很多朋友对DOM有感冒,这里我花了一些时间写了一个小小的教程,这个能看懂,会操作了,我相信基于DOM的其它API(如JDOM,DOM4J等)一般不会有什么问题。

    后附java代码,也可以下载(可点击这里入下载)导入到Eclipse或MyEclipse。

    image

    Node和Element的关系

    1. Element是Node的子接口,所以Element的方法要比Node方法要多,这样的话使用起来比较方便,一般情况我们都把节点转换成元素(或者叫标签,即Element);

      image

    2. 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”常量字段值“查看:

    image

    修改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属性值,修改失败!!!"); } } }

    转载请注意出处或作者,谢谢!

  • 相关阅读:
    [GeeksForGeeks] Maximum Length Chain of Pairs
    [Coding Made Simple] Buy/Sell stock with at most K transactions to maximize profit
    [LeetCode 10] Regular Expression Matching
    056_统计/etc/passwd 中 root 出现的次数
    055_使用脚本循环创建三位数字的文本文件(111-999 的所有文件)
    054_自动修改计划任务配置文件
    053_修改 Linux 系统的最大打开文件数量
    052_获取本机 MAC 地址
    051_循环关闭局域网中所有主机
    050_显示进度条(回旋镖版)
  • 原文地址:https://www.cnblogs.com/javalittleman/p/4134775.html
Copyright © 2011-2022 走看看