# java对xml文件的基本操作

下面是简单的总结三种常用的java对xml文件的操作

1. dom方式对xml进行操作,这种操作原理是将整个xml文档读入内存总,在内存中进行操作,当xml文档非常庞大的时候就会出现内存溢出的异常,这种方式可以进行增删改查的操作。
2. sax方式进行xml的操作,这种方式则不是将整个xml文档读入到内存中进行操作,sax的操作方式是实时将文档中的数据进行处理,这种方式是一个标签一个标签的进行读取,然后由程序员去实现一个自定义的操作,那么这里需要去实现ContentHandler这个接口中的方法,但是这种方式只能读取xml中的数据,效率快,不占用太大内存。
3. dom4j这是有第三方提供的一种解析方式,我们需要去下载dom4j.jar才能进行使用,这种方式结合了前两种的一些优势,也是比较常用的一种解析方式。
一、dom对xml的基本操作
		<?xml version="1.0" encoding="UTF-8" standalone="no"?>
		<书架>
		
		<书>
			<书名>科学怪人</书名>
			<作者>张三</作者>
			<售价>20.0元</售价>
		</书>
		<书>
			<书名>java</书名>
			<作者>扎笑道</作者>
		</书>
		</书架>

下面这个例子就是简单操作xml的例子:
要求:对上面这个xml文件进行操作

package com.cn.ljh.jaxpxml;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
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;


