Java处理xml

1、xml

XML是一种通用的数据交换格式,它的平台无关性、语言无关性、系统无关性、给数据集成与交互带来了极大的方便。本文主要使用DOM解析、SAX解析、JDOM解析、DOM4J解析等四种方式解析XML。

2 、DMO

2.1特性

优点:
1、形成了树结构,有助于更好的理解、掌握,且代码容易编写。
2、解析过程中,树结构保存在内存中,方便修改。
3、
缺点:
1、由于文件是一次性读取,所以对内存的耗费比较大。
2、如果XML文件比较大,容易影响解析性能且可能会造成内存溢出。

2.2 示例

package xml;

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;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.*;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintWriter;

/**
 * <p>
 * DOM生成与解析XML文档
 * <p>
 * 优点:整个文档树在内存中,便于操作;支持删除、修改、重新排列等多种功能
 * <p>
 * 缺点:将整个文档调入内存(包括无用的节点),浪费时间和空间; 使用场合:一旦解析了文档还需多次访问这些数据;硬件资源充足(内存、CPU)。
 * 
 * @author pp
 */
public class DomDemo {

	// 创建xml到指定文件中
	public static void createXml(String fileName) throws ParserConfigurationException {
		DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
		DocumentBuilder builder = factory.newDocumentBuilder();
		Document document = builder.newDocument();

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

		/* 子节点(可以包含多个) */
		Element employee = document.createElement("employee");

		Element name = document.createElement("name");
		name.appendChild(document.createTextNode("丁宏亮"));
		employee.appendChild(name);
		Element sex = document.createElement("sex");
		sex.appendChild(document.createTextNode("m"));
		employee.appendChild(sex);
		Element age = document.createElement("age");
		age.appendChild(document.createTextNode("30"));
		employee.appendChild(age);

		/* 把字节点放入根节点 */
		root.appendChild(employee);

		TransformerFactory tf = TransformerFactory.newInstance();

		try {
			Transformer transformer = tf.newTransformer();
			DOMSource source = new DOMSource(document);
			transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
			transformer.setOutputProperty(OutputKeys.INDENT, "yes");
			PrintWriter pw = new PrintWriter(new FileOutputStream(fileName));
			StreamResult result = new StreamResult(pw);
			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 static void parserXml(String fileName) {
		try {

			DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
			DocumentBuilder db = dbf.newDocumentBuilder();
			Document document = db.parse(fileName);
			/*
			 * 第一个for为了获取root(根)元素,第二个才开始获取元素 与Dom4j相比多了此步骤
			 */
			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++) {
						Node node2 = employeeMeta.item(k);
						if (node2 instanceof Element) {
							System.out.println(node2.getNodeName()+ ":" + node2.getTextContent());
						}
						if (k == employeeMeta.getLength() - 1) {
							System.out.println("-------------");
						}
					}
				}
			}
			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());
		}
	}
}

3、SAX

3.1

优点:
1、采用事件驱动模式,对内存耗费比较小。
2、适用于只处理XML文件中的数据时。
缺点:
1、编码比较麻烦。
2、很难同时访问XML文件中的多处不同数据。

3.2

package xml;

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.AttributesImpl;
import org.xml.sax.helpers.DefaultHandler;

import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Result;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.sax.SAXTransformerFactory;
import javax.xml.transform.sax.TransformerHandler;
import javax.xml.transform.stream.StreamResult;
import java.io.*;

/**
 * <p>SAX文档解析 
 * <p>优点:不用事先调入整个文档,占用资源少;SAX解析器代码比DOM解析器代码小,适于Applet,下载。
 * <p>缺点:不是持久的;事件过后,若没保存数据,那么数据就丢了;无状态性;从事件中只能得到文本,但不知该文本属于哪个元素
 * @author pp
 */ 
