Java对XML文档进行解析(SAX、StAX解析)

  • Post author:
  • Post category:java


SAX解析器方式入口:javax.xml.parsers包中的SAXParser解析器(通过getXMLReader获得文档阅读器)XMLReader

下面解析users.xml文件

<?xml version="1.0" encoding="UTF-8"?>
<users>
	<user id="A1001" aa="aaa">
		<name>dragon</name>
		<age>21</age>
	</user>

	<user id="A1002">
		<name>Rose</name>
		<age>19</age>
	</user>
</users>

1.

@Test
	public void demo1() throws ParserConfigurationException, SAXException, FileNotFoundException, IOException{
		//1.获得XML文档阅读器
		SAXParser sax=SAXParserFactory.newInstance().newSAXParser();
		XMLReader reader=sax.getXMLReader();
		//2.设置阅读方式
		reader.setContentHandler(new DefaultHandler(){

			@Override
			public void startDocument() throws SAXException {
				System.out.println("1.开始阅读文档!");
			}

			@Override
			public void endDocument() throws SAXException {
				System.out.println("4.文档阅读完毕");
			}
			/**
			 * uri - 名称空间 URI
			 * localName - 本地名称(不带前缀),
			 * qName - 限定名(带有前缀)
			 * atts - 连接到元素上的属性
			 */
			@Override
			public void startElement(String uri, String localName,
					String qName, Attributes attributes) throws SAXException {
				String str="";
				for(int i=0;i<attributes.getLength();i++){
					str+=attributes.getQName(i)+"="+attributes.getValue(i)+",";	//获取所有的属性
				}
				System.out.println("2.一个元素开始:"+qName+","+str);
			}

			@Override
			public void endElement(String uri, String localName, String qName)
					throws SAXException {
				System.out.println("3.一个元素结束:"+qName);
			}
			/**
			 * ch - 来自 XML 文档的字符
			 * start - 数组中的开始位置
			 * length - 从数组中读取的字符的个数 
			 */
			@Override
			public void characters(char[] ch, int start, int length)
					throws SAXException {
				String str = new String(ch, start, length);
				if(str.trim().length()!=0){
					System.out.println("文本内容"+str);
				}
			}
			
		});
		
		//3.阅读动作的触发
		reader.parse("./xml/users.xml");
	}

结果:

1.开始阅读文档!
2.一个元素开始:users,
2.一个元素开始:user,id=A1001,aa=aaa,
2.一个元素开始:name,
文本内容dragon
3.一个元素结束:name
2.一个元素开始:age,
文本内容21
3.一个元素结束:age
3.一个元素结束:user
2.一个元素开始:user,id=A1002,
2.一个元素开始:name,
文本内容Rose
3.一个元素结束:name
2.一个元素开始:age,
文本内容19
3.一个元素结束:age
3.一个元素结束:user
3.一个元素结束:users
4.文档阅读完毕

2.

/**
	 * 把users.xml中的信息读取出来,按如下格式输出
	 * 	id:A1001
	 * 	name:dragon
	 * 	age:21
	 * -------------
	 * 	id:A1002
	 *  name:Rose
	 *  age:19
	 */
	@Test
	public void demo2() throws ParserConfigurationException, Exception{
		//获取XMLReader文档阅读器
		SAXParser sax = SAXParserFactory.newInstance().newSAXParser();
		XMLReader reader=sax.getXMLReader();
		
		//设置阅读器
		reader.setContentHandler(new DefaultHandler(){
			private String elementName="";
			@Override
			public void startElement(String uri, String localName,
					String qName, Attributes attributes) throws SAXException {
				if(qName.equals("user")){
					String id=attributes.getValue("id");
					System.out.println("id:"+id);
				}else if(qName.equals("name") || qName.equals("age")){
					elementName=qName;
				}
				
			}

			@Override
			public void endElement(String uri, String localName, String qName)
					throws SAXException {
				elementName="";
				if(qName.equals("user")){
					System.out.println("----------");
				}
			}

			@Override
			public void characters(char[] ch, int start, int length)
					throws SAXException {
				if(!elementName.equals("")){
					System.out.println(elementName+":"+new String(ch, start, length));
				}
			}
			
		});
		
		
		//阅读动作的触发
		reader.parse("./xml/users.xml");
		
	}

结果:

id:A1001
name:dragon
age:21
----------
id:A1002
name:Rose
age:19
----------

StAX解析技术的入口:XMLEventReader


(extends Iterator)

下面通过StAX对users.xml进行解析

package cn.hncu.stax;

import java.io.FileReader;

import javax.xml.namespace.QName;
import javax.xml.stream.XMLEventReader;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.events.Characters;
import javax.xml.stream.events.StartElement;
import javax.xml.stream.events.XMLEvent;

/*
 * Sax的技术入口:XMLReader,通过SAXParser解析器获取
 * StAX技术的入口:XMLEventReader	(extends Iterator)
 */
public class StaxDemo {
	public static void main(String[] args) throws Exception,ClassCastException {
		//1.通过XMLInputFactory
		XMLInputFactory factory=XMLInputFactory.newFactory();
		//createXMLEventReader(Reader reader) 根据 reader 创建一个新 XMLEventReader。
		XMLEventReader reader=factory.createXMLEventReader(new FileReader("./xml/users.xml"));
		
		//reader是一个迭代器,内部遍历出的每个元素是一个XMLEventReader对象
		
		//2.遍历XML事件
		while(reader.hasNext()){
			XMLEvent event = reader.nextEvent();
			if( event.isStartElement() ){
				StartElement startElement = event.asStartElement();
				//startElement.getName()返回的是一个qName对象
				if(startElement.getName().getLocalPart().equals("user")){
					String id=startElement.getAttributeByName(new QName("id")).getValue();
					System.out.println("id:"+id);
				}else if(startElement.getName().getLocalPart().equals("name")){
					//获取文本内容   当前元素开始事件的下一个对象
					Characters chs = reader.nextEvent().asCharacters();
					System.out.println("name:"+chs.getData());
				}else if(startElement.getName().getLocalPart().equals("age")){
					//获取文本内容   当前元素开始事件的下一个对象
					Characters chs = reader.nextEvent().asCharacters();
					System.out.println("age:"+chs.getData());
				}
			}else if(event.isEndElement()){
				if(event.asEndElement().getName().getLocalPart().equals("user")){
					System.out.println("---------");
				}
			}
		}
		
	}
}

结果:

id:A1001
name:dragon
age:21
---------
id:A1002
name:Rose
age:19
---------

由以上对比可知,使用StAX对xml文档进行解析,更为灵活,所以建议采用StAX对xml文档进行解析



版权声明:本文为Dragon_Dai_2017原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。