Sax解析XML文档

SAX解析XML文件采用事件驱动的方式进行,也就是说,SAX是逐行扫描文件,遇到符合条件的设定条件后就会触发特定的事件,回调你写好的事件处理程序。使用SAX的优势在于其解析速度较快,相对于DOM而言占用内存较少。而且SAX在解析文件的过程中得到自己需要的信息后可以随时终止解析,并不一定要等文件全部解析完毕。

Sax API中有四个接口,分别是ContentHandler,DTDHandler,EntityResolver,ErrorHandler。实现可以通过实现着四个接口来实现xml解析,但是在实际中一般都是用DefaultHandler,DefaultHandler类实现了所有以上接口EntityResolverDTDHandlerContentHandlerErrorHandler,并提供了所有方法的空实现。我们在使用SAX时,一般都是继承自DefaultHandler,然后实现需要的方法,而保持其他方法默认实现。

在这里有五个个方法 需要注意

startDocument(),在开始读取xml文档的时候调用、在这里可以进行初始化的一些操作

endDocument (),结束的时候调用

startElement (String uri, String localName,String qName,Attributes attributes),这个方法是在执行读取xml ElementNode的时候会调用。

他的参数的主要 uri 指的是代表命名空间的标识符,当元素没有命名空间或
者解析器的命名空间支持特性没有打开时是空串。
localName - 代表没有前缀的本地名,当支持命名空间特性没有打开时是空串。
qName - 代表带有前缀的限定名,当限定名不能获取时是空串。

attributes - 与元素相关的属性,如果没有属性,那么就是空的属性对象。

endElement (String uri, String localName, String qName)

 public void characters (char ch[], int start, int length)参数 ch表示当前督导的textnode字节数组,starrt表示字节开始的位置,length表示textnode的长度。要获取当前textnode可以用String data=new String(ch,start,length);

举个例子:

<?xml version="1.0" encoding="UTF-8"?>
<persons>
    <person id="23">
        <name>newii</name>
        <age>21</age>
    </person>
     <person id="20">
        <name>wiwi</name>
        <age>26</age>
    </person>
</persons>
当用sax解析这个xml的时候开始先执行 startDocument 然后会读取到persons这个。就会调用 startElement。root结点一般不会做什么操作,继续往下走 到了person这个结点.一步步往下走。过程如图


其实就是挨着结点进行。

下面我们就具体讲解sax解析的操作.
一.我们通过XMLReaderFactory、XMLReader完成,步骤如下
    1.通过XMLReaderFactory创建XMLReader对象  
    XMLReader reader = XMLReaderFactory.createXMLReader();  
    2. 设置事件处理器对象  
    reader.setContentHandler(实现的DefaultHandler的实例对象);  
    3.读取要解析的xml文件  
    FileReader fileReader =new FileReader(new File(路径));  
    4.指定解析的xml文件  
    reader.parse(new InputSource(fileReader));

二.我们通过SAXParserFactory、SAXParser、XMLReader完成,步骤如下
1.使用SAXParserFactory创建SAX解析工厂
SAXParserFactory spf = SAXParserFactory.newInstance();
2.通过SAX解析工厂得到解析器对象
SAXParser sp = spf.newSAXParser();
3.通过解析器对象得到一个XML的读取器
XMLReader xmlReader = sp.getXMLReader();
4.设置读取器的事件处理器
xmlReader.setContentHandler(实现的DefaultHandler的实例对象);
5.解析xml文件
xmlReader.parse(文件路径);
如果只是使用SAXParserFactory、SAXParser他们完成只需要如下3步骤
1.获取sax解析器的工厂对象
SAXParserFactory factory = SAXParserFactory.newInstance();
2.通过工厂对象 SAXParser创建解析器对象
SAXParser saxParser = factory.newSAXParser();
3.通过解析saxParser的parse()方法设定解析的文件和自己定义的事件处理器对象
saxParser.parse(new File(文件路径),实现的DefaultHandler的实例对象);

大概流程就是这样,最后再贴上一个关于sax解析xml的代码。

public class SaxXml extends DefaultHandler {
    private static final String TAG="SAXForHandle";
    private List<Person> persons;
    private String perTag;
    Person person;
    public List<Person> getPerson(){
    	return persons;
    }
	@Override
	public void startDocument() throws SAXException {
		// TODO Auto-generated method stub
		persons=new ArrayList<Person>();
	}

	@Override
	public void endDocument() throws SAXException {
	}

	@Override
	public void startElement(String uri, String localName, String qName,
			Attributes attributes) throws SAXException {
		// TODO Auto-generated method stub
		if("person".equals(localName)){
			for (int i = 0; i < attributes.getLength(); i++) {
				Log.i(TAG, "attributeName:"+attributes.getLocalName(i)+"value"+attributes.getValue(i));
			person =new Person();
			person.setId(Integer.valueOf(attributes.getValue(i)));
			}
		}
		perTag=localName;
		
	}

	@Override
	public void endElement(String uri, String localName, String qName)
			throws SAXException {
		if("person".equals(localName)){
			persons.add(person);
			person=null;
		}
		perTag=null;
	}

	@Override
	public void characters(char[] ch, int start, int length)
			throws SAXException {
		String data=new String(ch,start,length).trim();
		if("name".equals(perTag)){
			person.setName(data);
		}else if("age".equals(perTag)){
			person.setAge(new Short(data));
		}
	}
	
	
}
如有错误之处,敬请指正。




  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值