第7章  SAX解析XML

  通过上一章的学习,我们知道基于DOM的解析器的核心是在内存中建立和XML文档相对应的树性树状结构,XML文件的标记、标记中的文本数据、实体等都会和内存中树状结构的某个节点相对应。使用DOM解析器的好处是,可以方便的操作内存中的树的节点来处理XML文档,获取自己所需要的数据。但DOM解析的不足之处在于,如果XML文件较大,或者只需要解析XML文档一部分数据,此时就会占有大量的内存空间。和DOM解析不同的是,SAX解析器不在内存中建立和XML文件相对应的树状结构数据,SAX解析器的核心是事件处理机制,具有占有内存少、效率高等特点。

本章知识要点:
掌握SAX概念和特点
熟练掌握SAX的工作机制
了解SAX常用接口
熟练掌握SAX解析XML文档的步骤
熟练掌握解析器和事件处理器的创建和使用
熟练掌握SAX处理各种应用
掌握SAX和DOM共同构建XML文档

7.1  SAX概述

  高效地解析XML数据非常重要,尤其是对于那些要处理大量数据的应用程序,这种技术尤为重要。不正确的解析会导致过度的内存消耗和过长的处理时间,从而有损于可伸缩性。SAX就是其中一种,并以快速高效解析大量XML文档而著称。

7.1.1  SAX介绍

  用于读取和操作XML文件的标准是文档对象模型(Document Object Model,DOM)。遗憾的是,DOM方法涉及读取整个文件并将该文件存储在一个树结构中,而这样可能是低效的、缓慢的,并且很消耗资源。一种替代技术就是Simple API for XML,或称为SAX,翻译过来的意思是简易应用程序编写接口。SAX允许在读取文档时处理它,从而不必等待整个文档被存储之后才采取操作。

7.1.2  工作机制

  SAX在概念上与DOM完全不同。首先,不同于DOM的文档驱动,它是事件驱动的,也就是说,它并不需要读入整个文档,而文档的读入过程也就是SAX的解析过程。所谓事件驱动,是指一种基于回调(callback)机制的程序运行方法。我们也可以把它称为授权事件模型。
SAX解析器装载XML文件时,它遍历XML文档并在其主机应用程序中产生事件(经由回调函数、指派函数或者任何可调用平台完成这一功能)表示这一过程。这样,编写SAX应用程序就如同采用最现代的工具箱编写GUI事件程序。

7.1.3  常用接口

  SAX是一个接口,一套API,在SAX接口里声明了处理XML文档的时候需要的方法。利用SAX编写的程序,可以快速的对数据进行操作。SAX接口中常用的接口如下所示:
Attributes接口
ContentHandler接口
DTDHandler接口
EntityResolver接口
XMLReader接口
SAX错误处理程序的基本接口

7.1.4  SAX解析器创建及使用

  SAX接口提供了解析XML文件的API,基于SAX接口的解析器这里我们称作SAX解析器。和DOM解析不同的是,SAX解析器不在内存中建立和XML文件相对应的树状结构数据。SAX解析器的核心是事件处理机制。

7.2  SAX应用

  SAX是一种基于事件驱动的API。利用SAX解析XML文档,涉及到两个部分:解析器和事件处理器。解析器负责读取XML文档,并向事件处理器发送事件,如元素开始和元素结束。事件处理器则负责对事件做出响应,对传递的XML数据进行处理。

7.2.1  处理文件开始与结束

  当SAX解析器解析XML文档时,解析到不同的标记会触发不同的事件。当SAX解析器开始解析XML文件时,就会报告“文件开始”事件给事件处理器,此时事件处理器会调用方法startDocument()方法,然后再陆续处理并报告其他的事件,如“开始标记”、“文本事件”等,如果解析到XML文档的结束,解析器会报告“文件结束”事件,事件处理器会调用endDocument()方法。解析器在解析XML文件的过程中,只能报告一次“文件开始”事件和“文件结束”事件。如果要实现处理“文件结束”和“文件开始”事件,需要在程序的类中重写这两个继承的方法。

