使用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)注释掉,你会发现会输出以下内容:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | 节点名:#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代码-----------------------------------
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | <? 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代码-----------------------------------
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 | 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 ;<br> 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属性值,修改失败!!!" ); } } } |
转载请注意出处或作者,谢谢!
【推荐】还在用 ECharts 开发大屏?试试这款永久免费的开源 BI 工具!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步