原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 、作者信息和本人声明。否则将追究法律责任。
作者: 永恒の_☆ 地址:http://blog.csdn.net/chenghui0317/article/details/11990891
一、前言
SAX操作xml是基于事件来完成的,自己只负责调用解析的方法,然后具体解析操作都是交给DefaultHandler处理者来完成的,总的来说使用SAX解析和生成xml文档还是比较方便的 。
二、准备条件
因为SAX是jdk自带的解析方式,所以不用添加jar包引用。
三、使用SAX实战
1、解析xml文档
实现思路:
<1>先由SAXParserFactory这个工厂的实例生产一个SAXParser解析器;
<2>然后根据读取的xml路径,传递给SAXParser这个解析器,再调用parse()方法;
<3>在parse()方法中需要传递DefaultHandler这个类的扩展类的实例,因为它才会真正去一步步去解析xml文档的;
<4>在DefaultHandler扩展类中需要重写startDocument(),endDocument()等等方法,因为他们方法内部有返回的具体文档的结果。
具体代码如下:
import java.io.BufferedOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; import java.util.List; import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; import javax.xml.transform.OutputKeys; import javax.xml.transform.Result; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerConfigurationException; import javax.xml.transform.sax.SAXTransformerFactory; import javax.xml.transform.sax.TransformerHandler; import javax.xml.transform.stream.StreamResult; import org.xml.sax.Attributes; import org.xml.sax.InputSource; import org.xml.sax.SAXException; import org.xml.sax.helpers.AttributesImpl; import org.xml.sax.helpers.DefaultHandler; /** * 使用SAX操作xml的简单例子 * @author Administrator * */ public class SAXOperateXmlDemo { public void parseXml01(){ String xmlPath = "D:\\project\\dynamicWeb\\src\\resource\\user01.xml"; String xmlName = xmlPath.substring(xmlPath.lastIndexOf("\\")); try { //获取SAX分析器的工厂实例,专门负责创建SAXParser分析器 SAXParserFactory saxParserFactory = SAXParserFactory.newInstance(); //获取SAXParser分析器的实例 SAXParser saxParser = saxParserFactory.newSAXParser(); //和其他解析方式一样,也要间接通过InputStream输入流对象获取xml信息 //1、直接指定绝对路径获取文件输入流对象 //InputStream inputStream = new FileInputStream(xmlPath); //2、使用类的相对路径查找xml路径 //InputStream inputStream = this.getClass().getResourceAsStream(xmlName); //3、也可以指定路径完成InputStream输入流的实例化操作 InputStream inputStream = new FileInputStream(new File(xmlPath)); //4、使用InputSource输入源作为参数也可以转换xml //InputSource inputSource = new InputSource(inputStream); //解析xml文档 saxParser.parse(inputStream, new XmlSAXHandler01());//这里传递了自定义的XmlSAXHandler()管理者参数来解析xml,不像以前都是直接调用返回的Document对象 } catch (ParserConfigurationException e) { e.printStackTrace(); } catch (SAXException e) { e.printStackTrace(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } public static void main(String[] args) { SAXOperateXmlDemo demo = new SAXOperateXmlDemo(); demo.parseXml01(); } } /** * 解析SAX的处理者01 * @author Administrator * */ class XmlSAXHandler01 extends DefaultHandler { @Override public void startDocument() throws SAXException { System.out.println("---->startDocument() is invoked..."); super.startDocument(); } @Override public void endDocument() throws SAXException { System.out.println("---->endDocument() is invoked..."); super.endDocument(); } @Override public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { System.out.println("-------->startElement() is invoked..."); super.startElement(uri, localName, qName, attributes); } @Override public void endElement(String uri, String localName, String qName) throws SAXException { System.out.println("-------->endElement() is invoked..."); super.endElement(uri, localName, qName); } @Override public void characters(char[] ch, int start, int length) throws SAXException { System.out.println("------------>characters() is invoked..."); super.characters(ch, start, length); } }
上面代码简单解析了一个xml,user01.xml文件的内容如下:
<?xml version="1.0" encoding="utf-8" ?>
<Root>Content</Root>
接下来执行该类的main方法根据控制台的显示可知:
<1>解析类必须继承DefaultHandler这个类,重写自己需要获取节点信息的方法,不重写的情况下会调用父类的对应方法,所以不影响程序;
<2>XmlSAXHandler01这个处理者来完成xml的解析工作,并且调用方式是按照xml层级关系来处理的,比如最开始调用startDocument()获取Document对象,然后再递归调用startElement()获取根节点以及子节点的信息,其中的characters()用于获取节点文本内容信息,待节点解析完毕之后会调用endElement(),同样整个xml解析完毕之后会调用endDocument()结束。
上面只是简单的获取了xml的根目录的元素,接下来使用DefaultHandler这个处理者怎么获取节点内的信息。
具体代码如下:
public void parseXml02(){
String xmlPath = "D:\\project\\dynamicWeb\\src\\resource\\user02.xml";
try {
//获取SAX分析器的工厂实例,专门负责创建SAXParser分析器
SAXParserFactory saxParserFactory = SAXParserFactory.newInstance();
//获取SAXParser分析器的实例
SAXParser saxParser = saxParserFactory.newSAXParser();
InputStream inputStream = new FileInputStream(new File(xmlPath));
//解析xml文档
saxParser.parse(inputStream, new XmlSAXHandler02());
} catch (ParserConfigurationException e) {
e.printStackTrace();
} catch (SAXException e) {
e.printStackTrace();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
对应的XMLSAXHandler02的代码如下:
/**
* 解析SAX的处理者02
* @author Administrator
*
*/
class XmlSAXHandler02 extends DefaultHandler {
@Override
public void startDocument() throws SAXException {
System.out.println("---->startDocument() is invoked...");
}
@Override
public void endDocument() throws SAXException {
System.out.println("---->endDocument() is invoked...");
}
@Override
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
System.out.println("-------->startElement() is invoked...");
System.out.println("uri的属性值:" + uri);
System.out.println("localName的属性值:" + localName);
System.out.println("qName的属性值:" + qName);
if(attributes.getLength()>0){
System.out.println("element属性值-->" + attributes.getQName(0) + ":" + attributes.getValue(0)); //根据下标获取属性name和value,也可以直接传递属性name获取属性值:attributes.getValue("id")
}
}
@Override
public void endElement(String uri, String localName, String qName) throws SAXException {
System.out.println("-------->endElement() is invoked...");
System.out.println("uri的属性值:" + uri);
System.out.println("localName的属性值:" + localName);
System.out.println("qName的属性值:" + qName);
}
@Override
public void characters(char[] ch, int start, int length) throws SAXException {
System.out.println("------------>characters() is invoked...");
System.out.println("节点元素文本内容:" + new String(ch, start, length));
}
}
上面的xml在src下面,user02.xml具体如下:
<?xml version="1.0" encoding="utf-8" ?>
<Root>
这个是根节点的内容
<user id="001">用户信息</user>
</Root>
接下来执行该类的main方法,
根据控制台的显示可知:
<1>XMLSAXHandler02在解析的时候执行方法是从最外层往内、从上往下依次解析的,并且每一次解析节点都是startElement()和endElement()成对出现的;
<2>图中显示了每一个节点解析的信息,并且startElement()和endElement()的区别在于前面方法有携带属性,而后面方法没有;
<3>图中之所以出现三个“节点元素文本内容”是XMLSAXHandler02也是把非标签的文本当前一个节点了,所以在解析的时候要排除这种情况,以免影响最终想要的结果。
另外发现:
<1>查看父类的方法发现它们的方法体什么都没做;
<2>SAX不支持重新修改XML的结构;
<3>如果正常业务需求,解析xml之后不可能只是简单输出下内容,而是要返回成一个集合或者其他形式返回,目前情况可以使用全局的ArrayList集合来完成解析之后节点内容的封装。
接下来需要实现如何封装SAX解析完毕的XML文档,都知道java是面向对象编程的,那么这个时候可以把文档中的每一个节点都看成一个对象,包括节点里面的属性也是一样,那么在解析XML的时候直接使用javabean封装一下,思路就非常清晰了,但是现在还有还一个问题: 如何在SAXParser调用parse()方法之后返回最终的结果集呢?就目前肯定不行的,其一方法没有返回值,其二解析操作完全交给DefaultHandler去做了,所以这种情况下肯定不能使用普通变量或者全局变量,因为使用了之后会随着当前操作类的实例化生命周期而存在,并且DefaultHandler在调用的时候又需要产生一个新的实例,这样前后就没有关联性了。 所以只能使用静态ArrayList来完成了。
具体操作如下:
1、前面说了构建节点对象和属性对象,具体代码如下:
import java.util.List; /** * Xml节点对象 * @author Administrator * */ public class Node { private Long id; private String name; private String text; private List<Attribute> attributeList; private List<Node> nodeList; public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getText() { return text; } public void setText(String text) { this.text = text; } public List<Attribute> getAttributeList() { return attributeList; } public void setAttributeList(List<Attribute> attributeList) { this.attributeList = attributeList; } public List<Node> getNodeList() { return nodeList; } public void setNodeList(List<Node> nodeList) { this.nodeList = nodeList; } }
/**
* Xml属性对象
* @author Administrator
*
*/
public class Attribute {
private String name;
private String value;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}
2、在SAXOperateXmlDemo这个操作类中添加两个常量,具体如下:
public static List<Node> nodeList = null;
public static Node node = null;
不光集合需要全局静态化,节点对象也要全局静态化,因为解析过程中获取标签名称和标签内文本是分开操作的,如果不这样对象的属性值无法完整获取。
3、定义xml文档解析方法,具体如下:
public void parseXml03(){
String xmlPath = "D:\\project\\dynamicWeb\\src\\resource\\user03.xml";
try {
//获取SAX分析器的工厂实例,专门负责创建SAXParser分析器
SAXParserFactory saxParserFactory = SAXParserFactory.newInstance();
//获取SAXParser分析器的实例
SAXParser saxParser = saxParserFactory.newSAXParser();
InputStream inputStream = new FileInputStream(new File(xmlPath));
//解析xml文档
saxParser.parse(inputStream, new XmlSAXHandler03());
//迭代list
if(SAXOperateXmlDemo.nodeList.size() > 0){
for (Node node : SAXOperateXmlDemo.nodeList) {
System.out.println("-----------------------------------------");
System.out.println("【节点】" + node.getName() + ":" + node.getText());
List<Attribute> attributeList = node.getAttributeList();
if (attributeList != null) {
for (Attribute attribute : attributeList) {
System.out.println("【属性】" + attribute.getName() + ":" + attribute.getValue());
}
}
}
}
} catch (ParserConfigurationException e) {
e.printStackTrace();
} catch (SAXException e) {
e.printStackTrace();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
4、对应的解析处理者代码如下:
/**
* 解析SAX的处理者03
* @author Administrator
*
*/
class XmlSAXHandler03 extends DefaultHandler {
@Override
public void startDocument() throws SAXException {
SAXOperateXmlDemo.nodeList = new ArrayList<Node>();
}
@Override
public void endDocument() throws SAXException {
}
@Override
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
SAXOperateXmlDemo.node = new Node();
SAXOperateXmlDemo.node.setId(null);
SAXOperateXmlDemo.node.setName(qName);
//封装当前节点的属性
List<Attribute> attributeList = new ArrayList<Attribute>();
if(attributes.getLength()>0){
for (int i = 0; i < attributes.getLength(); i++) {
Attribute attribute = new Attribute();
attribute.setName(attributes.getQName(i));
attribute.setValue(attributes.getValue(i));
attributeList.add(attribute);
}
}
SAXOperateXmlDemo.node.setAttributeList(attributeList);
}
@Override
public void endElement(String uri, String localName, String qName) throws SAXException {
}
@Override
public void characters(char[] ch, int start, int length) throws SAXException {
if(SAXOperateXmlDemo.node != null){
SAXOperateXmlDemo.node.setText(new String(ch, start, length));
//因为startElement()在characters()的前面调用,所以必须放在后面才能把文本添加进去
SAXOperateXmlDemo.nodeList.add(SAXOperateXmlDemo.node);
SAXOperateXmlDemo.node = null;
//在这里之所以重新置为null是在解析标签的时候节点与节点之间的回车符、Tab符或者空格以及普通文本等等这些字符串也算一个节点
//如果不这样,那么解析的时候会把之前添加成功的节点内的文本给替换掉。
}
}
}
5、代码中解析的user03.xml的结构如下:
<?xml version="1.0" encoding="utf-8" ?>
<Root>
<user id="001">UserInfo_1</user>
<user id="002">UserInfo_2</user>
</Root>
接下来执行该解析xml的方法,
根据控制台的显示可知:
<1>使用全局静态变量完成完成了对Xml解析之后的封装工作,并且在输出的时候没有问题,但是需要注意的是去掉空文本节点这种特殊情况,否则会出现获取的节点内的内容为"\n\t" 等等结果;
<2>虽然功能是完成了,但是如果Xml文档中录入的不是文本,而是添加的详细的子节点呢?这样每一个节点就是一个Node对象,在查询和使用的时候非常的不方便。
所以为了避免这种情况,作出如下改动:
因为需求只需要获取User信息,那么不用每一个解析的节点都封装成一个对象,并且属性对象和节点对象可以合并,不用分太开这样不易于后期维护。
具体操作如下:
假设现在需要解析的xml文档如下:
<?xml version="1.0" encoding="utf-8" ?>
<Users>
<user id="9527">
<name>admin</name>
<age>40</age>
<hobby>manage someone!</hobby>
</user>
<user id="9632">
<name>chenghui</name>
<age>110</age>
<hobby>code something!</hobby>
</user>
</Users>
然后创建User实体类封装,具体如下:
/**
* xml节点对象
* @author Administrator
*
*/
public class User {
private Long id;
private String name;
private Long age;
private String hobby;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Long getAge() {
return age;
}
public void setAge(Long age) {
this.age = age;
}
public String getHobby() {
return hobby;
}
public void setHobby(String hobby) {
this.hobby = hobby;
}
}
解析当前xml的方法具体如下:
public void parseXml04(){
String xmlPath = "D:\\project\\dynamicWeb\\src\\resource\\user04.xml";
try {
//获取SAX分析器的工厂实例,专门负责创建SAXParser分析器
SAXParserFactory saxParserFactory = SAXParserFactory.newInstance();
//获取SAXParser分析器的实例
SAXParser saxParser = saxParserFactory.newSAXParser();
InputStream inputStream = new FileInputStream(new File(xmlPath));
//解析xml文档
saxParser.parse(inputStream, new XmlSAXHandler04());
//迭代list
if(SAXOperateXmlDemo.userList.size() > 0){
for (User user : SAXOperateXmlDemo.userList) {
System.out.println("-----------------------------------------");
System.out.println("【Id】" + user.getId());
System.out.println("【姓名】" + user.getName());
System.out.println("【年龄】" + user.getAge());
System.out.println("【爱好】" + user.getHobby());
}
}
} catch (ParserConfigurationException e) {
e.printStackTrace();
} catch (SAXException e) {
e.printStackTrace();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
并且当前解析类需要添加两个全局静态变量,具体如下:
public static List<User> userList = null;
public static User user = null;
对应的解析xml处理者代码如下:
/**
* 解析SAX的处理者04
* @author Administrator
*
*/
class XmlSAXHandler04 extends DefaultHandler {
private String currentQName; //因为startElement()才能获取到标签名称,但是标签的内容在characters()获取,而且他们的执行顺序一直是顺序的,所以可以使用currentQName来过渡一下获取上一次的标签名
@Override
public void startDocument() throws SAXException {
SAXOperateXmlDemo.userList = new ArrayList<User>();
}
@Override
public void endDocument() throws SAXException {
}
@Override
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
if(qName.equals("user")){
SAXOperateXmlDemo.user = new User(); //每次解析到user标签了才会创建user对象的实例
//添加user标签中的id属性
if(attributes.getLength() > 0){
SAXOperateXmlDemo.user.setId(Long.valueOf(attributes.getValue("id")));
}
}
this.currentQName = qName;
}
@Override
public void endElement(String uri, String localName, String qName) throws SAXException {
//需要说明的是,因为每一个非空标签都有characters(),那么无法知道user子标签循环完了
//但是可以这样,如果不考虑子标签顺序可以判断是否解析到了最后一个子标签来判断
//或者直接在user标签的endElement()中添加即可。
if(qName.equals("user")){
SAXOperateXmlDemo.userList.add(SAXOperateXmlDemo.user);
SAXOperateXmlDemo.user = null;
}
this.currentQName = null;
}
@Override
public void characters(char[] ch, int start, int length) throws SAXException {
String content = new String(ch, start, length);
//System.out.println(currentQName + ":" + content);
if(SAXOperateXmlDemo.user != null && currentQName != null){
if(currentQName.equals("name")){
SAXOperateXmlDemo.user.setName(content);
}else if(currentQName.equals("age")){
SAXOperateXmlDemo.user.setAge(Long.valueOf(content));
}else if(currentQName.equals("hobby")){
SAXOperateXmlDemo.user.setHobby(content);
}
}
}
}
直接运行该解析方法,
好了,现在满足需求了 解析自己需要的节点然后封装成集合展示出来。
2、生成xml文档
SAX能够解析xml,同样肯定能生成xml,而且使用起来也不是很复杂。
实现思路:
<1>创建保存xml的结果流对象StreamResult;
<2>然后利用SAXTransformerFactory这个工厂创建TransformerHandler这个操作者;
<3>操作这个TransformerHandler获取Transformer,利用Transformer创建节点信息;
具体代码如下:
public void buildXml01(){
try {
//创建保存xml的结果流对象
Result reultXml = new StreamResult(new FileOutputStream(new File("c:\\user.xml")));
//获取sax生产工厂对象实例
SAXTransformerFactory saxTransformerFactory = (SAXTransformerFactory) SAXTransformerFactory.newInstance();
//获取sax生产处理者对象实例
TransformerHandler transformerHandle = saxTransformerFactory.newTransformerHandler();
transformerHandle.setResult(reultXml);
//获取sax生产器
Transformer transformer = transformerHandle.getTransformer();
//transformer.setOutputProperty(OutputKeys.ENCODING,"UTF-8");//xml的编码格式
transformer.setOutputProperty(OutputKeys.INDENT,"yes");//换行
//开始封装document文档对象,这里和解析一样都是成双成对的构造标签
transformerHandle.startDocument();
AttributesImpl attrImple = new AttributesImpl();
transformerHandle.startElement("", "", "Users",attrImple);
attrImple.addAttribute("", "", "id", "string", "123");
transformerHandle.startElement("", "", "user", attrImple);
transformerHandle.characters("这个是用户的信息".toCharArray(), 0, "这个是用户的信息".length());
transformerHandle.endElement("", "", "user");
transformerHandle.endElement("", "", "Users");
//因为没有appendChild等等添加子元素的方法,sax提供的是构造在startElement()和endElement()区间内的标签为包含的节点的父节点
transformerHandle.endDocument();
System.out.println("xml文档生成成功!");
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (TransformerConfigurationException e) {
e.printStackTrace();
} catch (SAXException e) {
e.printStackTrace();
}
}
执行该生成方法,
然后看看生成的XML,结果显示达到了期望,但是有一个问题:
如果使用 transformer.setOutputProperty(OutputKeys.ENCODING,"UTF-8"); 重新指定了编码,插入的中文会变成乱码,现在没有想到解决方案。。
但是如果不指定编码 却没有问题,显示结果是上图中的默认的UTF-8。
相关推荐
1. **效率高**:SAX解析器只读取和处理当前需要的部分,不需要将整个XML文件加载到内存,尤其适合处理大型XML文档。 2. **内存消耗小**:与DOM解析器(将整个XML结构转化为内存中的树形结构)相比,SAX解析器对内存...
总的来说,Java中的SAX解析XML文档是一种高效且灵活的方式,尤其适用于处理大文件或资源有限的环境。通过创建自定义的事件处理器,我们可以精确地控制解析过程,只处理关心的数据,而忽略其他部分,从而优化性能。
在处理大型XML文件时,传统的DOM(Document Object Model)解析方式可能会遇到性能问题,因为DOM会将整个XML文档加载到内存中,对于超大文件,这可能导致内存溢出。为了解决这个问题,我们可以采用流式解析的方式,...
XML(eXtensible Markup Language)是...以上代码展示了如何使用DOM4J、DOM、JDOM和SAX解析和创建XML文件的基本方法。这些示例适合初学者了解XML处理的基础知识,随着经验的积累,可以根据实际需求选择合适的解析方式。
在Android和Java编程中,处理XML文件是常见的任务,而SAX(Simple API for XML)是一种轻量级、事件驱动的XML解析器,它以流式方式读取XML文档,只在需要时解析内容,因此非常适合处理大体积的XML文件。 SAX解析器...
SAX解析器不创建整个XML文档树,而是当遇到XML文档的各个部分(如元素、属性、文本等)时,触发相应的事件回调函数。开发者通过实现SAX解析器的ContentHandler接口,定义这些回调函数来处理这些事件。 以下是使用...
SAX解析器在读取XML文件时,会触发一系列的事件,例如开始文档、结束文档、开始元素、结束元素等。开发者需要创建一个实现了SAX解析器接口的类,即`DefaultHandler`或自定义的处理器,然后重写这些事件的方法,以便...
JAVA 解析XML和生成XML文档源码。比较全 1.DOM生成和解析XML文档 2.SAX生成和解析XML文档 3.DOM4J生成和解析XML文档 4.JDOM生成和解析XML
- JDOM库的导入和使用方法,包括创建XML文档、解析XML文件、修改XML数据等。 - JOM4J库的API介绍和使用示例,展示如何快速读写XML,以及执行XPath查询。 - 演示如何配置和实现SAX事件处理器,处理XML解析过程中的...
SAX(Simple API for XML)是XML解析器的一种,它采用事件驱动的方式对XML文档进行解析,而不是一次性加载整个文档到内存中,因此在处理大型XML文件时,SAX解析器具有较高的性能和较低的内存消耗。 标题“sax解析...
Java解析XML数据主要涉及到...总的来说,SAX解析器是Java处理XML文档的一种高效方式,特别适合处理大文件或资源有限的情况。通过自定义事件处理器,我们可以灵活地解析XML文档中的特定信息,而不必一次性加载整个文档。
在Android中,我们可以使用`DefaultHandler`作为SAX解析器的基类,创建一个继承自`DefaultHandler`的自定义处理器类,然后重写其中的方法,如`startElement`、`endElement`和`characters`,来处理XML中的元素和内容...
这个"Project1231_001_XML_SAX"可能包含了一个简单的XML文件和对应的SAX解析示例代码,通过运行这个项目,开发者可以了解如何在实际应用中使用SAX解析XML数据,以及如何处理XML文档中的不同结构。学习和理解SAX解析...
DOM解析器将整个XML文档加载到内存中,创建一个树形结构的文档对象模型,允许开发者通过节点层级遍历和操作XML数据。DOM解析的特点包括: 1. 完整性:DOM解析器一次性加载整个XML文档,因此可以随时访问任何部分的...
webservice远程调用,返回String数据并生成xml文件到本地工程,在通过SAX解析器把数据解析出来。这是webservice应用的一个简单的例子。根据该例子的思想,可以实现很多功能了。例如把client工程的sayHello方法改为...
在IT行业中,XML(eXtensible Markup Language)是一种用于存储和传输数据的标准化格式,尤其在Web应用程序、配置文件和数据交换中广泛使用。理解如何解析XML文档是开发过程中的重要技能。本篇我们将深入探讨SAX...
首先,SAX解析器以流式方式读取XML文档,当遇到文档的不同部分时,会触发相应的事件,如开始文档、开始元素、结束元素等。开发者可以注册事件处理器来响应这些事件,从而获取XML元素的信息。 1. **初始化解析器**:...
相较于DOM解析,SAX解析不将整个XML文档加载到内存中,而是采用事件驱动的方式,逐行读取并处理XML内容,因此在处理大型XML文件时更为高效。下面将详细介绍SAX解析XML文件的基本原理、工作流程以及在Android环境下...
虽然DOM提供了一种方便的方式来访问和修改XML文档的任何部分,但这种方法对内存的需求较大,不适合处理大型XML文件。 **SAX解析**: 相比之下,SAX解析器采用事件驱动模型,逐行读取XML文档,遇到元素、属性等结构...