public class JaxpXml {
	public static void main(String [] args) throws Exception{
				//1、创建一个工厂类
		DocumentBuilderFactory doucumentfactory = DocumentBuilderFactory.newInstance();
		//2、创建一个解析器
		DocumentBuilder builder = doucumentfactory.newDocumentBuilder();
		Document document = builder.parse("src/Books.xml");
		test7(document);
	}
	//1、在第一个元素上在增加一个子元素
	public static boolean test1(Document document) throws Exception{
		//先创建一个新的元素
		Element element = document.createElement("内部价");
		element.setTextContent("1元");
		//获得父节点
		Node node = document.getElementsByTagName("书").item(0);
		//将新创建的节点添加上去
		node.appendChild(element);
		//将内存中的数据写入到硬盘
		TransformerFactory factory = TransformerFactory.newInstance();
		Transformer transformer = factory.newTransformer();
		transformer.transform(new DOMSource(document), new StreamResult("src/Books.xml"));
		return true;
	}
	//2、在第一个元素的第一个子元素前面增加一个兄弟元素
	public static boolean test2(Document document) throws TransformerException {
		//创建一个新的元素
		Element element = document.createElement("笔名");
		element.setTextContent("大侠");
		//获取插入位置的元素
		Node node = document.getElementsByTagName("书名").item(0);
		System.err.println(node.getTextContent());
		
		node.insertBefore(element, node);
		
		//node.appendChild(element);
		//将内存中的数据写入到硬盘上
		TransformerFactory factory = TransformerFactory.newInstance();
		factory.newTransformer().transform(new DOMSource(document), new StreamResult("src/Books.xml"));
		return true;
	}
	//3、删除第一个元素的第一个子元素
	public static boolean test3(Document document) throws Exception{
		//得到第一个节点
		Node node = document.getElementsByTagName("内部价").item(0);
		//获得父节点
		node.getParentNode().removeChild(node);
		//将内存中的数据写入硬盘中
		TransformerFactory factory = TransformerFactory.newInstance();
		factory.newTransformer().transform(new DOMSource(document), new StreamResult("src/Books.xml"));
		
		return true;
	}
	//4、删除第一个元素
	public static boolean test4(Document document){
		Node node = document.getElementsByTagName("书").item(0);
		node.getParentNode().removeChild(node);
		TransformerFactory factory = TransformerFactory.newInstance();
		try {
			factory.newTransformer().transform(new DOMSource(document), new StreamResult("src/Books.xml"));
		} catch (TransformerException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return true;
	}
	//5、在第二个元素上增加属性
	public static void test5(Document document) throws Exception{
		Node node = document.getElementsByTagName("书").item(0);
		Element element = (Element) node;
		element.setAttribute("出版社","四川出版社");
		
		//将文件写入硬盘
		TransformerFactory factory = TransformerFactory.newInstance();
		factory.newTransformer().transform(new DOMSource(document), new StreamResult("src/Books.xml"));
	}
	//6、删除第一个元素的属性
	public static void test6(Document document) throws Exception{
		//获得第一个节点
		Node node = document.getElementsByTagName("书").item(0);
		Element element = (Element) node;
		element.removeAttribute("出版社");
		
		TransformerFactory factory = TransformerFactory.newInstance();
		factory.newTransformer().transform(new DOMSource(document), new StreamResult("src/Books.xml"));
	}
	//7、增加一个新的完整的元素,这个元素有三个子元素,并且添加一个属性
	public static void test7(Document document) throws Exception{
		//创建一个新的元素
		Element oneE = document.createElement("书");
		Element towE = document.createElement("书名");
		towE.setTextContent("java");
		Element towW = document.createElement("作者");
		towW.setTextContent("扎笑道");
		//获取父节点(书架)
		Node node = document.getFirstChild();
		node.appendChild(oneE);
		
		oneE.appendChild(towE);
		oneE.appendChild(towW);
		
		TransformerFactory factory = TransformerFactory.newInstance();
		factory.newTransformer().transform(new DOMSource(document), new StreamResult("src/Books.xml"));
		
	}
	//8、获取第一个元素的第一个子元素的内容
	public static boolean test8(Document document){
		NodeList nodelist = document.getElementsByTagName("书名");
		Node node = nodelist.item(0);
		String name = node.getTextContent();
		System.out.println(name);
		return false;
	}
	//9、获取属性内容
	public static void test9(Document document){
		NodeList nodelist = document.getElementsByTagName("书");
		Node node = nodelist.item(0);
		Element element = (Element) node;
		String attName = element.getAttribute("id");
		System.out.println(attName);
	}
	//10、循环遍历打印标签内容
	public static void test10(Node node){
		//判断是不是Node类型
		short type = node.getNodeType();
		if(type == Node.ELEMENT_NODE){
			System.out.println(node.getNodeName());
		}
		NodeList nodelist = node.getChildNodes();
		long len = nodelist.getLength();
		for(int i=0;i<len;i++){
			Node n = nodelist.item(i);
			test10(n);
		}
	}
	//11、修改第一本书的书名的内容
	public static boolean test11(Document document) throws Exception{
		//得到第一本书
		NodeList nodelist = document.getElementsByTagName("书名");
		//得到第一本书的书名元素
		Node node = nodelist.item(0);
		node.setTextContent("商人");
		//将内存中的数据写到硬盘上
		TransformerFactory factory = TransformerFactory.newInstance();
		factory.newTransformer().transform(new DOMSource(document), new StreamResult("src/Books.xml"));
		return true;
	}
}

二、sax对xml的基本操作
	<?xml version="1.0" encoding="UTF-8"?>
		<movies>
			<movie>
				<name>捉妖记</name>
				<time>2015</time>
				<director>许诚毅</director>
			</movie>
			<movie>
				<name>老炮儿</name>
				<director>冯小刚</director>
				<time>2016</time>
			</movie>
		</movies>

下面这个例子就是sax对xml的基本操作:
要求:对上面的xml文件进行内容读取,然后进行数据的封装

数据封装类

	package com.cn.ljh.sax;
	public class Movie {
		private String name;
		private String time;
		private String director;
		
		public Movie(){
			
		}
		public String getName() {
			return name;
		}
		public void setName(String name) {
			this.name = name;
		}
		public String getTime() {
			return time;
		}
		public void setTime(String time) {
			this.time = time;
		}
		public String getDirector() {
			return director;
		}
		public void setDirector(String director) {
			this.director = director;
		}
}

sax操作类

package com.cn.ljh.sax;
import java.util.ArrayList;
import java.util.List;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.DefaultHandler;

public class SaxTeat {
	
