• 第一行代码Android 第九章9.3 解析XML格式(Pull解析方式,SAX解析方式)


    9.3 解析XML格式数据
            通常情况下,每个需要访问网络的应用程序都会有一个自己的服务器,我们可以向服务器提交数据,也可以从服务器上获取数据。
            网络上传输的数据一般都是格式化后的数据,这种数据会有一定的结构规格和语义,当另一方收到数据消息之后就可以按照相同的结构规格来进行解析,从而取出他想要的那部分内容
            在网络上传输数据时最常用的格式是:XML和JSON。

    搭建一个最简单的Web服务器,在这个服务器上提供一段XML文本,然后我们在程序里去访问这个服务器,再对得到的XML文本进行解析。
    1.搭建Web服务器
            1)http://httpd.apache.org/download.cgi 下载一个Apache服务器安装包
            2)下载后安装 (填写好域名(自定义),选择好安装路径)
            3)电脑浏览器地址栏中输入127.0.0.1,验证服务器是否搭建成功
    2.进入到htdocs目录下,新建一个名为get_data.xml的文件

    1. <apps>
    2. <app>
    3. <id>1id>
    4. <name>Google Mapsname>
    5. <version>1.0version>
    6. app>
    7. <app>
    8. <id>2id>
    9. <name>Chromename>
    10. <version>2.1version>
    11. app>
    12. <app>
    13. <id>3id>
    14. <name>Google Playname>
    15. <version>2.3version>
    16. app>
    17. apps>

    准备工作已做完,接下来在Android程序里去获取并解析这段XML数据

    9.3.1 Pull解析方式
            解析XML格式的数据其实有很多种,最常见的两种是Pull解析和SAX解析。

    1. //修改MainActivity中的代码
    2. public class MainActivity extends AppCompatActivity implements Views.OnClickListener {
    3. ...
    4. private void sendRequestWithOkHttp() {
    5. new Thread(new Runnable() {
    6. @Override
    7. public void run() {
    8. try {
    9. OkHttpClient client = new OkHttpClient();
    10. //指定访问的服务器地址是电脑本机
    11. Request request = new Request.Builder().url("http://10.0.2.2/get_data.xml").build();
    12. Response response = Client.newCall(request).execute();
    13. String responseData = response.body().string();
    14. //解析服务器返回的数据
    15. parseXMLWithPull(responseData);
    16. } catch (Exception e) {
    17. e.printStackTrace();
    18. }
    19. }
    20. }).start();
    21. }
    22. ...
    23. private void parseXMLWithPull(String xmlData) {
    24. try {
    25. //首先获取一个XmlPullParserFactory实例
    26. XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
    27. //借助XmlParserFactory实例得到XmlPullParser对象
    28. XmlPullParser xmlPullParser = factory.newPullParser();
    29. //调用setInput方法将服务器返回的XML数据设置进行就可以解析了
    30. xmlPullParser.setInput(new StringReader(xmlData));
    31. //得到当前解析事件
    32. int eventType = xmlPullParser.getEventType();
    33. String id="";
    34. String name="";
    35. String version="";
    36. //XmlPullParser.END_DOCUMENT解析完成的标志
    37. while (eventType != XmlPullParser.END_DOCUMENT) {
    38. String nodeName = xmlPullParser.getName();
    39. switch (eventType) {
    40. //开始解析某个节点
    41. case XmlPullParser.START_TAG: {
    42. if ("id".equals(nodeName)) {
    43. id = xmlPullParser.nextText();
    44. } else if ("name".equals(nodeName)) {
    45. name = xmlPullParser.nextText();
    46. } else if ("version".equals(nodeName)) {
    47. version = xmlPullParser.nextText();
    48. }
    49. break;
    50. }
    51. //完成解析某个节点
    52. case XmlPullParser.END_TAG: {
    53. if ("app".equals(nodename)) {
    54. Log.d("MainActivity","id is"+id);
    55. Log.d("MainActivity","name is"+name);
    56. Log.d("MainActivity","version is"+version);
    57. }
    58. break;
    59. }
    60. default:
    61. break;
    62. }
    63. eventType = xmlPullParser.next();
    64. }
    65. } catch (Exception e) {
    66. e.printStackTrace();
    67. }
    68. }
    69. }

    9.3.2 SAX解析方式
            它的用法比Pull解析更复杂一些,但是语义方面会更加清楚。
            通常情况下我们都会新建一个类继承自DefaultHandler,并重写父类的5个方法。

    1. //新建一个ConetentHandler类继承自DefaultHandler
    2. public class ContentHandler extends DefaultHandler {
    3. private String nodeName;
    4. //给节点分别定义了一个StringBuilder对象
    5. private StringBuilder id;
    6. private StringBuilder name;
    7. private StringBuilder version;
    8. @Override
    9. //开始解析XML时调用
    10. public void startDocument() thorws SAXException {
    11. //初始化节点
    12. id = new StringBuilder();
    13. name = new StringBuilder();
    14. version = new StringBuilder();
    15. }
    16. @Override
    17. //开始解析某个节点时调用
    18. public void startElement(String uri,String localName,String qName,Attributes attributes) throws SAXException {
    19. //记录当前节点名
    20. nodeName =localName;
    21. }
    22. @Override
    23. //获取某个节点的时候调用
    24. public void characters(char[] ch,int start,int length) throws SAXException {
    25. //根据当前的节点名判断将内容添加到哪一个StringBulder
    26. if ("id".equals(nodeName)) {
    27. id.append(ch,start,length);
    28. } else if ("name".equals(nodeName)) {
    29. name.append(ch,start,length);
    30. } else if ("version".equals(nodeName)) {
    31. version.append(ch,start,length);
    32. }
    33. }
    34. @Override
    35. //完成解析某个节点时调用
    36. public void EndElement(String uri,String localName,String qName) throws SAXException {
    37. if ("app".equals(localName)) {
    38. Log.d("ContentHandler","id is"+id.toString().trim()); //trim()方法是用于去掉字符串开头和结尾的空格的
    39. Log.d("ContentHandler","name is"+name.toString().trim());
    40. Log.d("ContentHandler","version is"+version.toString().trim());
    41. //最后要将StringBuilder清空掉,不然会影响下一次内容的读取
    42. id.serLength(0);
    43. name.setLength(0);
    44. version.setLength(0);
    45. }
    46. }
    47. @Override
    48. //完成整个XML解析时调用
    49. public void endDocument() throws SAXException {
    50. super.endDocument();
    51. }
    52. }
    1. //修改MainActivity中的代码
    2. public class MainActivity extends AppCompatActivity implements Views.OnClickListener {
    3. ...
    4. private void sendRequestWithOkHttp() {
    5. new Thread(new Runnable() {
    6. @Override
    7. public void run() {
    8. try {
    9. OkHttpClient client = new OkHttpClient();
    10. //指定访问的服务器地址是电脑本机
    11. Request request = new Request.Builder().url("http://10.0.2.2/get_data.xml").build();
    12. Response response = Client.newCall(request).execute();
    13. String responseData = response.body().string();
    14. //解析服务器返回的数据
    15. parseXMLWithSAX(responseData);
    16. } catch (Exception e) {
    17. e.printStackTrace();
    18. }
    19. }
    20. }).start();
    21. }
    22. ...
    23. private void parseXMLWithSAX(String xmlData) {
    24. try {
    25. //首先获取一个SAXParserFactory实例
    26. SAXParserFactory factory = SAXParserFactory.newInstance();
    27. //借助SAXParserFactory实例得到XMLReader对象
    28. XMLReader xmlReader= factory.newSAXParser().getXMLReader();
    29. ContentHandler handler = new ContentHandler();
    30. //将ContentHandler的实例设置到XMLReader中
    31. xmlReader.setContentHandler(handler);
    32. //开始执行解析
    33. xmlReader.parse(new InputSource(new StringReader(xmlData)));
    34. } catch (Exception e) {
    35. e.printStackTrace();
    36. }
    37. }
    38. }
  • 相关阅读:
    c语言-输入输出详解
    Spring基础元注解@Target、@Retention、@Documented、@Inherited
    线路横断面测量坐标转换程序
    氨基苯酚/多巴胺仿生修饰碳纳米管/α-氧化铝/ CNTs-Ag纳米复合材料
    EffectiveC++-条款40:明智而审慎地使用多重继承
    第2章 Spring Boot实践,开发社区登录模块(下)
    oracle10数据库迁移
    window通过vscode的ssh访问linux服务器-详细部署教程
    C++ string类模板
    RocketMQ源码(7)—Producer发送消息源码(1)—发送消息的总体流程【一万字】
  • 原文地址:https://blog.csdn.net/XXX_17/article/details/126129339