XML文档解析:DOM解析与DOM的增删改查

DOM解析XML的概述:

DOM解析优点:

整个文档树在内存中,便于操作;
可以修改,删除、重新排列XML;
可以随机访问任何一个节点,访问效率高。

DOM解析的缺点:

占用内存大,占用资源多
解析速度慢	

DOM解析适用场合:

需多次访问这些数据;
对解析效率要求不高;
硬件资源充足(内存、CPU)。

DOM解析XML文件的步骤:

	// 1、 获取解析器类工厂
	DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
	 // 2、根据解析器工厂获得解析器
	DocumentBuilder db = factory.newDocumentBuilder();
	// 3、根据解析器获得document对象
	Document document = db.parse("dtd/books.xml");//根据自己的XML文件路径填写

得到了DOCUMENT对象document,就相当于得到了整个xml文件

接下来通过代码进行实例的分析:

books.xml:

<?xml version="1.0" encoding="gbk" standalone="no"?><books>
	<book language="zh">
		<name>红楼梦</name>
		<author>曹雪芹</author>
		<price>76</price>
	</book>
	<book language="en">
		<name>西游记</name>
		<author>吴承恩</author>
		<price>89</price>
	</book>
</books>

DOM方式解析XML(通过简单的获取元素和属性):

public class Demo1 {
	@Test
	public void Test() {
		// 1、 获取解析器类工厂
		DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
		// 2、根据解析器工厂获得解析器
		try {
			DocumentBuilder db = factory.newDocumentBuilder();
			// 3、根据解析器获得document对象
			Document document = db.parse("dtd/books.xml");
			// 根据document对象获得节点值
			NodeList nodes1 = document.getElementsByTagName("book");// 根据节点的元素名获取元素,返回的book节点可能不只一个,返回的是一个NodeList对象
			System.out.println(nodes1.getLength());
			for (int i = 0; i < nodes1.getLength(); i++) {
				Node node = nodes1.item(i);// 根据元素获取元素节点book
				//根据节获元素属性
				NamedNodeMap attributes = node.getAttributes();
				for (int j = 0; j < attributes.getLength(); j++) {
					Node item = attributes.item(j);
					System.out.println(item.getNodeName());//得到属性名
					System.out.println(item.getNodeValue());//得到属性值
				}
				System.out.println(node.getNodeName());// 得到book元素(可能不只一个book元素)
				NodeList childNodes = node.getChildNodes();// 根据上一步获得的book节点,获取book节点下面的子节点
				for (int j = 0; j < childNodes.getLength(); j++) {
					Node text = childNodes.item(j);
					// 根据节点名称和xml文件中的元素名称做比较equals的打印输出
					if (text.getNodeName().equals("name")) {
						System.out.println(text.getTextContent());
					}
					if (text.getNodeName().equals("author")) {
						System.out.println(text.getTextContent());
					}
					if (text.getNodeName().equals("price")) {
						System.out.println(text.getTextContent());
					}
				}
			}
		} catch (ParserConfigurationException | SAXException | IOException e) {
			e.printStackTrace();
		}
	}
}

接下来对XML文件进行简单的增、删、改操作:

增加元素和属性操作:

在book后面添加 1997-12-15 节点:
1、添加的位置
2、将元素创建出来

// dom元素增加操作
	@Test
	public void Test1() throws UnsupportedEncodingException, FileNotFoundException {
		// 1、获取document对象
		Document document = DomUtil.getDocument("xml/books.xml");
		// 2、问题分析:book后面添加<data>1997-12-15</data>节点
		// 2.1首先元素添加到那个位置
		Node book = document.getElementsByTagName("book").item(0);
		// 2.2元素要创建出来
		Element data = document.createElement("data");
		data.setTextContent("1997-12-15");
		book.appendChild(data);
		// 回写操作
		DomUtil.backWrite(document, "xml/books.xml");
	}

	@Test
	// 添加元素的属性
	public void Test2() throws UnsupportedEncodingException, FileNotFoundException {
		// 获得document对象
		Document document = DomUtil.getDocument("xml/books.xml");
		Element book = (Element) document.getElementsByTagName("book").item(0);

		book.setAttribute("language", "英文");
		// 回写操作
		DomUtil.backWrite(document, "xml/books.xml");
	}

