Android--SAX解析方式

本文涉及的产品
全局流量管理 GTM,标准版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
云解析 DNS,旗舰版 1个月
简介: 版权声明:本文为博主原创文章,转载请标明出处。 https://blog.csdn.net/chaoyu168/article/details/53759507 Pull 解析方式虽然非常的好用,但它并不是我们唯一的选择。
版权声明:本文为博主原创文章,转载请标明出处。 https://blog.csdn.net/chaoyu168/article/details/53759507
Pull 解析方式虽然非常的好用,但它并不是我们唯一的选择。SAX解析也是一种特别常
用的 XML 解析方式,虽然它的用法比 Pull解析要复杂一些,但在语义方面会更加的清楚。
通常情况下我们都会新建一个类继承自 DefaultHandler,并重写父类的五个方法,如下

所示:

public class MyHandler extends DefaultHandler {
@Override
public void startDocument() throws SAXException {
}
@Override
public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException {
}
@Override
public void characters(char[] ch, int start, int length) throws
SAXException {
}
@Override

public void endElement(String uri, String localName, String qName) throws
SAXException {
}
@Override
public void endDocument() throws SAXException {
}
}

这五个方法一看就很清楚吧?startDocument()方法会在开始 XML 解析的时候调用,
startElement()方法会在开始解析某个结点的时候调用,characters()方法会在获取结点中内容
的时候调用,endElement()方法会在完成解析某个结点的时候调用,endDocument()方法会在
完成整个 XML 解析的时候调用。其中,startElement()、characters()和 endElement()这三个方
法是有参数的,从 XML 中解析出的数据就会以参数的形式传入到这些方法中。需要注意的
是,在获取结点中的内容时,characters()方法可能会被调用多次,一些换行符也被当作内容
解析出来,我们需要针对这种情况在代码中做好控制。
那么下面就让我们尝试用 SAX 解析的方式来实现和上一小节中同样的功能吧。新建一
个 ContentHandler类继承自 DefaultHandler,并重写父类的五个方法,如下所示:

public class ContentHandler extends DefaultHandler {
private String nodeName;
private StringBuilder id;
private StringBuilder name;
private StringBuilder version;
@Override
public void startDocument() throws SAXException {
id = new StringBuilder();
name = new StringBuilder();
version = new StringBuilder();
}
@Override
public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException {

// 记录当前结点名
nodeName = localName;
}
@Override
public void characters(char[] ch, int start, int length) throws
SAXException {
// 根据当前的结点名判断将内容添加到哪一个StringBuilder对象中
if ("id".equals(nodeName)) {
id.append(ch, start, length);
} else if ("name".equals(nodeName)) {
name.append(ch, start, length);
} else if ("version".equals(nodeName)) {
version.append(ch, start, length);
}
}
@Override
public void endElement(String uri, String localName, String qName) throws
SAXException {
if ("app".equals(localName)) {
Log.d("ContentHandler", "id is " + id.toString().trim());
Log.d("ContentHandler", "name is " + name.toString().trim());
Log.d("ContentHandler", "version is " + version.toString().trim());
// 最后要将StringBuilder清空掉
id.setLength(0);
name.setLength(0);
version.setLength(0);
}
}
@Override
public void endDocument() throws SAXException {
}
}

可以看到,我们首先给 id、name 和 version 结点分别定义了一个 StringBuilder 对象,并
在 startDocument()方法里对它们进行了初始化。 每当开始解析某个结点的时候, startElement()
方法就会得到调用,其中 localName 参数记录着当前结点的名字,这里我们把它记录下来。
接着在解析结点中具体内容的时候就会调用 characters()方法, 我们会根据当前的结点名进行
判断,将解析出的内容添加到哪一个 StringBuilder对象中。最后在 endElement()方法中进行
判断,如果 app结点已经解析完成,就打印出 id、name 和 version的内容。需要注意的是,
目前 id、name 和 version中都可能是包括回车或换行符的,因此在打印之前我们还需要调用
一下 trim()方法,并且打印完成后还要将 StringBuilder的内容清空掉,不然的话会影响下一
次内容的读取。
接下来的工作就非常简单了,修改 MainActivity中的代码,如下所示:

public class MainActivity extends Activity implements OnClickListener {
……
private void sendRequestWithHttpClient() {
new Thread(new Runnable() {
@Override
public void run() {
try {
HttpClient httpClient = new DefaultHttpClient();
// 指定访问的服务器地址是电脑本机
HttpGet httpGet = new HttpGet("http://10.0.2.2:8080/
get_data.xml");
HttpResponse httpResponse = httpClient.execute(httpGet);
if (httpResponse.getStatusLine().getStatusCode() == 200) {
// 请求和响应都成功了
HttpEntity entity = httpResponse.getEntity();
String response = EntityUtils.toString(entity,
"utf-8");
parseXMLWithSAX(response);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}).start();
}
……
private void parseXMLWithSAX(String xmlData) {
try {
SAXParserFactory factory = SAXParserFactory.newInstance();
XMLReader xmlReader = factory.newSAXParser().getXMLReader();

ContentHandler handler = new ContentHandler();
// 将ContentHandler的实例设置到XMLReader中
xmlReader.setContentHandler(handler);
// 开始执行解析
xmlReader.parse(new InputSource(new StringReader(xmlData)));
} catch (Exception e) {
e.printStackTrace();
}
}
}

在得到了服务器返回的数据后,我们这次去调用 parseXMLWithSAX()方法来解析 XML
数据。parseXMLWithSAX()方法中先是创建了一个 SAXParserFactory的对象,然后再获取到
XMLReader对象,接着将我们编写的 ContentHandler的实例设置到 XMLReader中,最后调
用 parse()方法开始执行解析就好了。
现在重新运行一下程序,点击 Send Request 按钮后观察 LogCat 中的打印日志,你会看
到和图 10.7中一样的结果。
除了 Pull 解析和 SAX 解析之外,其实还有一种 DOM 解析方式也算挺常用的,不过这
里我们就不再展开进行讲解了,感兴趣的话你可以自己去查阅一下相关资料。
目录
相关文章
|
2月前
|
IDE Android开发 iOS开发
深入解析Android与iOS的系统架构及开发环境差异
本文旨在探讨Android和iOS两大主流移动操作系统在系统架构、开发环境和用户体验方面的显著差异。通过对比分析,我们将揭示这两种系统在设计理念、技术实现以及市场策略上的不同路径,帮助开发者更好地理解其特点,从而做出更合适的开发决策。
148 2
|
2月前
|
安全 Android开发 iOS开发
安卓与iOS的较量:技术特性与用户体验的深度解析
在移动操作系统的战场上,安卓和iOS一直占据着主导地位。本文将深入探讨这两大平台的核心技术特性,以及它们如何影响用户的体验。我们将从系统架构、应用生态、安全性能和创新功能四个方面进行比较,帮助读者更好地理解这两个系统的异同。
70 3
|
1月前
|
开发工具 Android开发 iOS开发
深入解析安卓与iOS开发环境的优劣
【10月更文挑战第4天】 本文将深入探讨安卓和iOS两大主流移动操作系统的开发环境,从技术架构、开发工具、用户体验等方面进行详细比较。通过分析各自的优势和不足,帮助开发者更好地理解这两个平台的异同,从而为项目选择最合适的开发平台提供参考。
21 3
|
10天前
|
安全 5G Android开发
安卓与iOS的较量:技术深度解析
【10月更文挑战第24天】 在移动操作系统领域,安卓和iOS无疑是两大巨头。本文将深入探讨这两个系统的技术特点、优势和不足,以及它们在未来可能的发展方向。我们将通过对比分析,帮助读者更好地理解这两个系统的本质和内涵,从而引发对移动操作系统未来发展的深思。
22 0
|
1月前
|
安全 Android开发 iOS开发
深入解析:安卓与iOS的系统架构及其对应用开发的影响
本文旨在探讨安卓与iOS两大主流操作系统的架构差异,并分析这些差异如何影响应用开发的策略和实践。通过对比两者的设计哲学、安全机制、开发环境及性能优化等方面,本文揭示了各自的特点和优势,为开发者在选择平台和制定开发计划时提供参考依据。
50 4
|
1月前
|
测试技术 数据库 Android开发
深入解析Android架构组件——Jetpack的使用与实践
本文旨在探讨谷歌推出的Android架构组件——Jetpack,在现代Android开发中的应用。Jetpack作为一系列库和工具的集合,旨在帮助开发者更轻松地编写出健壮、可维护且性能优异的应用。通过详细解析各个组件如Lifecycle、ViewModel、LiveData等,我们将了解其原理和使用场景,并结合实例展示如何在实际项目中应用这些组件,提升开发效率和应用质量。
39 6
|
2月前
|
存储 开发框架 数据可视化
深入解析Android应用开发中的四大核心组件
本文将探讨Android开发中的四大核心组件——Activity、Service、BroadcastReceiver和ContentProvider。我们将深入了解每个组件的定义、作用、使用方法及它们之间的交互方式,以帮助开发者更好地理解和应用这些组件,提升Android应用开发的能力和效率。
157 5
|
2月前
|
缓存 Android开发 开发者
Android RecycleView 深度解析与面试题梳理
本文详细介绍了Android开发中高效且功能强大的`RecyclerView`,包括其架构概览、工作流程及滑动优化机制,并解析了常见的面试题。通过理解`RecyclerView`的核心组件及其优化技巧,帮助开发者提升应用性能并应对技术面试。
74 8
|
2月前
|
存储 缓存 Android开发
Android RecyclerView 缓存机制深度解析与面试题
本文首发于公众号“AntDream”,详细解析了 `RecyclerView` 的缓存机制,包括多级缓存的原理与流程,并提供了常见面试题及答案。通过本文,你将深入了解 `RecyclerView` 的高性能秘诀,提升列表和网格的开发技能。
65 8
|
1月前
|
安全 网络安全 Android开发
深度解析:利用Universal Links与Android App Links实现无缝网页至应用跳转的安全考量
【10月更文挑战第2天】在移动互联网时代,用户经常需要从网页无缝跳转到移动应用中。这种跳转不仅需要提供流畅的用户体验,还要确保安全性。本文将深入探讨如何利用Universal Links(仅限于iOS)和Android App Links技术实现这一目标,并分析其安全性。
181 0

推荐镜像

更多