	//现在要求将xml文档中的所有内容读取到movie中进行封装
	public static void main(String[] args) throws Exception {
		//下面就是sax解析xml的方式
		//创建sax解析工厂
		SAXParserFactory factory = SAXParserFactory.newInstance();
		//创建sax的解析器
		SAXParser parser = factory.newSAXParser();
		//创建xml读取器
		XMLReader reader = parser.getXMLReader();
		
		List<Movie> movies = new ArrayList<Movie>();//存储电影数据
		
		//挂载解析器(并实现解析其中的方法)
		reader.setContentHandler(new DefaultHandler(){
			
			Movie movie = null;
			String tag = null;
		
			
			//读取到元素开始,执行该方法
			public void startElement(String uri, String localName, String qName, Attributes attributes)
					throws SAXException {
				super.startElement(uri, localName, qName, attributes);
				if("movie".equals(qName)){
					movie = new Movie();
				}
				tag = qName;
			}
			
			//读取到元素结束,执行该方法
			public void endElement(String uri, String localName, String qName) throws SAXException {
				super.endElement(uri, localName, qName);
				if("movie".equals(qName)){
					movies.add(movie);
				}
			}
			
			//读取到内容,执行该方法
			public void characters(char[] ch, int start, int length) throws SAXException {
				super.characters(ch, start, length);
				if("name".equals(tag)){
					movie.setName(new String(ch,start,length));
				}
				if("time".equals(tag)){
					movie.setTime(new String(ch, start, length));
				}
				if("director".equals(tag)){
					movie.setDirector(new String(ch,start,length));
				}
				tag = null;
			}
		});
		
		reader.parse("src/movie.xml");
		
		for(Movie m : movies){
			System.out.println(m.getName());
			System.out.println(m.getDirector());
			System.out.println(m.getTime());
		}
	}
}

可以看到上面,我没有去实现ContentHandler这个接口,我是去继承了DefaultHandler类,这里用到了适配器的设计模式(这样我们可以更加方便的去实现里面的方法)。同时我们也可以看出来,这个类中的方法就像是事件一样的方法,当解析器读到每一个标签或者内容都会触发这些方法,所以,这些方法需要自己去实现。同时,这样操作我们还需要将数据进行封装,这样方便我们以后的操作。

三、dom4j对xml的基本操作
	<?xml version="1.0" encoding="UTF-8"?>
		<cars>
			<car time="2015">
				<name>科鲁兹</name>
				<color>白色</color>
				<price>1500000</price>
				<oil>10.L</oil>
			</car>
			<car where="中国">
				<name>新蒙迪欧</name>
				<price>1700000</price>
			</car>
			<car where="japan">
				<name>丰田</name>
				<color>黑色</color>
				<price>1000000</price>
			</car>
		</cars>

下面这个例子就是dom4j对xml的基本操作
要求:对上面的xml文件进行一些简单的操作

	package com.cn.ljh.Dom4j;
	import java.io.FileWriter;
	import java.util.List;
	import org.dom4j.Attribute;
	import org.dom4j.Document;
	import org.dom4j.Element;
	import org.dom4j.Node;
	import org.dom4j.io.SAXReader;
	import org.dom4j.io.XMLWriter;
	import org.junit.Test;

	public class Dom4jTest {
	
		// 对cas这个xml文件进行操作,利用dom4j的方式
	
		// 1.得到第一辆车的名字
		@Test
		public void test1() throws Exception {
			SAXReader read = new SAXReader();
			// 得到文档树
			Document document = read.read("src/cars.xml");
			// 得到根元素
			Element root = document.getRootElement();
			List<Element> elements = root.elements("car");
			// 得到第一个car元素
			Element e = elements.get(0);
			// 得到name元素
			Element name_E = e.element("name");
			String name = name_E.getText();
			System.out.println("name= " + name);
		}
	
		// 2.得到第二辆车的属性
		@Test
		public void test2() throws Exception {
			// 得到读取器
			SAXReader read = new SAXReader();
			Document document = read.read("src/cars.xml");
			// 得到根元素
			Element root = document.getRootElement();
			// 得到所有车的元素
			List<Element> es = root.elements("car");
			// 得到第二个车的元素
			Element car2 = es.get(1);
			Attribute att = car2.attribute("where");
			String where = att.getText();
			System.out.println("where=" + where);
		}
	
