SAX介绍
SAX(Simple API for XML)是一种事件驱动的流式XML文件处理方式,区别与DOM方式的是不需要在内存中建一棵DOM树,而是根据读取XML时遇到的标签事件来顺序处理,因此具有速度快,内存占用上的优点。
XML生成
代码如下:
1 package com.test.sax; 2 3 import javax.xml.transform.OutputKeys; 4 import javax.xml.transform.Result; 5 import javax.xml.transform.Transformer; 6 import javax.xml.transform.TransformerConfigurationException; 7 import javax.xml.transform.sax.SAXTransformerFactory; 8 import javax.xml.transform.sax.TransformerHandler; 9 import javax.xml.transform.stream.StreamResult; 10 11 import org.xml.sax.SAXException; 12 import org.xml.sax.helpers.AttributesImpl; 13 14 public class TestCreateXml { 15 16 public static void main(String[] args) { 17 //创建SAXTransformerFactory实例 18 SAXTransformerFactory factory = (SAXTransformerFactory) SAXTransformerFactory.newInstance(); 19 try { 20 //创建TransformerHandler实例 21 TransformerHandler handler = factory.newTransformerHandler(); 22 //创建Transformer实例 23 Transformer transformer = handler.getTransformer(); 24 //设置输出的xml属性,encoding为编码, 25 transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8"); 26 //indent是确保输出的xml文件能够自动换行 27 transformer.setOutputProperty(OutputKeys.INDENT, "yes"); 28 29 //创建Result对象,将Result对象加载到TransHandler中 30 // 注意:1、这一步必须在Transformer.setOutputProperty()之后,不然设置的xml属性将不生效 31 // 2、这一步也必须在TransformerHandler.startDocument()之前,不然会报错。 32 // 分析源码后发现,startDocument()会先判断result是否为空,为空则报错 33 Result result = new StreamResult("src/test-sax-create.xml"); 34 handler.setResult(result); 35 36 // 创建属性Attribute对象 37 AttributesImpl attr = new AttributesImpl(); 38 //开始写文件 39 handler.startDocument(); 40 //写入根节点conpany 41 handler.startElement("", "", "conpany", attr); 42 43 //清空属性, 44 attr.clear(); 45 //设置属性 46 attr.addAttribute( "", "", "name", "", "1"); 47 //写入根节点的子节点book 48 handler.startElement("", "", "department", attr); 49 50 attr.clear(); 51 //分别写入book节点的子节点 52 attr.addAttribute( "", "", "name", "", "employee1"); 53 attr.addAttribute( "", "", "id", "", "1"); 54 handler.startElement("", "", "employee", attr); 55 //写入子节点内容 56 handler.characters("123".toCharArray(), 0, "123".toCharArray().length); 57 //写入子节点末尾 58 handler.endElement("", "", "employee"); 59 //写入department节点末尾 60 handler.endElement("", "", "department"); 61 //写入根节点末尾 62 handler.endElement("", "", "conpany"); 63 //写文件结束 64 handler.endDocument(); 65 } catch (TransformerConfigurationException e) { 66 e.printStackTrace(); 67 } catch (SAXException e) { 68 e.printStackTrace(); 69 } 70 } 71 }
生成文件如下:
XML解析
代码如下:
1 package com.test.sax; 2 3 import java.io.IOException; 4 import java.util.ArrayList; 5 import java.util.HashMap; 6 import java.util.List; 7 import java.util.Map; 8 9 import javax.xml.parsers.ParserConfigurationException; 10 import javax.xml.parsers.SAXParser; 11 import javax.xml.parsers.SAXParserFactory; 12 13 import org.xml.sax.Attributes; 14 import org.xml.sax.SAXException; 15 import org.xml.sax.helpers.DefaultHandler; 16 17 18 public class TestParseXml { 19 20 public static void main(String[] args) throws SAXException, IOException, ParserConfigurationException { 21 //创建SAXTransformerFactory实例 22 SAXParserFactory saxParserFactory = SAXParserFactory.newInstance(); 23 //创建TransformerHandler实例 24 SAXParser saxParser = saxParserFactory.newSAXParser(); 25 26 MyHandler myHandler = new MyHandler(); 27 28 saxParser.parse(TestParseXml.class.getClassLoader().getResourceAsStream("test.xml"), myHandler); 29 } 30 31 } 32 33 34 class MyHandler extends DefaultHandler{ 35 36 /** 37 * 开始解析文档时,调用的方法 38 */ 39 @Override 40 public void startDocument() throws SAXException { 41 System.out.println("---------startDocument-------"); 42 } 43 44 /** 45 * 文档解析完结时,调用的方法 46 */ 47 @Override 48 public void endDocument() throws SAXException { 49 System.out.println("---------endDocument-------"); 50 super.endDocument(); 51 } 52 53 /** 54 * 开始解析每个元素时,调用的方法,会重复调用 55 */ 56 @Override 57 public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { 58 59 //qName 元素标签 60 System.out.println("---------startElement-------" + qName); 61 62 // 处理属性 63 if(attributes != null ) 64 { 65 for (int i = 0; i < attributes.getLength(); ++i) 66 { 67 String attrName = attributes.getQName(i); 68 String attrValue = attributes.getValue(i); 69 System.out.print("\t "+ attrName + "=" + attrValue); 70 } 71 } 72 System.out.println(""); 73 } 74 75 @Override 76 public void endElement(String uri, String localName, String qName) throws SAXException { 77 78 System.out.println("---------endElement-------" + qName); 79 } 80 81 /** 82 * 解析到每个元素的内容时会调用此方法 83 */ 84 @Override 85 public void characters(char[] ch, int start, int length) throws SAXException { 86 String content = new String(ch,start,length); 87 System.out.println("---------characters-------" + "content == "+ content); 88 } 89 }
控制台输出:
1 ---------startDocument------- 2 ---------startElement-------conpany 3 name=hd 4 ---------characters-------content == 5 6 ---------startElement-------department 7 name=department1 8 ---------characters-------content == 9 10 ---------startElement-------employee 11 name=employee1 id=1 12 ---------characters-------content == 123 13 ---------endElement-------employee 14 ---------characters-------content == 15 16 ---------endElement-------department 17 ---------characters-------content == 18 19 ---------startElement-------department 20 name=department2 21 ---------characters-------content == 22 23 ---------startElement-------employee 24 name=employee2 id=2 25 ---------characters-------content == 321 26 ---------endElement-------employee 27 ---------characters-------content == 28 29 ---------startElement-------employee 30 name=employee3 id=3 31 ---------endElement-------employee 32 ---------characters-------content == 33 34 ---------endElement-------department 35 ---------characters-------content == 36 37 ---------startElement-------department 38 name=department3 39 ---------characters-------content == 40 41 ---------endElement-------department 42 ---------characters-------content == 43 44 ---------endElement-------conpany 45 ---------endDocument-------
Simple API for XML