2.sax技术可以在不加载全部 xml 文件时,就可以解析xml文档,看一个原理图: 3
2. Java用SAX解析代码:(有去读指定元素的方法,还有不取出空格的方法) 4
Java解析XML文档DOM入门案例
² 面试题: 如何设置JVM运行内存的大小?
题目: 请问,执行以下代码会出现什么问题? byte[] bytes = new byte[1024*1024*1000] ; bytes[0] = 0; System.out.println(bytes[0]); 答: 会出现JVM内存溢出的问题,因为在 JDK5.0 的JVM默认内存是64M,而题目给出的代码占了1000M的内存,所以出现内存溢出 , 如果要运行这段代码,我们需要手动的设置 JVM内存, 设置方法: 1. 在eclipse中 在你要执行的那个项目右键->属性->Run/Debug setting ->选择你的主函数名 ->Edit ->arguments ->VMargument ->添加 -Xmx???m (???的大小自己设置)
2. 在CMD命令行中 Java -Xmx1000m HelloWorld(类名)
|
1.为什么会出现sax技术
因为dom技术,会把整个xml文件加载到内存中,这样如果 xml过大,则可能会出现内存溢出. |
2.sax技术可以在不加载全部 xml 文件时,就可以解析xml文档,看一个原理图:
|
² SAX的优缺点(读取方便,不能增删改)
优点: SAX解析XML文档,遍历(读取)有很大的优势,不用担心读取比较大的XML文档会内存溢出(DOM解析的缺点), 缺点: 无法进行增删改 /* * 优点: 遍历(读取)方便,解析的文档大一点也没事,但是DOM解析文档要是大就会出现内存溢出 * 缺点:只能遍历(读取),无法进行增删改 * ============================================================ * SAX解析的时候,是按照XML文档一行一行进行解析的,至于这么执行监听器,这个和图形化界面的监听器原理差不多 * 函数有5个 * 1. startDocument(); 开始读取文档 * 2. startElement(); 开始读取元素 * 3. character(); 读取文本 * 4. endElement();元素结束 * 5. endDocument();文档结束 * */
|
² SAX解析XML文档的入门案例
1. XML文档:
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <class> <stu score="80"> <name>小红</name> <sex>女</sex> <age>20</age> </stu> <stu id="s11302"> <name>小明</name> <sex>男</sex> <age>20</age> </stu> </class> |
2. Java用SAX解析代码:(有去读指定元素的方法,还有不取出空格的方法)
package com.zx.SAX;
import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; import org.xml.sax.Attributes; import org.xml.sax.SAXException; import org.xml.sax.helpers.DefaultHandler;
public class Test {
//使用SAX解析XML文档 /* * 优点: 遍历(读取)方便,解析的文档大一点也没事,但是DOM解析文档要是大就会出现内存溢出 * 缺点:只能遍历(读取),无法进行增删改 * ============================================================ * SAX解析的时候,是按照XML文档一行一行进行解析的,至于这么执行监听器,这个和图形化界面的监听器原理差不多 * 函数有5个 * 1. startDocument(); 开始读取文档 * 2. startElement(); 开始读取元素 * 3. character(); 读取文本 * 4. endElement();元素结束 * 5. endDocument();文档结束 * */ public static void main(String[] args) throws Exception { //创建一个SAX解析器工厂对象 SAXParserFactory spf = SAXParserFactory.newInstance(); //创建一个SAX解析器 SAXParser sp = spf.newSAXParser(); //解析文档和关联事件监听类 //sp.parse("src/classes2.xml", new MyDefaultHandler()); sp.parse("src/classes2.xml", new MyDefaultHandler2()); //解析的时候,解析器会自动调用事件监听的函数 }
}
//------------------------------------
//事件监听器2 (如何只读取姓名和年龄) class MyDefaultHandler2 extends DefaultHandler{ private boolean isName = false; private boolean isAge = false; @Override public void startDocument() throws SAXException { // TODO Auto-generated method stub super.startDocument(); }
@Override public void endDocument() throws SAXException { // TODO Auto-generated method stub super.endDocument(); }
//判断是否是Name或Age @Override public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { //如果为姓名或是年龄就修改isName和isAge的值 if(qName.equals("name")){ isName = true; }else if(qName.equals("age")){ isAge = true; } }
@Override public void endElement(String uri, String localName, String qName) throws SAXException { // TODO Auto-generated method stub super.endElement(uri, localName, qName); } //判断一下是否为Name或Age在取出 @Override public void characters(char[] ch, int start, int length) throws SAXException { String str = new String(ch,start,length); if (!str.trim().equals("") && (isAge ||isName)) { System.out.println(str); } isName = false; isAge = false; } } //------------------------------------------- //事件监听类 class MyDefaultHandler extends DefaultHandler{
//开始读取文档(读取一个XML文档只执行一次) @Override public void startDocument() throws SAXException { // TODO Auto-generated method stub System.out.println("startDocument()"); } //文档结束(读取一个XML文档只执行一次) @Override public void endDocument() throws SAXException { // TODO Auto-generated method stub System.out.println("endDocument()"); }
//开始读取元素 <xxx> @Override public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { System.out.print(qName+" :"); }
//元素结束 </xxx> @Override public void endElement(String uri, String localName, String qName) throws SAXException { } //读取文本 <> xxx </> @Override public void characters(char[] ch, int start, int length) throws SAXException { String str = new String(ch,start,length); //这里注意要用trim()这个去除空格的函数,不然又空格存在,空格的行也会输出 //作用:不取出为空的行 if (!str.trim().equals("")) { System.out.println(str); } } }
|
3. 结果截图
|
² SAX读取XML文档案例2
1. XML文档
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <students> <student sid="002"> <name>小李</name> <course> <java>9</java> <oracle>70</oracle> <vb>8</vb> </course> </student> <student sid="003"> <name>小韩</name> <course> <java>90</java> <oracle>70</oracle> <vb>85</vb> </course> </student> <student sid="004"> <name>小明名</name> <course> <java>34</java> <oracle>50</oracle> <vb>58</vb> </course> </student> <student sid="005"> <name>小红</name> <course> <java>29</java> <oracle>39</oracle> <vb>88</vb> </course> </student> </students> |
2. 用SAX解析XML的代码
主函数和服务类
import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; import org.xml.sax.Attributes; import org.xml.sax.SAXException; import org.xml.sax.helpers.DefaultHandler;
public class ParseBySAX { public static void main(String[] args) throws Exception { StudentService studentService = new StudentService(); studentService.parseXMLBySAX("src/student.xml", new MyDefaultHandler()); } }
class StudentService { //通过SAX解析XML文档 public void parseXMLBySAX(String fullFilePath,DefaultHandler defaultHandler) throws Exception{ //创建SAX解析器工厂 SAXParserFactory saxParserFactory = SAXParserFactory.newInstance(); //创建SAX解析器 SAXParser saxParser = saxParserFactory.newSAXParser(); //解析XML文档 saxParser.parse(fullFilePath,defaultHandler); } } |
事件监听类
//SAX事件监听类 class MyDefaultHandler extends DefaultHandler{
@Override public void startDocument() throws SAXException { // TODO Auto-generated method stub }
@Override public void endDocument() throws SAXException { // TODO Auto-generated method stub }
@Override public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { //如果遇到student节点就输出属性,如果遇到姓名或成绩就输出并且记录是否为姓名或成绩 if(qName.equals("student")){ System.out.print("sid:\t"+ attributes.getValue("sid")+"\t"); }else if(qName.equals("name")){ isName = true; System.out.print(qName+":\t"); }else if (qName.equals("java")) { isJava = true; System.out.print(qName+":\t"); }else if (qName.equals("oracle")) { isOracle = true; System.out.print(qName+":\t"); }else if(qName.equals("vb")){ isVb = true; System.out.print(qName+":\t"); } }
@Override public void endElement(String uri, String localName, String qName) throws SAXException { //如果读取一个学生结束,就换行 if(qName.equals("student")){ System.out.println(); } }
@Override public void characters(char[] ch, int start, int length) throws SAXException { String value = new String(ch,start,length); //如果节点为姓名,或成绩就输出 if(!value.trim().equals("")&&(isName||isJava||isOracle||isVb)){ System.out.print(value+"\t"); } isName = false; isJava = false; isOracle = false; isVb = false; } private boolean isName; private boolean isJava; private boolean isOracle; private boolean isVb; } |
3. 结果截图
|