根据一个CRUD的案例,对JAXP解析xml技术,进行详细的解释:

首先,已知一个xml文件中的数据如下:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<书架>
<书 出版社="深圳出版社1"><!-- 出版社="深圳出版社1"属性名和属性值 -->
<书名>Java</书名>
<作者>张泽华</作者>
<售价>39.00元</售价>
</书>
<书 出版社="深圳出版社2">
<书名>JavaScript网页开发</书名>
<作者>李红蕾</作者>
<售价>28.00元</售价>
</书>
</书架>

然后根据单元测试的形式,对CRUD分别写在一个测试框架方法里面。以方便测试代码正确性。

package com.itheima.dom;

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.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.TransformerFactoryConfigurationError;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult; import junit.framework.Assert; 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; /*
*
* 使用 xml dom 对xml 文件进行 CRUD操作
*
1.读取节点的文本内容
2.读取属性值
3.添加节点
4.删除节点
5.更新节点
6.打印所有元素节点的名称.
protected的方法,不让new对象 *
*/
public class TestDomExercises { // 读取节点的文本内容 : Java就业培训教程
@Test
public void testReadContent() throws Exception {// 测试框架异常需要抛出 // 获得代表xml 文件的document 对象 Document document = getDocument(); // 根据标签名 获得 名的标签的 节点 列表
NodeList nl= document.getElementsByTagName("书名"); int length = nl.getLength(); System.out.println("长度 : " + length); // 返回第一个 书名 节点
Node firstBookNameNode = nl.item(0); String result = firstBookNameNode.getTextContent();//String getTextContent() 此属性返回此节点及其后代的文本内容。 Assert.assertEquals("Java", result);
} // 2.读取属性值 : 出版社="深圳出版社1"
@Test
public void testReadAttribute() throws Exception { // 获得document 对象
Document document = getDocument(); NodeList nl = document.getElementsByTagName("书"); // 拿到 第一本书的 节点 对象
// Node firstBookNode = nl.item(0); // 注意:这里查看api 之后, 发现Node里面没有【根据 属性名获得属性值】的方法,而 元素 element 有 直接【根据 属性名获得属性值】的方法, 而这里 拿到的 实际上就是
// 一个 元素 Node节点, 所以 这里 想到了强制类型 转换 , 转换为 元素Element , 然后 根据他的方法的属性名获得属性的值 // 拿到 第一本书
//nl.item(0)返回Node对象,向下转型成Element对象。因为Element里面有直接根据元素找值得方法:getAttribute("出版社");根据名称获取属性的值
Element firstBookElement = (Element) nl.item(0); //String getAttribute(String name) 通过名称获得属性值。
String result = firstBookElement.getAttribute("出版社");//根据属性名获取属性值 Assert.assertEquals("深圳出版社1", result); } // 3.添加节点 : <售价>79.00元</售价>
@Test
public void testAddPrice() throws Exception, SAXException, IOException { // 获得document 对象
Document document = getDocument(); // 获得第一本书 节点
Node firstBookNode = document.getElementsByTagName("书").item(0); // 创建 售价 节点, 并且将 文本设置为 79.00元
//Element org.w3c.dom.Document.createElement(String tagName)
//Element createElement(String tagName) 创建指定类型的元素。
Element createPriceElement = document.createElement("售价");
//
createPriceElement.setTextContent("79.00元");//<售价>79.00元</售价> //Node org.w3c.dom.Node.appendChild(Node newChild)
firstBookNode.appendChild(createPriceElement);//将节点 newChild 添加到此节点的子节点列表的末尾。如果 newChild 已经存在于树中,则首先移除它。 writeBack2Xml(document); } /*
* 回去写代码时, 如果碰到这个 异常 :
*
* initializationError(org.junit.runner.manipulation.Filter)
*
* 就是 你 没有 加 @Test 注解
*/ // 4.删除节点: <售价>39.00元</售价>
@Test
public void testDelete() throws Exception, SAXException, IOException { // 获得 document 对象
Document document = getDocument(); // 获得 售价 39.00元的 节点
NodeList priceNodeList = document.getElementsByTagName("售价"); for (int i = 0; i < priceNodeList.getLength(); i++) { // 拿到 每个售价节点
Node node = priceNodeList.item(i); if ("39.00元".equals(node.getTextContent())) { // 如果进来, 则说明找到 39.00元的售价节点
// 拿到当前节点的父节点, 然后 删除 这个 节点
node.getParentNode().removeChild(node); }
} // 更新 到 xml 文件
writeBack2Xml(document); } // 5.更新节点 : <售价>79.00元</售价> ---------->> <售价>9.9元</售价>
public void testUpdatePrice() { } // 6.打印所有元素节点的名称. @Test
public void testPrintAllElementsName() throws Exception, SAXException,
IOException { // 获得document 对象
Document document = getDocument(); printAllElementsName(document);
} public void printAllElementsName(Node node) { if (Node.ELEMENT_NODE == node.getNodeType()) { // 说明 就是 元素 节点
System.out.println(node.getNodeName());
} NodeList childNodes = node.getChildNodes(); for (int i = 0; i < childNodes.getLength(); i++) { // 拿到 遍历过程中的 每一个 node
Node item = childNodes.item(i); printAllElementsName(item);
}
} // 需要将内存中的document 对象 重新写回到 xml 文件中去
private void writeBack2Xml(Document document)
throws TransformerFactoryConfigurationError,
TransformerConfigurationException, TransformerException { // 如何弄?
// 查看 文档, transformerFacotry --->> Transformer实例 TransformerFactory factory = TransformerFactory.newInstance(); // 获得转换器的 实例对象
Transformer transformer = factory.newTransformer(); // 调用 转换方法 将 内存中document 对象 写到 xml 文件中 去
//abstract void transform(Source xmlSource, Result outputTarget) 将 XML Source 转换为 Result。
//DOMSource正好是Source实现类。而且它有构造方法DOMSource(Node n) 正好接收一个Node
//Result实现类有一个StreamResult他的构造方法StreamResult.StreamResult(String systemId)
// systemId:Must be a String that conforms to the URI syntax
//因此源Source,和结果Result都解决了
transformer.transform(new DOMSource(document), new StreamResult(
"src/book.xml"));
} // 抽取 方法 (右键——>>refactor--->>rctract method)--->> 重构 -- 抽取 方法
private Document getDocument() throws ParserConfigurationException,
SAXException, IOException {
// 1. 获得工厂
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); // 2. 获得 builder 对象
DocumentBuilder builder = factory.newDocumentBuilder(); // 3. 拿到 代表xml 文件的document 对象
Document document = builder.parse("src/book.xml");
return document;
} }

XML解析之JAXP案例详解的更多相关文章