		// 3.得到第二辆车的价格
		@Test
		public void test3() throws Exception {
			SAXReader read = new SAXReader();
			Document document = read.read("src/cars.xml");
			Element root = document.getRootElement();
			List<Element> cars = root.elements("car");
			Element car = cars.get(1);
			// 得到价格
			Element price = car.element("price");
			String text = price.getText();
			System.out.println(text);
		}
	
		// 4.添加第一辆车一个属性
		@Test
		public void test4() throws Exception {
			SAXReader read = new SAXReader();
			Document document = read.read("src/cars.xml");
			Element root = document.getRootElement();
			List<Element> cars = root.elements("car");
			Element car = cars.get(0);
			// 添加属性
			car.addAttribute("time", "2015");
			// 将内存中的数据写到硬盘上
			XMLWriter writer = new XMLWriter(new FileWriter("src/cars.xml"));
			writer.write(document);
			writer.close();
	
			String text = car.attribute("time").getText();
			System.out.println(text);
	
		}
	
		// 5.删除第一辆车的属性
		@Test
		public void test5() throws Exception {
			SAXReader read = new SAXReader();
			Document document = read.read("src/cars.xml");
			Element root = document.getRootElement();
			List<Element> cars = root.elements("car");
			Element car = cars.get(0);
			// 得到第一辆车的属性
			Attribute att = car.attribute("where");
			// 删除属性
			car.remove(att);
			// 将内存中的数据写入到硬盘上
			XMLWriter writer = new XMLWriter(new FileWriter("src/cars.xml"));
			writer.write(document);
			writer.close();
		}
	
		// 6.给第一辆车添加油耗元素
		@Test
		public void test6() throws Exception {
			SAXReader reader = new SAXReader();
			Document document = reader.read("src/cars.xml");
			Element root = document.getRootElement();
			List<Element> cars = root.elements("car");
			Element car = cars.get(0);
			// 添加一个元素
			car.addElement("oil").addText("10.L");
			// 将数据写入到内存中
			XMLWriter writer = new XMLWriter(new FileWriter("src/cars.xml"));
			writer.write(document);
			writer.close();
		}
	
		// 7.删除第二辆车的颜色的元素
		@Test
		public void test7() throws Exception {
			SAXReader reader = new SAXReader();
			Document document = reader.read("src/cars.xml");
			Element root = document.getRootElement();
			List<Element> cars = root.elements("car");
			Element car = cars.get(1);
			Element color = car.element("color");
			car.remove(color);
			// 将数据写入到硬盘上
			XMLWriter writer = new XMLWriter(new FileWriter("src/cars.xml"));
			writer.write(document);
			writer.close();
		}
		// 8.打印所有的标签内容和名字
		@Test
		public void test8() throws Exception{
			SAXReader reader = new SAXReader();
			Document document = reader.read("src/cars.xml");
			Element root = document.getRootElement();
			//遍历所有元素
			print(root);
			
		}
		
		//遍历所有元素的方法
		private void print(Element element){
			String text_name = element.getName();
			String text = element.getText();
			System.out.println("name = "+text_name+"text = "+text);
			for(int i=0,size = element.nodeCount(); i < size;i++){
				Node node = element.node(i);
				if(node instanceof Element){
					print((Element) node);
				}
			}
		}
		
		// 9.创建一个完整的car,包含属性
		@Test
		public void test9() throws Exception{
			SAXReader reader = new SAXReader();
			Document document = reader.read("src/cars.xml");
			Element root = document.getRootElement();
			Element car  = root.addElement("car")
					.addAttribute("where", "japan");
			car.addElement("name").addText("丰田");
			car.addElement("color").addText("黑色");
			car.addElement("price").addText("1000000");
			
			//将内存中的数据写入到硬盘中
			XMLWriter writer = new XMLWriter(new FileWriter("src/cars.xml"));
			writer.write(document);
			writer.close();
		}
	}
	

那么上面这些例子只是简单的以dom4j的方式进行简单的操作,dom4j的功能还有非常多,当我们需要使用这种方式去操作一个xml的时候可以去研究官方文档。dom4j的操作方式要比上面的两种简单高效。

记录学习的每一步,记录每一次的成长!!!!

原文地址:https://www.cnblogs.com/mojita/p/5259913.html