XML和JSON
本文翻译自xmlpull,SAX,android,JSON官方文档(http://www.saxproject.org/quickstart.html,http://www.json.org/),经测试整理如下。 网络传输数据一般我们会在网络上传输一些格式化的数据,这些数据有自己的语义。当另一方收到数据时,以相同的语义进行解析,获取真正想要的数据。 在网络中传输数据时最常用的方法是:XML和JSON,本文先介绍XML解析。 XML,可扩展标记语言(Extensible Markup Language)是一个以文本来描述数据的文档,可以实现客户端与服务器之间的数据传输。如下一个xml文档示例: <?xml version="1.0" encoding="UTF-8"?>
<person>
<teacher id = "1">
<name>wyg</name>
</teacher>
<teacher id = "2">
<name>wyg</name>
</teacher>
</person>
一个基本的xml文件就是由上述部分构成。xml有以下用途:
下面我们集中讨论一下如何解析xml,即在接收方怎么处理该xml文档。主要介绍两种:PULL解析和SAX解析。 PULL解析概述XmlPullParser是一个接口,通过XMLPULL V1 API定义了解析方法。
XmlPullParser有两个关键的方法: 可以通过
事件类型有如下几种:
可以通过下列方式获取下一个事件:
若当前标签有属性的话可以通过 在第一次使用
PULL解析步骤为了通过PULL解析XML格式内容,我们需要完成以下内容
简单介绍一下命名空间:XML命名空间提供避免元素命名冲突的方法。XML命名空间属性被放置于元素的开始标签之中,并使用以下的语法: <wyg:person xmlns:wyg="http://www.sywyg.com">
<wyg:teacher id = "1"/>
</wyg:person>
所有带有相同前缀的子元素都会与同一个命名空间相关联。上述内容来自:http://www.w3school.com.cn/xml/xml_namespaces.asp。 通过上述两步,我们就可以开始解析xml文档了。典型的XMLPULL程序会反复调用 一套完整的解析代码如下: /** * XML解析:PULL解析 * @author sywyg * @since 2015.7.27 */
public class MainActivity extends Activity {
private final String TAG = "result";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void btnClick(View view){
String xmlData =
"<?xml version="1.0" encoding="UTF-8"?>" +
"<person>" +
" <teacher id="1" >" +
" <name>wyg</name>" +
" </teacher>" +
" <teacher id="2" name="sywyg"></teacher>" +
"</person>";
parseXMLWithPULL(xmlData);
}
// 解析数据
public void parseXMLWithPULL(String xmlData) {
ArrayList<Teacher> listTeacher = new ArrayList<Teacher>();
XmlPullParserFactory factory = null;
XmlPullParser xpp = null;
//事件类型
int eventType = 0;
// xml文件位置
// String xmlName = "person.xml";
// 1. 创建PULL解析器
try {
// 1.1 获得XMLPULL工厂实例
factory = XmlPullParserFactory.newInstance();
// 1.2 通过工厂实例创建解析器
xpp = factory.newPullParser();
// 2. 设置xml文档数据
xpp.setInput(new StringReader(xmlData));
// 3. 开始解析数据
eventType = xpp.getEventType();
Teacher teacher = null;
while (eventType != XmlPullParser.END_DOCUMENT) {
String nodeName = xpp.getName();
switch (eventType) {
case XmlPullParser.START_DOCUMENT:
Log.d(TAG,"Start document");
case XmlPullParser.START_TAG:
// 读取标签
if ("teacher".equals(nodeName)) {
teacher = new Teacher();
String id = xpp.getAttributeValue(0);
teacher.setId(Integer.parseInt(id));
} else if ("name".equals(nodeName)) {
teacher.setName(xpp.getText());
}
break;
case XmlPullParser.TEXT:
Log.d(TAG,"getText:" + xpp.getText());
break;
case XmlPullParser.END_TAG:
// 解析完某个节点
if("teacher".equals(nodeName)){
Log.d(TAG,teacher.toString());
}
break;
default:
Log.d(TAG,"end document ");
break;
}
eventType = xpp.next(); // 可能抛出IO异常
}
} catch (XmlPullParserException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
更过相关内容请参考Android API,如 SAX解析看完PULL方式解析,我们来看一下SAX方式解析。 SAX(Simple API for XML),可以方便的读取和操作XML数据。SAX解析方式也是基于事件处理数据流,在遇到相应的事件时,调用对应的方法处理事件。 SAX解析中主要有四种处理事件的接口: 在继承 public class MyXMLSAXHandler extends DefaultHandler {
@Override
public void startDocument() throws SAXException {}
@Override
public void startElement(String uri,String localName,String qName,Attributes attributes) throws SAXException {}
@Override
@Override
public void characters(char[] ch,int start,int length) throws SAXException {}
public void endElement(String uri,String qName) throws SAXException {}
@Override
public void endDocument() throws SAXException {}
}
根据方法名我们也能大体猜到每个方法的作用了:
解析步骤为了通过SAX解析XML格式内容,我们需要完成以下内容:
代码如下: public class MyXMLSAXHandler extends DefaultHandler {
private static String xmlData = "<?xml version="1.0" encoding="UTF-8"?>"
+ "<person>"
+ "<teacher id="1">"
+ "<name>wyg</name>wyg2"
+ "</teacher>"
+ "</person>";
private String id;
private StringBuilder name;
private String nodeName;
public static void main(String[] args) {
XMLReader reader = null;
try {
// 1. 创建XMLReader对象
// 这种方式是通过XMLReaderFactory的静态方法获取的动态对象。
reader = XMLReaderFactory.createXMLReader();
// 2. 创建XML事件处理器
ContentHandler handler = new MyXMLSAXHandler();
// 3. 注册事件处理器
reader.setContentHandler(handler);
//reader.setErrorHandler((ErrorHandler) handler);
// 4. 开始执行解析
reader.parse(new InputSource(new StringReader(xmlData)));
} catch (SAXException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void startDocument() throws SAXException {
name = new StringBuilder();
System.out.println("start Document");
}
@Override
public void startElement(String uri,Attributes attributes) throws SAXException {
nodeName = localName;
if("teacher".equals(nodeName)){
// 清空换行符或回车
id = attributes.getValue(0).trim();
}
System.out.println("start Element");
}
@Override
public void characters(char[] ch,int length) throws SAXException {
if("name".equals(nodeName)){
name.append(ch,start,length);
//System.out.println(name);
}
System.out.println("start characters");
}
@Override
public void endElement(String uri,String qName) throws SAXException {
if("teacher".equals(localName)){
System.out.println("id = " + id);
System.out.println("name = " + name);
// 将name值清空,方便再读取
name.setLength(0);
id = null;
}
// 避免characters()方法读取换行符
nodeName = null;
System.out.println("end Element");
}
@Override
public void endDocument() throws SAXException {
System.out.println("end Document");
}
}
注意: <teacher id="1">
<name>wyg</name>wyg2
</teacher>
对于上面的xml,则读取完结束标签 下面我们看以下JSON数据。内容翻译自http://www.json.org/ JSONJSON(JavaScript Object Notation) 是一种轻量级的数据交换格式,易于人阅读和编写,同时也易于机器解析和生成。 JSON建构于两种结构:
这些都是常见的数据结构。事实上大部分现代计算机语言都以某种形式支持它们。这使得一种数据格式在同样基于这些结构的编程语言之间交换成为可能。 JSON具有以下这些形式: 对象是一个无序的“‘名称/值’对”集合。一个对象以“{”(左括号)开始,“}”(右括号)结束。每个“名称”后跟一个“:”(冒号);“‘名称/值’ 对”之间使用“,”(逗号)分隔。 例如: 值(value)可以是双引号括起来的字符串(string)、数值(number)、true、false、 null、对象(object)或者数组(array),这些结构可以嵌套。 字符串(string)是由双引号包围的任意数量Unicode字符的集合,使用反斜线转义。一个字符(character)即一个单独的字符串(character string)。 数值(number)也与C或者Java的数值非常相似。除去未曾使用的八进制与十六进制格式。除去一些编码细节。 下面介绍一下Android中解析JSON,主要介绍两种:JSONObject,和谷歌的开源库GSON。 首先介绍了一下JSONObject JSONObject使用JSONObject会涉及到以下几个类:
注意这四个类都是线程不安全的,且其它类不应该继承这些类。 JSONArray一组有序的值,值可能是:JSONObject/JSONArray/String/Integer/Long/Double/NULL/null JSONObject该类是用来处理json中对象的,对象名是唯一并且非空的字符串。值可能是:JSONObject/JSONArray/String/Integer/Long/Double/NULL。 该类可以将值强制转换成另外的类型:
JSONStringer实现了JSONObject和JSONArray的 该类只能解析标准格式的JSON字符串,特别是下面要求:
注意调用非格式JSON字符串将会抛出JSONException异常,该类没有提供缩进输出,需要缩进输出的话 JSONTokenerJSON文本解析类,大部分应用只是用下列方式: String json = "{"
+ " "query": "Pizza","
+ " "locations": [ 94043,90210 ] "
+ "}";
JSONObject object = (JSONObject) new JSONTokener(json).nextValue();
String query = object.getString("query");
JSONArray locations = object.getJSONArray("locations");
对于下面的语法错误将会忽略:
下面介绍一下Gson GsonGson是Google提供的用来在java对象和JSON数据之间进行映射的java类库。可以将一个JSON字符串转成一个java对象, java数组/对象转换成JSON字符串从java数组/对象转换成JSON字符串可以通过Gson的 Gson gson = new Gson();
String[] strings = {"sywyg","wyg"};
String JsonStrings = gson.toJson(strings);
其中, JSON字符串转换成java数组/对象Gson提供了 json和xml比较1.JSON和XML的数据可读性基本相同 2.JSON和XML同样拥有丰富的解析手段 3.JSON相对于XML来讲,数据的体积小,网络传输节省流量 4.JSON与JavaScript的交互更加方便 5.JSON对数据的描述性比XML较差 6.JSON的速度要远远快于XML (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |