Java使用SAX解析xml文件详解

xml文件

xml文件是一种可扩展语言,专门用来存储和传输数据,它与html文件类,但是不用于显示文件内容,只是用来存储和传输文件。它的格式非常简单。大家可以自行百度

SAX方法解析xml文件

SAX方法是一种流解析的方法,它是以顺序的方式从头至尾的解析xml文件,过一遍之后就结束了,所以应该注意在解析的过程中不断的存储数据。
我们要解析的xml文件内容为:



    
      至尊宝
      9000
   
   
      白晶晶
      7000
   


解析代码:

public class xmltest {
	public static void main(String[] args) throws Exception {
		// SAX解析
		// 1、获取解析工厂
		SAXParserFactory factory = SAXParserFactory.newInstance();
		// 2、从解析工厂获取解析器
		SAXParser parse = factory.newSAXParser();
		// 3、编写处理器
		// 4、加载文档 Document 注册处理器
		PersonHandler handler = new PersonHandler();
		// 5、解析
		parse.parse(Thread.currentThread().getContextClassLoader().getResourceAsStream("basic/p.xml"), handler);

		List persons = handler.getPersons();
		for (person p : persons) {
			System.out.println(p.getName() + "----" + p.getAge());
		}
	}
}

class PersonHandler extends DefaultHandler {
	private List persons;
	private person p;
	private String tag;

	public void startDocument() throws SAXException {
		System.out.println("startDocument-------");
		persons = new ArrayList<>();
	}

	public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
		System.out.println("startElement-------" + qName);
		if (null != qName) {
			tag = qName;
			if (tag.equals("person")) {
				p = new person();
			}
		}
	}

	public void characters(char[] ch, int start, int length) throws SAXException {
		String contents = new String(ch, start, length);
		System.out.println("characters--------" + contents);
		if (tag != null) {
			if (tag.equals("name")) {
				p.setName(contents);
			} else if (tag.equals("age")) {
				if (contents.length() > 0)
					p.setAge(Integer.valueOf(contents));
			}
		}
	}

	public void endElement(String uri, String localName, String qName) throws SAXException {
		System.out.println("endElement-------" + qName);
		if (null != qName) {
			if (qName.equals("person"))
				persons.add(p);
		}
		tag = null;
	}

	public void endDocument() throws SAXException {
		System.out.println("endDocument-------");
	}

	public List getPersons() {
		return persons;
	}

	public void setPersons(List persons) {
		this.persons = persons;
	}

}

SAXParserFactory 在javax.xml.parsers中,是Java自带的一种类,其他用到的也是
前两步是每次必须要写的,我也不是很清楚,按照这个方法先初始化是没有问题的。
在解析中我们需要编写自己的处理器就是代码中的PersonHandler,实现一些文件解析的逻辑,就是如何处理某些数据。这是最关键的事情

PersonHandler中设置了一个person类的集合和对象,集合用来存储所有的person对象,对象用来存储每一个对象,然后将此对象加入到集合中。
在解析中我们需要重写一些方法,在解析过程中解析器会自动调用这些方法。

  1. startDocument():开始读取文件的方法,可以在这个方法内加入一些初始化的代码
  2. startElement():读取某一个标签的方法,参数中的qName代表这个标签的内容。例如:被<>包裹的标签qName就是两个尖括号中的文字。每次读到一个<>都会调用这个方法,例如:至尊宝,qName就是“name”,startElement()执行完后会执行一次characters()
  3. characters():标签中属性的方法,ch[]就是其中的内容,每次执行完startElement和endElement都会执行此方法。例如:至尊宝,ch[]就是“至尊宝”三个字,由于多层的结构,所以很多时候ch[]都为空,应该注意一下
  4. endElement():读取到结构时执行,qName返回的是其中的内容,例如:至尊宝,qName就是“name”, endElement()执行完后也会执行一次characters()
  5. endDocument():文件读取结束时执行。
    以上代码执行的结果为:
startDocument-------
startElement-------persons
characters--------
    
startElement-------person
characters--------
      
startElement-------name
characters--------至尊宝
endElement-------name
characters--------
      
startElement-------age
characters--------9000
endElement-------age
characters--------
   
endElement-------person
characters--------
   
startElement-------person
characters--------
      
startElement-------name
characters--------白晶晶
endElement-------name
characters--------
      
startElement-------age
characters--------7000
endElement-------age
characters--------
   
endElement-------person
characters--------

endElement-------persons
endDocument-------
至尊宝----9000
白晶晶----7000

根据输出结果就可以看出handler中方法的执行顺序:
对于根节点:会依次执行startElement、characters、endElement三个方法
对于非根节点:会依次执行startElement、characters、endElement、characters四个方法
这样,就可以根据自己的需求编写解析代码了

你可能感兴趣的:(Java)