zoukankan      html  css  js  c++  java
  • XML解析之JAXP案例详解

    根据一个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;
    	}
    
    }
    


  • 相关阅读:
    转载【工具】目前几种常见的线上接口文档管理平台的比较
    最好的Julia语言
    称霸Kaggle的十大深度学习技巧
    AI以假乱真怎么办?TequilaGAN教你轻松辨真伪
    2018 CISCN reverse
    2018 CISCN Writeup
    加壳&脱壳
    脱upx壳--初试--单步追踪
    Linux
    hackme.inndy.tw
  • 原文地址:https://www.cnblogs.com/wanghang/p/6299753.html
Copyright © 2011-2022 走看看