public class SaxDemo {
	public static void createXml(String fileName) {
		//创建一个 SAXTransformerFactory 类对象
		SAXTransformerFactory tff = (SAXTransformerFactory)SAXTransformerFactory.newInstance();

		try {
			//通过 SAXTransformerFactory 对象创建一个 TransformerHandler 对象
			TransformerHandler handler = tff.newTransformerHandler();
			//通过 TransformerHandler 对象创建一个 Transformer 对象
			Transformer tr = handler.getTransformer();
			//设置生成的 XML 文件编码格式
			tr.setOutputProperty(OutputKeys.ENCODING, "utf-8");
			//设置生成的 XML 文件自动换行
			tr.setOutputProperty(OutputKeys.INDENT, "yes");
			//如果不存在,就创建一个新的 XML 文件
			File file = new File(fileName);
			if (!file.exists()) {
				file.createNewFile();
			}
			//创建一个Result 对象,并且使其与 TransformerHandler 对象关联
			Result result = new StreamResult(new FileOutputStream(file));
			handler.setResult(result);

			//利用 handler 对象进行 XML 文件内容的编写
			//打开 document
			handler.startDocument();
			//为了创建节点属性和属性值
			AttributesImpl atts = new AttributesImpl();
			//根节点开始标签
			handler.startElement("", "", "School", atts);
			//atts.clear();  //清空 atts 的值
			//设置属性和属性值
			atts.addAttribute("", "", "id", "", "1");
			//子节点开始标签
			handler.startElement("", "", "student", atts);

			atts.clear();  //清空子节点设的值
			//字节点下name节点开始标签
			handler.startElement("", "", "name", atts);
			String name="pwx";
			handler.characters(name.toCharArray(), 0, name.length());
			//字节点下name节点结束标签
			handler.endElement("", "", "name");
			//子节点结束标签
			handler.endElement("", "", "student");

			//根节点结束标签
			handler.endElement("", "", "School");

			//关闭 document
			handler.endDocument();

		} catch (TransformerConfigurationException e) {
			e.printStackTrace();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} catch (SAXException e) {
			e.printStackTrace();
		}
	} 
	public static void parserXml(String fileName) { 
		SAXParserFactory saxfac = SAXParserFactory.newInstance(); 
		try { 
			SAXParser saxparser = saxfac.newSAXParser(); 
			InputStream is = new FileInputStream(fileName); 
			saxparser.parse(is, new MySAXHandler()); 
		} catch (ParserConfigurationException e) { 
			e.printStackTrace(); 
		} catch (SAXException e) { 
			e.printStackTrace(); 
		} catch (FileNotFoundException e) { 
			e.printStackTrace(); 
		} catch (IOException e) { 
			e.printStackTrace(); 
		} 
	} 
} 
class MySAXHandler extends DefaultHandler { 
	boolean hasAttribute = false; 
	Attributes attributes = null; 
	public void startDocument() throws SAXException { 
		System.out.println("文档开始打印了"); 
	} 
	public void endDocument() throws SAXException { 
		System.out.println("文档打印结束了"); 
	} 
	public void startElement(String uri, String localName, String qName, 
			Attributes attributes) throws SAXException { 
		if (qName.equals("employees")) { 
			return; 
		} 
		if (qName.equals("employee")) { 
			System.out.println(qName); 
		} 
		if (attributes.getLength() > 0) { 
			this.attributes = attributes; 
			this.hasAttribute = true; 
		} 
	} 
	public void endElement(String uri, String localName, String qName) 
			throws SAXException { 
		if (hasAttribute && (attributes != null)) { 
			for (int i = 0; i < attributes.getLength(); i++) { 
				System.out.println(attributes.getQName(0) 
						+ attributes.getValue(0)); 
			} 
		} 
	} 
	public void characters(char[] ch, int start, int length) 
			throws SAXException { 
		System.out.println(new String(ch, start, length)); 
	} 
} 

4、JDom

4.1 特征:

	1、仅使用具体类,而不使用接口。
	2、API大量使用了Collections类。

4.2 Mven依赖

<dependency>
    <groupId>org.jdom</groupId>
    <artifactId>jdom</artifactId>
    <version>1.1.3</version>
</dependency>

4.3 示例

package xml;

import org.jdom.Document;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.input.SAXBuilder;
import org.jdom.output.XMLOutputter;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.List;
/**  
 * JDOM 生成与解析XML文档  
 * @author pp
 */  
public class JDomDemo extends XmlDocument {   

	public static void createXml(String fileName) {   
		Document document;   
		Element  root;   
		root=new Element("employees");   
		document=new Document(root);   
		Element employee=new Element("employee");   
		root.addContent(employee);   
		Element name=new Element("name");   
		name.setText("ddvip");   
		employee.addContent(name);   
		Element sex=new Element("sex");   
		sex.setText("m");   
		employee.addContent(sex);   
		Element age=new Element("age");   
		age.setText("23");   
		employee.addContent(age);   
		XMLOutputter XMLOut = new XMLOutputter();   
		try {   
			XMLOut.output(document, new FileOutputStream(fileName));   
		} catch (FileNotFoundException e) {   
			e.printStackTrace();   
		} catch (IOException e) {   
			e.printStackTrace();   
		}   

	}   

