xml jdk原生api生成和解析---dom解析

原创
2012/12/30 09:16
阅读数 3.5K
解析器读入整个文档,然后构建一个驻留内存的树结构。

优点:整个文档树在内存中,便于操作;支持删除、修改、重新排列等多种功能;
缺点:将整个文档调入内存(包括无用的节点),浪费时间和空间;

使用场合:一旦解析了文档还需多次访问这些数据;硬件资源充足(内存、CPU)。 


import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintWriter;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
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;
import org.xml.sax.SAXException;

/**
 * 
 * @author hongliang.dinghl DOM生成与解析XML文档
 */
public class DomDemo {
	private Document document;
	private String fileName;

	public void init() {
		try {
			DocumentBuilderFactory factory = DocumentBuilderFactory
					.newInstance();
			DocumentBuilder builder = factory.newDocumentBuilder();
			this.document = builder.newDocument();
		} catch (ParserConfigurationException e) {
			System.out.println(e.getMessage());
		}
	}

	public void createXml(String fileName) {
		//创建一个新的文档对象
		init();
		//根节点
		Element root = this.document.createElement("employees");
		//将根节点加载到文档对象中
		this.document.appendChild(root);
		
		//创建子元素
		Element employee = this.document.createElement("employee");
		Element name = this.document.createElement("name");
		
		//添加文本节点
		name.appendChild(this.document.createTextNode("qiankunshe"));
		
		employee.appendChild(name);
		Element age = this.document.createElement("age");
		age.appendChild(this.document.createTextNode("25"));
		employee.appendChild(age);
		
		//添加层级关系
		root.appendChild(employee);
		TransformerFactory tf = TransformerFactory.newInstance();
		try {
			Transformer transformer = tf.newTransformer();
			DOMSource source = new DOMSource(document);
			
			//添加xml 头信息
			transformer.setOutputProperty(OutputKeys.ENCODING, "gb2312");
			transformer.setOutputProperty(OutputKeys.INDENT, "yes");
			
			//输出xml流信息包装类
			PrintWriter pw = new PrintWriter(new FileOutputStream(fileName));
			StreamResult result = new StreamResult(pw);
			
			//将xml写到文件中
			transformer.transform(source, result);
			System.out.println("生成XML文件成功!");
		} catch (TransformerConfigurationException e) {
			System.out.println(e.getMessage());
		} catch (IllegalArgumentException e) {
			System.out.println(e.getMessage());
		} catch (FileNotFoundException e) {
			System.out.println(e.getMessage());
		} catch (TransformerException e) {
			System.out.println(e.getMessage());
		}
	}

	public void parserXml(String fileName) {
		try {
			DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
			DocumentBuilder db = dbf.newDocumentBuilder();
			
			//将xml文件解析
			Document document = db.parse(fileName);
			
			//获得所有节点,递归遍历节点
			NodeList employees = document.getChildNodes();
			for (int i = 0; i < employees.getLength(); i++) {
				//取得一个节点
				Node employee = employees.item(i);
				
				
				NodeList employeeInfo = employee.getChildNodes();
				for (int j = 0; j < employeeInfo.getLength(); j++) {
					Node node = employeeInfo.item(j);
					NodeList employeeMeta = node.getChildNodes();
					for (int k = 0; k < employeeMeta.getLength(); k++) {
						System.out.println(employeeMeta.item(k).getNodeName()
								+ ":" + employeeMeta.item(k).getTextContent());
					}
				}
			}
			System.out.println("解析完毕");
		} catch (FileNotFoundException e) {
			System.out.println(e.getMessage());
		} catch (ParserConfigurationException e) {
			System.out.println(e.getMessage());
		} catch (SAXException e) {
			System.out.println(e.getMessage());
		} catch (IOException e) {
			System.out.println(e.getMessage());
		}
	}
}


* 创建xml

1、创建文档对象

            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
            DocumentBuilder builder = factory.newDocumentBuilder();
            this.document = builder.newDocument();

       上面三句话是创建一个文档对象,第一步是获得一个文档解析工厂对象,第二步是通过工厂方法创建一个新的解析对象,第三步是创建一个新的文档对象


2、创建元素节点节点

    Element root = this.document.createElement("employees");

3、创建属性节点

    root.setAttribute("name", "liu");

4、创建文本子节点

    root.appendChild(this.document.createTextNode("qiankunshe"));

5、文本加入到文档对象中

    this.document.appendChild(root);

到这里就要描述下xml文档的结构了

1、xml为树形结构(如果学习过html的同学应该是知道的,html为特殊的xml),由根节点——》枝节点——》叶节点

以下图职员信息xml为例:

其中employees为根节点,employe、name、age都是枝节点(这些节点都是元素节点)

而liu、25为文本节点


通过上图说明了,我们在创建xml时,employees包含n个employe元素,employe元素有包含了一个name和一个age元素

理论上这个语句就表名我们要的方法了document.appendChild(root);

只不过document变成了employees或employe、name、age了,但要记得一点就是节点只能添加到元素节点下面


xml解析

public void parserXml(String fileName) {
		try {
			DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
			DocumentBuilder db = dbf.newDocumentBuilder();
			
			//将xml文件解析
			Document document = db.parse(fileName);
			
			//获得所有节点,递归遍历节点
			NodeList employees = document.getChildNodes();
			for (int i = 0; i < employees.getLength(); i++) {
				//取得一个节点
				Node employee = employees.item(i);
				
				
				NodeList employeeInfo = employee.getChildNodes();
				for (int j = 0; j < employeeInfo.getLength(); j++) {
					Node node = employeeInfo.item(j);
					NodeList employeeMeta = node.getChildNodes();
					for (int k = 0; k < employeeMeta.getLength(); k++) {
						System.out.println(employeeMeta.item(k).getNodeName()
								+ ":" + employeeMeta.item(k).getTextContent());
					}
				}
			}
			System.out.println("解析完毕");
		} catch (FileNotFoundException e) {
			System.out.println(e.getMessage());
		} catch (ParserConfigurationException e) {
			System.out.println(e.getMessage());
		} catch (SAXException e) {
			System.out.println(e.getMessage());
		} catch (IOException e) {
			System.out.println(e.getMessage());
		}
	}

1.创建解析对象

DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();

2.解析文件

Document document = db.parse(fileName);

3.获得文档第一层节点

NodeList employees = document.getChildNodes();

4.一层一层的解析完毕

NodeList employees =  employees.item(i).getChildNodes();


使用原生api进行解析时,可以先使用

document.getElementById("");
document.getElementsByTagName("");
直接获得自己要解析的对象


使用原生的api的问题

1.对xml格式有强依赖,有换行和无换行的xml,解析出来的东西是不同的(会多几个文本节点)

2.为一次性加载,对于解析大的xml来说,可能会出现内存溢出的情况


解决方式

1.加入类型判断,如:node.getNodeType() == Node.ELEMENT_NODE; 判断节点是不是元素节点

2.对于太大的xml可以适当的截取,来解析


展开阅读全文
打赏
0
5 收藏
分享
加载中
更多评论
打赏
0 评论
5 收藏
0
分享
返回顶部
顶部