android 解析网络数据.md

android解析XML的几种方式

  1. 使用DOM的方式:

    将XML文档解析成树状模型并将其放入内存来完成解析工作的.
    好处:结构清除、操作方便。但耗费系统资源

  2. 使用SAX的方式:

    采用的是事件驱动,也就是说,它并不需要解析完整个文档在按内容顺序解析文档的过程中,SAX会判断当前读到的字符是否合法XML语法中的某部分,如果符合就会触发事件。所谓事件,其实就是一些回调(callback)方法,这些方法(事件)定义在ContentHandler接口。

  3. 使用PULL的方式:(Android提供了支持,不需要第三方的包)

    允许你的应用程序代码主动从解析器中获取事件,正因为是主动获取事件,因此可以在满足了需要的条件后不再获取事件,结束解析.即:可以控制想解析到哪里就可以停止解析。
    SAX不能控制事件的处理主动结束

使用PULL解析

资料参考:XML PULL解析

步骤:

  1. 通过XmlPullParserFactory来得到XmlPullParser实例
1
2
XmlPullParserFactory factory=XmlPullParserFactory.newInstance();
XmlPullParser xmlPullParser=factory.newPullParser();
  1. 设置将要解析的xml数据,使用setInput方法,可接受两种不同的数据,一种是string,另一种是inputstream
1
2
3
xmlPullParser.setInput(new StringReader(xmlData));
或者
xmlPullParser.setInput(inputstream,"utr-8");//需要制定编码
  1. 得到解析事件,来判断是否为文档的末尾(处理不符合规则的情况)
1
int eventType=xmlPullParser.getEventType();
  1. 使用while循环,循环读取节点对应的数据,注意开始和结束的标识,XmlPullParser.START_TAG/END_TAG:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
while (eventType!=XmlPullParser.END_DOCUMENT){
String nodeName=xmlPullParser.getName();
switch (eventType){
case XmlPullParser.START_TAG:{
if(nodeName.equals("id")){ id=xmlPullParser.nextText();
}
break;
}
case XmlPullParser.END_TAG:{
//相应进行处理
break;
}
eventType=xmlPullParser.next();
}

首先用eventType判断的该节点的开始还是结束,因为:<id>1</id><>和</>是对应存在的,通过getName是获取<id>id值,最后通过nextText获取对应的值为1

相关方法解释:

  • 得到对应AttributeValue的属性值:
1
2
3
4
5
6
7
8
xmlPullParser.getAttributeValue(null, "virtual");
或者
xmlPullParser.getAttributeValue(0);
得到的是下面,xml中`virtual`的对应值:
<clientsetting
actual="1=183.62.250.17:8890"
virtual="1=www.sina.com.cn:9002">
</clientsetting>

案例解析:

  • 根目录下的子节点不断循环出现的情况。如下:
1
2
3
4
<ServerList>
<Server tag="服务器1" group="甬交所实盘电信" ip="14.23.84.3" port="9001" mode="Socket" offsetpath=""/>
<Server tag="服务器2" group="甬交所实盘电信" ip="14.23.84.3" port="9002" mode="Socket" offsetpath=""/>
</ServerList>

子节点:Server不断地循环出现。对应的解析如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
int eventType=parser.getEventType();//产生第一个事件
while(eventType!=XmlPullParser.END_DOCUMENT) {
switch(eventType) {
case XmlPullParser.START_DOCUMENT:
netSettingVOs=new ArrayList<NetSettingVO>();//用list集合进行存储
break;
case XmlPullParser.START_TAG:
String name=parser.getName();//获取当前解释器指向元素的名称
if ("Server".equals(name)) {
netSettingVO = new NetSettingVO();
netSettingVO.setSvrName(parser.getAttributeValue(0));//tag
netSettingVO.setGroupName(parser.getAttributeValue(1));//group
}
break;
case XmlPullParser.END_TAG:
if ("Server".equals(parser.getName())) {
netSettingVOs.add(netSettingVO);//END_TAG的时候进行加入
netSettingVO=null;
}
break;
}
eventType=parser.next();
}

总结就是START_TAG进行实例化list集合,在START_TAG子项获取对应的attr,最后在END_TAG进行加入list集合。当然要使用parser.next()进行移动

SAX解析方式

步骤:

  1. 继承DefaultHandler并重写5个方法,父类中这5个方法都是空方法
  • startDocument 开始xml解析时候调用,可用来进行初始化操作
  • endDocument 完成整个xml解析调用
  • startElement 开始解析某个节点是时调用,可获取当前节点名
  • endElement 完成解析某个节点时调用。可获取该节点所对应的值
  1. 通过SAXParserFactory获取XMLReader实例,注意这里并不是SAXParser实例
1
2
SAXParserFactory factory = SAXParserFactory.newInstance();
XMLReader xmlReader =factory.newSAXParser().getXMLReader();
  1. 创建DefaultHandler实例,并调用setContentHandler进行设置
1
2
3
Contenthandler contenthandler = new Contenthandler();
//将Contenthandler实例设置到XMLReader中
xmlReader.setContentHandler(contenthandler);
  1. 进行解析:
1
xmlReader.parse(new InputSource(new StringReader(xmlData)));

使用DOM方式解析xml

android之dom解析xml

使用JSONObject解析json

首先要知道格式一个数组[{},{},{}],还是一个字符串:{}
在数组的情况下,先得到JSONArray,然后在逐条对到元素:JSONObject,最后再取到每一个值。

1
2
3
4
5
6
7
JSONArray jsonArray=new JSONArray(jsonData);//得到数组
for(int i=0;i<jsonArray.length();i++){
JSONObject jsonObject=jsonArray.getJSONObject(i);
String id=jsonObject.getString("id");
String name=jsonObject.getString("name");
String version=jsonObject.getString("version");
}

如果是一条字符串,直接得到JSONObject即可。

1
JSONObject jsonObject=new JSONObject(jsonData);

下面列出了JsonElement 四种具体实现类型

  • JsonPrimitive (Java Doc) —— 例如一个字符串或整型
  • JsonObject (Java Doc) —— 一个以 JsonElement 名字(类型为 String)作为索引的集合。类似于 Map<String,JsonElement>集合(Java Doc)
  • JsonArray (Java Doc)—— JsonElement 的集合。注意数组的元素可以是四种类型中的任意一种,或者混合类型都支持。
  • JsonNull (Java Doc) —— 值为null

使用Gson解析json

使用参考:Android客户端与服务端之间使用JSON交互数据。
原理解析:
完全理解Gson(1):简单入门
完全理解Gson(2):Gson序列化
完全理解Gson(3):Gson反序列化

使用jackson解析

Jackson:与GSON类似,在频繁使用时性能更佳

各种解析json数据的类库比较

  • 开源的Jackson:

    Jackson对于复杂类型的json转换bean会出现问题,一些集合Map,List的转换出现问题。
    Jackson对于复杂类型的bean转换Json,转换的json格式不是标准的Json格式
    参考: 各个JSON技术的比较

建议:

使用Google的Gson和阿里巴巴的FastJson两种并行使用
如果只是功能要求,没有性能要求,可以使用google的Gson
如果有性能上面的要求可以使用Gson将bean转换json确保数据的正确,使用FastJson将Json转换Bean