	public  static void parserXml(String fileName) {   
		SAXBuilder builder=new SAXBuilder(false);    
		try {   
			Document document=builder.build(fileName);   
			Element employees=document.getRootElement();    
			List<?> employeeList=employees.getChildren("employee");   
			for(int i=0;i<employeeList.size();i++){
				Element employee=(Element)employeeList.get(i);   
				List<?> employeeInfo=employee.getChildren();   
				for(int j=0;j<employeeInfo.size();j++){
					System.out.println(((Element)employeeInfo.get(j)).getName()+":"+((Element)employeeInfo.get(j)).getValue());   
				}   
			}   
		} catch (JDOMException e) {   
			e.printStackTrace();   
		} catch (IOException e) {   
			e.printStackTrace();   
		}    

	}   
}   

5、DOM4J

5.1 特征

1、JDOM的一种智能分支,它合并了许多超出基本XML文档表示的功能。
2、它使用接口和抽象基本类方法。
3、具有性能优异、灵活性好、功能强大和极端易用的特点。
4、是一个开放源码的文件

5.2 Maven依赖

<dependency>
   <groupId>dom4j</groupId>
   <artifactId>dom4j</artifactId>
   <version>1.6</version>
</dependency>

5.3 示例

package xml;

import java.io.File;   
import java.io.FileWriter;   
import java.io.IOException;   
import java.io.Writer;   
import java.util.Iterator;   

import org.dom4j.Document;   
import org.dom4j.DocumentException;   
import org.dom4j.DocumentHelper;   
import org.dom4j.Element;   
import org.dom4j.io.SAXReader;   
import org.dom4j.io.XMLWriter;   
/**  
 * <p>Dom4j 生成XML文档与解析XML文档  
 * <p>DOM4J 是一个非常非常优秀的Java XML API
 * @author pp
 */  
public class Dom4jDemo extends XmlDocument {   

	public static void createXml(String fileName){
		Document document = DocumentHelper.createDocument();   
		Element employees=document.addElement("employees");   
		Element employee=employees.addElement("employee");   
		Element name= employee.addElement("name");   
		name.setText("pp");   
		Element sex=employee.addElement("sex");   
		sex.setText("man");   
		Element age=employee.addElement("age");   
		age.setText("18");   
		try {   
			Writer fileWriter=new FileWriter(fileName);   
			XMLWriter xmlWriter=new XMLWriter(fileWriter); 
			xmlWriter.write(document);   
			xmlWriter.close();   
		} catch (IOException e) {   
			System.out.println(e.getMessage());   
		}   
	}   

	public static void parserXml(String fileName) {
		File inputXml=new File(fileName);   
		SAXReader saxReader = new SAXReader();   
		try {
			Document document = saxReader.read(inputXml);   
			Element employees=document.getRootElement();
			for(Iterator<?> i = employees.elementIterator(); i.hasNext();){   
				Element employee = (Element) i.next();   
				for(Iterator<?> j = employee.elementIterator(); j.hasNext();){   
					Element node=(Element) j.next();   
					System.out.println(node.getName()+":"+node.getText());
				}   
			}   
		} catch(DocumentException e) {   
			System.out.println(e.getMessage());   
		}   
	}   
}   

6、总结

DOM4J性能最好,连Sun的JAXM也在用DOM4J。目前许多开源项目中大量采用DOM4J,例如大名鼎鼎的Hibernate也用DOM4J来读取XML配置文件。如果不考虑可移植性,那就采用DOM4J。
JDOM和DOM在性能测试时表现不佳,在测试10M文档时内存溢出。在小文档情况下还值得考虑使用DOM和JDOM。另外,DOM仍是一个非常好的选择。DOM实现广泛应用于多种编程语言。它还是许多其它与XML相关的标准的基础,因为它正式获得W3C推荐(与基于非标准的Java模型相对),所以在某些类型的项目中可能也需要它(如在JavaScript中使用DOM)。
SAX表现较好,这要依赖于它特定的解析方式-事件驱动。一个SAX检测即将到来的XML流,但并没有载入到内存(当然当XML流被读入时,会有部分文档暂时隐藏在内存中)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

书香水墨

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值