XML的解析
* 通过解析技术完成XML增删改查。
* 常用的XML的解析的技术有哪些(DOM解析和SAX解析的区别)?
* 常用的XML的解析的技术有两种,一种就是DOM和SAX解析。
* DOM和SAX的区别:
* DOM方式加载XML文档到内存中,形成树状结构。
* 缺点:如果文档过大,容易产生内存溢出的问题。
* 优点:可以做增删改的操作。
* SAX基于事件驱动的解析,边读边解析。
* 优点:不会产生内存溢出的问题。
* 缺点:不能做增删改的操作,查询速度比较快。
* 这些公司都支持DOM和SAX的解析,提供了开发包。
* SUN公司 提供了JAXP的解析(都支持DOM和SAX)
* DOM4J公司 提供了DOM4J包,解析XML(支持DOM和SAX)(必须会的)
* JDOM公司 提供了JDOM包,解析XML(支持DOM和SAX)(了解)
JAXP解析XML
* 快速入门的步骤
* 1. 先获取解析器工厂类
* 2. 通过工厂类获取解析器对象
* 3. 来进行解析XML的文档了,返回Document对象
* 4. 通过Document对象的api来完成某些操作
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <书架> <书 出版社="清华出版社"> <书名>Java基础</书名> <作者>哈哈</作者> <售价>998</售价> <简介>这书不错啊</简介> </书> <书> <书名>JavaWeb开发大全</书名> <作者>呵呵</作者> <售价>99.8元</售价> <简介>这书真不错啊</简介> </书> </书架>
xml文件
查询指定节点的文本内容
public static void run1() throws Exception{ /** * 0.先获取解析器的工厂类 * 1.获取DOM方式解析器对象(DocumentBuilder) * 1.1 通过解析器的工厂类来获取解析器对象 * 2.解析XML的文档(parse()),返回的Document对象 * 3.获取作者的节点,返回NodeList * 4.循环遍历,拿到每一个Node对象 * 5.获取文本内容 */ // 获取解析器工厂 DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); // 获取解析的对象 DocumentBuilder builder = factory.newDocumentBuilder(); // 解析book2.xml的文档 Document document = builder.parse("src/book2.xml"); // 获取作者的节点 NodeList nodeList = document.getElementsByTagName("作者"); // 循环遍历 for(int i=0;i<nodeList.getLength();i++){ // 循环一次,获取作者的标签 Node node = nodeList.item(i); // 打印节点的文本内容 System.out.println(node.getTextContent()); } }
案例
添加子节点
/** * 1.工厂 * 2.解析器 * 3.解析 获取document对象 * 4.创建元素对象(团购价) * 5.设置的文本内容 * 6.把元素对象添加到书的节点的下面 * 6.1获取第一步书 */ // 工厂 DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); // 解析器对象 DocumentBuilder builder = factory.newDocumentBuilder(); // 解析 Document document = builder.parse("src/book2.xml"); // 创建团购价的元素对象 Element tgj = document.createElement("团购价"); // 设置文本的内容 tgj.setTextContent("9两"); // 获取第一本书 Node book1 = document.getElementsByTagName("书").item(0); // 把团购价添加到第一本书下 book1.appendChild(tgj); // 回写 // 先获取回写了的工厂类 TransformerFactory transformerFactory = TransformerFactory.newInstance(); // 可以获取回写的类 Transformer transformer = transformerFactory.newTransformer(); // 调用tranform(document,XML文件)来进行回写 transformer.transform(new DOMSource(document), new StreamResult("src/book2.xml")); 删除节点 // 工厂 DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); // 解析器对象 DocumentBuilder builder = factory.newDocumentBuilder(); // 解析 Document document = builder.parse("src/book2.xml"); // 先获取团购价的节点 Node tgj = document.getElementsByTagName("团购价").item(0); // 获取团购价的父节点 Node book1 = tgj.getParentNode(); // 使用书的删除团购价的节点 book1.removeChild(tgj); // 回写 // 获取回写的工厂类 TransformerFactory transformerFactory = TransformerFactory.newInstance(); // 获取回写的类 Transformer transformer = transformerFactory.newTransformer(); // 回写 transformer.transform(new DOMSource(document), new StreamResult("src/book2.xml"));
添加
更新节点的文本
// 工厂 DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); // 解析器对象 DocumentBuilder builder = factory.newDocumentBuilder(); // 解析 Document document = builder.parse("src/book2.xml"); // 获取第二个作者 Node author2 = document.getElementsByTagName("作者").item(1); // 设置文本内容 author2.setTextContent("班主任"); // 回写 // 获取回写的工厂类 TransformerFactory transformerFactory = TransformerFactory.newInstance(); // 获取回写的类 Transformer transformer = transformerFactory.newTransformer(); // 回写 transformer.transform(new DOMSource(document), new StreamResult("src/book2.xml"));
修改
回写
* 获取TransformerFactory类获取Transformer类。
* Transformer类中有一个方法:transform(数据源(document),目的地(XML的文档))来完成回写的操作。(在上面代码中有具体操作)
XML的解析 JAXP的SAX解析
* JAXP的SAX解析:边读边解析,事件驱动。只能做查询,不能做增删改的操作。
* SAX解析两个概念
* 解析器
* 事件处理器
/** * 自己定义的事件处理器 * @author Administrator * */ class MyHandler extends DefaultHandler{ /** * 如果解析是开始标签,默认调用该方法 */ public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { // 获取到解析的内容 System.out.println("开始标签:"+qName); } /** * 如果解析的标签的文本内容,默认调用该方法 */ public void characters(char[] ch, int start, int length) throws SAXException { String str = new String(ch,start,length); System.out.println(str); } /** * 如果解析的结束标签,默认调用该方法 */ public void endElement(String uri, String localName, String qName) throws SAXException { System.out.println("结束标签:"+qName); } }
事件处理器
想获取指定元素的文本内容
class MyHandler2 extends DefaultHandler{ private boolean flag = false; private int count = 0; public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { // 说明刚好解析到作者的标签 if("作者".equals(qName)){ flag = true; count++; } } public void characters(char[] ch, int start, int length) throws SAXException { if(flag && count == 1){ // 解析作者标签的时候打印文本的内容 System.out.println(new String(ch,start,length)); } } public void endElement(String uri, String localName, String qName) throws SAXException { flag = false; } }
案例
XML的解析 DOM4J的解析(重点)
* 不是SUN提供的,第三方提供的jar包。
* dom4j-1.6.1.jar必须要有的。必须导入工程中。
* 如果是WEB项目 -- 复制jar包 -- WebRoot -- WEB-INF -- lib
* 创建一个文件夹
查询节点的文本内容
* 第一步:先导入jar包(dom4j-1.6.1.jar)。
* 第二步:编写代码
* 2.1 创建解析器的对象
* 2.2 解析XML的文档,返回Document对象(导包不要导错了)
* 2.3 先获取根节点 getRootElement();
* 2.4 看需求
DOM4J支持XPATH语言
* 通过XPATH语言非常方便查询XML的节点
* 如果直接DOM4J完成解析的工作,必须要先获取根节点。如果使用XPATH,通过查询方式来准确获取内容。
* 导入jaxen-1.1-beta-6.jar
* selectNodes(XPATH语法) 返回的内容是集合,泛型Node对象
* selectSingleNode(XPATH语法) 返回的内容一个Node对象
语法
* /AAA/BBB 从根节点开始的,一层一层去解析 selectNodes("/书架/书") == getRootElment()
* //AAA 无论层级关系 selectNodes("//作者")
* /AAA/BBB/* 任意的元素
* [1]或者[last()] 或者相同的子节点的第一个或者最后一个 selectSingleNode("/书架/书[last()]")
错误的:selectSingleNode("//作者[1]")
*
package cn.itcast.dom4j; import java.io.FileOutputStream; import java.util.List; import org.dom4j.Document; import org.dom4j.DocumentHelper; import org.dom4j.Element; import org.dom4j.Node; import org.dom4j.io.OutputFormat; import org.dom4j.io.SAXReader; import org.dom4j.io.XMLWriter; /** * DOM4J的练习 * @author Administrator * */ public class Dom4jTest { public static void main(String[] args) { try { run6(); } catch (Exception e) { e.printStackTrace(); } } /** * 对象XPATH进行测试 * @throws Exception */ public static void run6() throws Exception{ // 创建解析器对象 SAXReader reader = new SAXReader(); // 解析XML的文件 Document document = reader.read("src/book2.xml"); // 下一步获取根节点(省略) // List<Node> nodeList = document.selectNodes("/书架/书/作者"); /*List<Node> nodeList = document.selectNodes("//作者"); for (Node node : nodeList) { System.out.println(node.getText()); }*/ // 获取一个作者 Node author2 = document.selectSingleNode("/书架/书[last()]/作者"); System.out.println(author2.getText()); } /** * 修改指定节点的名称 * 修改第二个作者的文本内容 * @throws Exception */ public static void run5() throws Exception{ // 创建解析器对象 SAXReader reader = new SAXReader(); // 解析XML的文件 Document document = reader.read("src/book2.xml"); // 先获取根节点 Element root = document.getRootElement(); // 获取第二本 Element book2 = (Element) root.elements("书").get(1); // 获取作者的节点 book2.element("作者").setText("班长"); // 回写 OutputFormat format = OutputFormat.createPrettyPrint(); XMLWriter writer = new XMLWriter(new FileOutputStream("src/book2.xml"),format); // 写 writer.write(document); // 关闭流 writer.close(); } /** * 删除团购价的节点 * @throws Exception */ public static void run4() throws Exception{ // 创建解析器对象 SAXReader reader = new SAXReader(); // 解析XML的文件 Document document = reader.read("src/book2.xml"); // 先获取根节点 Element root = document.getRootElement(); // 获取第一本书 Element book1 = root.element("书"); // 获取团购价的节点 Element tgj = book1.element("团购价"); // 删除 book1.remove(tgj); // 回写 // 回写 OutputFormat format = OutputFormat.createPrettyPrint(); XMLWriter writer = new XMLWriter(new FileOutputStream("src/book2.xml"),format); // 写 writer.write(document); // 关闭流 writer.close(); } /** * 在指定的位置添加子节点 * 在第一本书的作者节点之前添加子节点 * @throws Exception */ public static void run3() throws Exception{ // 创建解析器对象 SAXReader reader = new SAXReader(); // 解析XML的文件 Document document = reader.read("src/book2.xml"); // 先获取根节点 Element root = document.getRootElement(); // 获取第一本书 Element book1 = root.element("书"); // 获取第一本书下的所有子节点 List<Element> bookChilds = book1.elements(); // 创建元素对象 Element tgj = DocumentHelper.createElement("团购价"); // 设置文本内容 tgj.setText("9两"); // 添加一个节点 bookChilds.add(1, tgj); // 回写 OutputFormat format = OutputFormat.createPrettyPrint(); XMLWriter writer = new XMLWriter(new FileOutputStream("src/book2.xml"),format); // 写 writer.write(document); // 关闭流 writer.close(); } /** * 查询作者标签的文本内容 * @throws Exception */ public static void run1() throws Exception{ // 创建解析器对象 SAXReader reader = new SAXReader(); // 解析XML的文件 Document document = reader.read("src/book2.xml"); // 先获取根节点 Element root = document.getRootElement(); // 获取书的节点 List<Element> books = root.elements("书"); // 循环遍历 for (Element book : books) { // 循环第一次,获取第一本书 Element author = book.element("作者"); // 获取节点的文本内容 System.out.println(author.getText()); } } /** * 添加子节点 * 在第一本书的节点下去添加团购价的节点 */ public static void run2() throws Exception{ // 解析器对象 SAXReader reader = new SAXReader(); // 解析 Document document = reader.read("src/book2.xml"); // 获取根节点 Element root = document.getRootElement(); // 获取第一本书 Element book1 = root.element("书"); // 直接在第一本书下去添加子节点(设置文本的内容) Element tgj = book1.addElement("团购价"); tgj.setText("9两"); // 回写 // 创建输出的格式 OutputFormat format = OutputFormat.createPrettyPrint(); //OutputFormat format = OutputFormat.createCompactFormat(); XMLWriter writer = new XMLWriter(new FileOutputStream("src/book2.xml"),format); // 把内存中Docuemnt写到XML文件中 writer.write(document); // 关闭流 writer.close(); } }
案例
时间: 2024-12-15 12:47:23