  1. spring的IOC,DI及案例详解

    一:spring的基本特征 Spring是一个非常活跃的开源框架:它是一个基于Core来架构多层JavaEE系统的框架,它的主要目的是简化企业开发.Spring以一种非侵入式的方式来管理你的代码,Sp ...

  2. 深入浅出 spring-data-elasticsearch - 基本案例详解(三

    『  风云说:能分享自己职位的知识的领导是个好领导. 』运行环境:JDK 7 或 8,Maven 3.0+技术栈:SpringBoot 1.5+, Spring Data Elasticsearch ...

  3. http500:服务器内部错误案例详解(服务器代码语法错误或者逻辑错误)

    http500:服务器内部错误案例详解(服务器代码语法错误或者逻辑错误) 一.总结 服务器内部错误可能是服务器中代码运行的时候的语法错误或者逻辑错误 二.http500:服务器内部错误案例详解 只是一 ...

  4. 解析Tomcat之HttpServlet详解

    解析Tomcat之HttpServlet详解 Servlet的框架是 由两个Java包组成:javax.servlet和javax.servlet.http. 在javax.servlet包中定义了所 ...

  5. str_replace函数的使用规则和案例详解

    str_replace函数的使用规则和案例详解 str_replace函数的简单调用: <?php $str = '苹果很好吃.'; //请将变量$str中的苹果替换成香蕉 $strg = st ...

  6. 数据结构图文解析之:队列详解与C++模板实现

    0. 数据结构图文解析系列 数据结构系列文章 数据结构图文解析之:数组.单链表.双链表介绍及C++模板实现 数据结构图文解析之:栈的简介及C++模板实现 数据结构图文解析之:队列详解与C++模板实现 ...

  7. ​ 用一个开发案例详解Oracle临时表

    ​ 用一个开发案例详解Oracle临时表 2016-11-14 bisal ITPUB  一.开发需求  最近有一个开发需求,大致需要先使用主表,或主表和几张子表关联查询出ID(主键)及一些主表字段 ...

  8. XML 解析之 jaxp 解析器

    XML 的解析方式有两种方式: DOM 解析和 SAX 解析. DOM 解析: 根据 XML 的层级结构, 在内存中分配一个树形结构, 把 XML 的标签, 属性和文本都封装成对象. 优点: 可以实现 ...

  9. linux ssh使用深度解析(key登录详解)

    linux ssh使用深度解析(key登录详解) SSH全称Secure SHell,顾名思义就是非常安全的shell的意思,SSH协议是IETF(Internet Engineering Task ...

随机推荐

  1. 18. 4Sum(中等)

    Given an array S of n integers, are there elements a, b, c, and d in S such that a + b + c + d = tar ...

  2. python socket网络编程之粘包问题详解

    一,粘包问题详情 1,只有TCP有粘包现象,UDP永远不会粘包 你的程序实际上无权直接操作网卡的,你操作网卡都是通过操作系统给用户程序暴露出来的接口,那每次你的程序要给远程发数据时,其实是先把数据从用 ...

  3. Web缓存(一) - HTTP协议缓存

    为什么要使用 Web 缓存 Web缓存一般分为浏览器缓存.代理服务器缓存以及网关缓存,本文主要讲的是 浏览器缓存,其它两种缓存大家自行去了解下. Web 缓存游走于服务器和客户端之间.这个服务器可能是 ...

  4. Go 语言Map(集合)

    Map 是一种无序的键值对的集合.Map 最重要的一点是通过 key 来快速检索数据,key 类似于索引,指向数据的值. Map 是一种集合,所以我们可以像迭代数组和切片那样迭代它.不过,Map 是无 ...

  5. Docker使用 Supervisor 来管理进程

    Docker 容器在启动的时候开启单个进程,比如,一个 ssh 或者 apache 的 daemon 服务.但我们经常需要在一个机器上开启多个服务,这可以有很多方法,最简单的就是把多个启动命令放到一个 ...

  6. 什么是 Docker

    Docker 是一个开源项目,诞生于 2013 年初,最初是 dotCloud 公司内部的一个业余项目.它基于 Google 公司推出的 Go 语言实现. 项目后来加入了 Linux 基金会,遵从了 ...

  7. cassandra 3.x官方文档(4)---分区器

    写在前面 cassandra3.x官方文档的非官方翻译.翻译内容水平全依赖本人英文水平和对cassandra的理解.所以强烈建议阅读英文版cassandra 3.x 官方文档.此文档一半是翻译,一半是 ...

  8. Mybatis源码分析--关联表查询及延迟加载(一)

    Mybatis提供了关联查询映射的功能. 一.一对一关联

  9. linux下数据同步、回写机制分析

    一.前言在linux2.6.32之前,linux下数据同步是基于pdflush线程机制来实现的,在linux2.6.32以上的版本,内核彻底删掉了pdflush机制,改为了基于per-bdi线程来实现 ...

  10. Hive的HQL语句及数据倾斜解决方案

    [版权申明:本文系作者原创,转载请注明出处] 文章出处:http://blog.csdn.net/sdksdk0/article/details/51675005 作者: 朱培          ID ...