删除元素和属性操作:

// dom删除元素
	@Test
	public void Test6() throws UnsupportedEncodingException, FileNotFoundException {
		// 获取document对象
		Document document = DomUtil.getDocument("xml/books.xml");
		// 获取book元素
		Node data = document.getElementsByTagName("data").item(0);
		data.getParentNode().removeChild(data);// 先获取父节点,在根据父节点去删除子节点
		// 回写操作
		DomUtil.backWrite(document, "xml/books.xml");
	}

	@Test
	// dom删除元素的属性
	public void Test4() throws UnsupportedEncodingException, FileNotFoundException {
		// 获取document对象
		Document document = DomUtil.getDocument("xml/books.xml");
		// 获取book元素
		Element book = (Element) document.getElementsByTagName("book").item(0);
		book.removeAttribute("language");

		// 回写操作
		DomUtil.backWrite(document, "xml/books.xml");
	}

修改元素和属性操作:

	@Test
	// 修改元素内容 name中的内容
	public void fun1() throws UnsupportedEncodingException, FileNotFoundException {
		// 获取document对象
		Document document = DomUtil.getDocument("dtd/books.xml");
		// 得到name元素对象
		NodeList authors = document.getElementsByTagName("author");
		Node author = authors.item(0);// 得到第一个元素为author节点,假设知道
		// 修改节点内容
		author.setTextContent("小曹");
		// 此时需要对author中的内容进行回写操作
		// 回写操作
		DomUtil.backWrite(document, "dtd/books.xml");
	}

	// 修改元素属性
	@Test
	public void fun2() throws UnsupportedEncodingException, FileNotFoundException {
		// 获取document对象
		Document document = DomUtil.getDocument("dtd/books.xml");
		// 获取需要修改的元素
		// 获取得到的元素是NodeList的返回值,.item(0)之后是Node的返回值,但是不能获取单个属性,查文档发现Element是可以获取得到单个属性
		Element en = (Element) document.getElementsByTagName("book").item(0);
		en.setAttribute("language", "en");
		// 回写操作
		DomUtil.backWrite(document, "dtd/books.xml");
	}

将回写操作和获得document对象进行封装:

//将获得document对象进行封装
	public static Document getDocument(String uri) {
		// 1、创建解析器类工厂
		DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
		// 2、根据解析器工厂生产解析器
		try {
			DocumentBuilder db = factory.newDocumentBuilder();
			// 3、根据生产的解析器获取document对象
			Document document = db.parse(uri);
			return document;
		} catch (IOException | SAXException | ParserConfigurationException e) {
			e.printStackTrace();
		}
		return null;
	}
	//将回写操作进行封装
	public static void backWrite(Document document, String uri)
			throws UnsupportedEncodingException, FileNotFoundException {
		// 1、获得修改器工厂
		TransformerFactory factory = TransformerFactory.newInstance();
		// 2、根据修改器工厂获得修改器
		try {
			Transformer tf = factory.newTransformer();
			// 3、根据修改器进行回写操作
			// tf.transform(new DOMSource(document), new StreamResult(new
			// File("dtd/books.xml")));
			//解决乱码问题,出现问题的原因是:保存的XML文件的编码和解析是的编码不一致
			tf.transform(new DOMSource(document),
					new StreamResult(new OutputStreamWriter(new FileOutputStream(uri), "GBK")));// 解决乱码问题
		} catch (TransformerConfigurationException e) {
			e.printStackTrace();
		} catch (TransformerException e) {
			e.printStackTrace();
		}
	}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值