7.2.2  处理指令

  该处理指令使得XML文件关联到某个层叠样式表,其路径为url。当SAX解析器处理XML文件时,如果发现XML文档中的处理指令会报告一个“处理指令”事件给事件处理器,事件处理器会调用下面的方法处理。
《XML基础教程与实验指导》 第7章 SAX解析XML

7.2.3  处理开始和结束标记

  在解析器解析XML文档时,如果发现了开始标记,就会触发“开始标记”事件,并向事件处理器发送一个“开始标记”事件报告。事件处理器获得发送的事件报告信息,就会调用方法。

7.2.4  处理文本数据

  XML文件中标记的内容是文本数据,当SAX解析器解析这些数据时,就报告“文本数据”事件给事件处理器,事件处理器获取事件信息后,就会调用下面的方法:
public void characters(char[] ch,int start,int length)throws SAXException

7.2.5  处理空白

  人们习惯上称标记之间的缩进区域是可忽略空白,这实际上不是很准确,应为XML文件的标记可以有文本和子标记,在这种情况下,标记之间的区域就可能包含非空白的字符内容(混合内容)。如果我们不允许标记有混合内容,即标记要么只包含有子标记要么只包含有文本数据,在这种情形下,称标记之间缩进区域是可忽略空白就比较恰当,这些空白区使得XML文件看起来更加美观,是没有价值的文本数据。

7.2.6  处理名称空间

  在XML文档中,名称空间主要是有效的区分名字相同的标记。当使用两个标记的名字相同时,它们可以通过隶属不同的名称空间来相互区分。名称空间通过声明名称空间来建立,分为有前缀的名称空间和无前缀的名称空间。

7.2.7  处理实体

  在XML文档中,利用DTD可以定义实体,然后与该DTD文件关联的XML文件可以通过实体引用使用该实体。实体又分为内部实体和外部实体,所谓内部实体就是实体的内容包含在DTD文件本身中;而外部实体是指实体的内容是DTD文件以外的其他文件。

7.2.8  SAX应用程序异常

  从上面的案例中,可以看出解析在调用parese方法时,必须使用try-catch语句来捕获SAXException异常,当SAXException异常发生时,parse方法会离开结束执行,停止解析过程。实际上,DefaultHandler类中的方法都可以抛出一个SAXException对象给解析器,比如,事件处理在调用startDocument()方法时,突然决定终止解析文件,就可以抛出一个SAXException对象给解析器,解析器将停止parse方法的执行。

7.3  SAX与DOM接口比较

  基于DOM接口的解析器,解析XML文档时,会将XML文档以树模型的方式加载到内存中。此时应用程序可以对树模型的任一个部分进行遍历和操作,通过DOM的树模型可以实现对XML文档的随机访问。这种访问方式给应用程序的开发带来了很大的灵活性,它可以任意地控制整个XML文档中的内容。然而,由于DOM解析器把整个XML文档转化成DOM树放在了内存中,因此,当XML文档比较大或者文档结构比较复杂时,对内存的需求就比较高。而且,对于结构复杂的树的遍历也是一项比较耗时的操作。所以,DOM解析器对机器性能的要求比较高,实现效率不十分理想。不过,由于DOM解析器的树结构的思想与XML文档的结构相吻合,所以通过DOM树机制很容易实现随机访问。

 

;
        }
}
>
);
        }
     }
>
data);
      }
}
>
str);
        }
}
>
count);
        }
}
>
>
);
         
        }
}

);
       }
}

>
); 
        }
}
学习雷锋好榜样

{System.out.println(text);}
          
       }
}
>

               }
        }
  }
>
);   
        }
}

);
       }
}
 String(ch,start,length);
          System.out.println(text.trim());
        }
}
>
;
            }
        }
}
yuansum);
        }
}
>
>

相关文章:

  • 2022-12-23
  • 2021-11-30
  • 2022-02-12
  • 2021-05-20
  • 2021-05-22
  • 2022-02-20
  • 2022-12-23
  • 2022-12-23
猜你喜欢
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
相关资源
相似解决方案