加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

SAX解析XML

发布时间:2020-12-16 05:59:12 所属栏目:百科 来源:网络整理
导读:SAX解析XML: SAX基本原理: 采用事件驱动解析XML文件,以流式方式逐行的去读,它不需要解析完整个文档,在按内容顺序解析文档的过各中,SAX会判断当前讲到的字符是否合法XML语法中的某部分,如果符合就触发事件(例如startDocument()、endDocument()诸如此

SAX解析XML:

SAX基本原理:

采用事件驱动解析XML文件,以流式方式逐行的去读,它不需要解析完整个文档,在按内容顺序解析文档的过各中,SAX会判断当前讲到的字符是否合法XML语法中的某部分,如果符合就触发事件(例如startDocument()、endDocument()诸如此类的事件),它的特点是不会记录前面所碰到的标签,并且它是一个解析速度快并且占用内存少的XML解析器,

SAX解析步骤:

1、从SAXPraserFactory中创建一个新的实例

2、再从SAXParserFactory里得到一个新的SAX解析器对象SAXParser

3、再调用SAXParser对象的.parse()方法里面带两个参数一个是输入流一个是DefaultHandler对象这样就可以了。而DefaultHandler是实现了ContentHandler接口的。ContentHandler接口中定义了一系列的方法事件:诸如:

[java] view plain copy print ?
  1. publicabstractvoidstartDocument()


方法作用:文档解析触发此事件

?
    publicabstractvoidendDocument()


方法作用:文档解析结束时触发此事件

?
    publicabstractvoidstartElement(Stringuri,StringlocalName,StringqName,Attributesatts)


方法作用:当开始读取元素时触发此事件

参数说明:

uri:命名空间

localName:不带命名空间的前缀的标签名

qName:不定期命名空间前缀的标签名

atts:得到所有的属性各和相应的值

?
    publicabstractvoidendElement(Stringuri,StringqName)


方法作用:读取的标签结束时触发此事件,参数说明同上

?
    publicabstractvoidcharacters(char[]ch,intstart,intlength)


方法作用:用来处理在XML文件中读到的内容

参数说明:

ch:用于存放文件的内容

start:所读到的字符串在这个数组中的起始位置

length:长度

我们可以用new String(ch,start,length)来获取内容

下面以person.xml文件为例采用SAX解析器来模拟解析这个XML文档:

[html] ?
    <?xmlversion="1.0"encoding="UTF-8"?>
  1. <persons>
  2. <personid="23">
  3. <name>李明</name>
  4. <age>30</age>
  5. </person>
  6. <personid="20">
  7. <name>李向梅</name>
  8. <age>25</age>
  9. </persons>


解析person.xml触发的事件为:

读到的标签及内容

触发事件

{文档开始}

startDocument()

<persons>

startElement(,"persons",null,"{Attributes}")

"nt"

characters("<persons>...</persons>","12","2")

<person>

startElement(,"person","{Attributes}")

"ntt"

characters("<persons>...</persons>","31","3")

<name>

startElement(,"name","{Attributes}")

"李明"

characters("<persons>...</persons>","40","2")

</name>

endElement("",null)

"ntt"

characters("<persons>...</persons>","50","3")

<age>

startElement(,"age","{Attributes}")

"30"

characters("<persons>...</persons>","58","2")

</age>

endElement("",null)

"nt"

characters("<persons>...</persons>","67","2")

</person>

endElement("","79","2")

又重复<person>

….

{文档结束}

endDocument()

实例1:读取XML文件里的内容把这些内容构造成一个Person对象,然后读取这个XML文档里内容将其Person对象添加到一个List集合里:

Person类:

?
    publicclassPerson{
  1. privateIntegerid;
  2. privateStringname;
  3. privateshortage;
  4. publicIntegergetId(){
  5. returnid;
  6. }
  7. publicvoidsetId(Integerid){
  8. this.id=id;
  9. publicStringgetName(){
  10. returnname;
  11. publicvoidsetName(Stringname){
  12. this.name=name;
  13. publicshortgetAge(){
  14. returnage;
  15. publicvoidsetAge(shortage){
  16. this.age=age;
  17. @Override
  18. publicStringtoString(){
  19. return"Person[age="+age+",id="+id+",name="+name+"]";
  20. }


业务bean:

?
    publicclassSAXPersonService{
  1. publicstaticList<Person>readXml(InputStreaminputStream)
  2. throwsException{
  3. //得到一个SAXParserFactory对象
  4. SAXParserFactoryspf=SAXParserFactory.newInstance();
  5. //SAX解析对象
  6. SAXParsersaxParser=spf.newSAXParser();
  7. //ContentHandler对象
  8. XMLContentHandlerhandler=newXMLContentHandler();
  9. //开始解析
  10. saxParser.parse(inputStream,handler);
  11. //关闭流
  12. inputStream.close();
  13. returnhandler.getPersons();
  14. }


XMLContentHandler继承自DefalutHander而DefaultHandler实现ContentHandler接口

?
    /**
  1. *继承于DefaultHandler这个类也是实现ContentHandler
  2. *@authorAdministrator
  3. *
  4. */
  5. publicclassXMLContentHandlerextendsDefaultHandler{
  6. privateList<Person>persons;
  7. privatePersonperson;
  8. privateStringpreTag;//当前标记
  9. publicList<Person>getPersons(){
  10. returnpersons;
  11. *文档开始
  12. publicvoidstartDocument()throwsSAXException{
  13. persons=newArrayList<Person>();
  14. *读取的文档内容
  15. publicvoidcharacters(char[]ch,intlength)
  16. throwsSAXException{
  17. if(person!=null){
  18. Stringdata=newString(ch,length);
  19. //判断前面的元素是否是"name"
  20. if("name".equals(preTag)){
  21. person.setName(data);
  22. }elseif("age".equals(preTag)){
  23. person.setAge(newShort(data));
  24. *元素开始
  25. publicvoidstartElement(Stringuri,
  26. Attributesattributes)throwsSAXException{
  27. //判断目前解析到的元素是否等于"person"
  28. if("person".equals(localName)){
  29. person=newPerson();
  30. //person.setId(Integer.parseInt(attributes.getValue(0)));
  31. person.setId(Integer.parseInt(attributes.getValue("","id")));
  32. //当前元素
  33. preTag=localName;
  34. *解析完一个元素后就把这个元素加到List里
  35. publicvoidendElement(Stringuri,StringqName)
  36. if("person".equals(localName)&&person!=null){
  37. persons.add(person);
  38. person=null;
  39. //再将这个当前元素设为null
  40. preTag=null;
  41. }


测试:

?
    publicclassSAXPersonServiceTestextendsAndroidTestCase{
  1. privatestaticfinalStringTAG="LogTest";
  2. publicvoidtestSAXReadXml()throwsException{
  3. //从资源文件中获取输入流
  4. InputStreaminputStream=SAXPersonServiceTest.class.getClassLoader()
  5. .getResourceAsStream("itcast.xml");
  6. List<Person>list=SAXPersonService.readXml(inputStream);
  7. for(Personperson:list){
  8. System.out.println(person);
  9. 如需转载引用请注明出处:<ahref="http://blog.csdn.net/jiahui524">http://blog.csdn.net/jiahui524</a>
?

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读