xml及json解析
来源:互联网 发布:网络攻击日语 编辑:程序博客网 时间:2024/05/20 18:18
1.引子:DOM
这篇文章写得挺好
http://www.cnblogs.com/yexiaochai/archive/2013/05/28/3102674.html
document object model 文档对象模型,用于访问xml html的标准
document对象的常用方法
节点常用属性
<!doctype html><html lang="en"> <head> <meta charset="UTF-8"> <meta name="Generator" content="EditPlus®"> <meta name="Author" content=""> <meta name="Keywords" content=""> <meta name="Description" content=""> <title>Dom概述</title> </head> <body> <h1>明天休息</h1><script> //alert(document.getElementsByTagName("h1")[0].firstChild.nodeValue); //alert(document.getElementsByTagName("h1")[0].lastChild.nodeValue); //alert(document.getElementsByTagName("h1")[0].childNodes[0].nodeValue );//alert(document.getElementsByTagName("h1")[0].innerHTML); </script> </body></html>
由于这里只有一个子节点,first=last ,都能弹出明天休息的框框
<!doctype html><html lang="en"> <head> <meta charset="UTF-8"> <meta name="Generator" content="EditPlus®"> <meta name="Author" content=""> <meta name="Keywords" content=""> <meta name="Description" content=""> <title>打印ul里面的li子节点信息</title> <script> function getLi(){ var bjNode= document.getElementById("bj"); var childnum = bjNode.childNodes.length;//alert(childnum); for(var i=0;i<childnum ;i++) alert( bjNode.childNodes[i].nodeName+","+bjNode.childNodes[i].nodeType+","+ bjNode.childNodes[i].nodeValue ); //#text 3 北京 //h1 1 //#text 3 奥运 } </script> </head> <body> <ul><li id="bj" value="beijing">北京<h1>海淀</h1>奥运</li><li id="sh" value="shanghai">上海</li><br/><input type="button" value="li取值" onclick="getLi()"/></ul> </body></html>
这里第一个节点下有3个子节点,第一个是文本节点,北京,第二个是一个元素节点,变大了的海淀,第三个是文本节点,奥运
所以依次输出了
#text,3,北京
H1,1,null
#text,3,奥运
由上面这两个例子就大概可以看出xml解析需要的基本知识,按节点获取,至于增删改查之类的这里不多说了~
2.关于xml
如果想系统、深入的学习xml的知识,最好看看Javascript的相关知识,包括各种BOM、DOM、xml约束、解析什么的
xml,可标记语言,用来传输数据,至于展示数据需要别的软件解析
例如数据结构的树形数据结构,如何才能交给PC处理?
xml的标签
一个标签中只能有一个主标签;一个标签下由若干子标签,但是不能互相嵌套;主题内容中的空格也会被读取,如果不处理,跑起来容易挂掉
3.着重看下如何解析,做安卓开发主要还是用,SAX DOM PULL
首先简单说下SAX和DOM解析的异同,而PULL解析是安卓特有,单独说
首先解析方式上,主要是以下两种,几乎所有商用的xml 解析器都同时实现了这两个接口
(1) JAXP,
(2)DOM4J解析
看名字就知道这个是DOM模式解析,脱胎于更早期的JDOM
Document document = reader.read(new File("input.xml"));
Document document = DocumentHelper.parseText(text);
//创建根节点
获取节点对象
List nodes = rootElm.elements("member");
for (Iterator it = nodes.iterator(); it.hasNext();) {
Element elm = (Element) it.next();
// do something
}
for(Iterator it=root.elementIterator();it.hasNext();){
Element element = (Element) it.next();
// do something
}
Element ageElm = newMemberElm.addElement("age");
element.setText("29");
//childElm是待删除的节点,parentElm是其父节点
Element contentElm = infoElm.addElement("content");
contentElm.addCDATA(diary.getContent());
节点对象属性
Element root=document.getRootElement();
//属性名name
String text=attribute.getText();
Attribute attribute=root.attribute("size");
root.remove(attribute);
Element root=document.getRootElement();
for(Iterator it=root.attributeIterator();it.hasNext();){
Attribute attribute = (Attribute) it.next();
String text=attribute.getText();
System.out.println(text);
}
newMemberElm.addAttribute("name", "sitinspring");
Attribute attribute=root.attribute("name");
attribute.setText("sitinspring");
将文档写入XML
XMLWriter writer = new XMLWriter(new FileWriter("output.xml"));
writer.write(document);
writer.close();
OutputFormat format = OutputFormat.createPrettyPrint();
指定XML编码
XMLWriter writer = new XMLWriter(new FileOutputStream ("output.xml"),format);
writer.write(document);
writer.close();
来对比下:
SAX这种基于事件的处理方式,一边读数据一边解析,无需保存数据,在需要的时候直接停止亦可
而DOM这种基于树的处理方式,需要先把数据完全读入,可以对他的数据、结构进行修改,但是另一方面来说,对于比较大的文档,他的内存消耗就比较大了
所以:
如果想对数据更改并输出为xml,DOM更合适;对于大文件,XML更合适,另外如果对速度有要求,同样XML是更好的选择
实例:
正好看到一篇好文,直接引用了。http://www.cnblogs.com/JerryWang1991/archive/2012/02/24/2365507.html
<?xml version="1.0" encoding="utf-8"?><channel><item id="0" url="http://www.baidu.com">百度</item><item id="1" url="http://www.qq.com">腾讯</item><item id="2" url="http://www.sina.com.cn">新浪</item><item id="3" url="http://www.taobao.com">淘宝</item></channel>
4.最后关于PULL解析
在android系统中,很多资源文件中,很多都是xml格式,在android系统中解析这些xml的方式,是使用pul解析器进行解析的,它和sax解析一样(个人感觉要比sax简单点),也是采用事件驱动进行解析的,当pull解析器,开始解析之后,我们可以调用它的next()方法,来获取下一个解析事件(就是开始文档,结束文档,开始标签,结束标签),当处于某个元素时可以调用XmlPullParser的getAttributte()方法来获取属性的值,也可调用它的nextText()获取本节点的值。
跟SAX不同的是, Pull解析器产生的事件是一个数字,而非方法,因此可以使用一个switch对感兴趣的事件进行处理。当元素开始解析时,调用parser.nextText()方法可以获取下一个Text类型节点的值pull本来是一个开源项目
Android SDK中已经集成了Pull解析器,无需添加任何jar文件
• 使用Pull解析器解析XML文件
– 1. Xml.newPullParser() 获得解析器
– 2 parser.setInput(in, "UTF-8") 设置输入流以及编码
– 3. parser.next() 获取下一个解析事件,得到一个事件代码
– 4. XmlPullParser中定义了常量来标识各种解析事件
START_DOCUMENT、
END_DOCUMENT 、
START_TAG 、
END_TAG 、
TEXT<?xml version='1.0' encoding='utf-8' standalone='yes' ?><map><string name='nickname'>hellokitty</string><boolean name='autostart' value='false' /><float name='autoclose' value='1000.0' /></map>
bean
package com.example.bean;public class Book { private String bookname; private String author; private String priceString; @Overridepublic String toString() {return "Book [bookname=" + bookname + ", author=" + author+ ", priceString=" + priceString + "]";}public String getBookname() {return bookname;}public void setBookname(String bookname) {this.bookname = bookname;}public String getAuthor() {return author;}public void setAuthor(String author) {this.author = author;}public String getPriceString() {return priceString;}public void setPriceString(String priceString) {this.priceString = priceString;} }
public class MainActivity extends Activity {public static String TAG = "pullparser";@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);} public void parsebyPull(View v) throws IOException{ //得到解析器XmlPullParser XmlPullParser pullparser = Xml.newPullParser(); List<Book> booklist= new ArrayList<Book>();Book book = null;try {//设置读取文件,要与xml里的编码格式一致InputStream in = new FileInputStream("data/data/com.example.pullparser/files/books.xml");pullparser.setInput(in, "UTF-8");//类型int evenType = pullparser.getEventType();while(evenType!=XmlPullParser.END_DOCUMENT){if (evenType==XmlPullParser.START_DOCUMENT) {Log.i(TAG, "START_DOCUMENT");} if (evenType==XmlPullParser.START_TAG){Log.i(TAG, "START_TAG"+pullparser.getName());if ("book".equals(pullparser.getName())) {book = new Book();}if ("bookname".equals(pullparser.getName())) {book.setBookname(pullparser.nextText());}if ("author".equals(pullparser.getName())) {book.setAuthor(pullparser.nextText());}if ("price".equals(pullparser.getName())) {book.setPriceString(pullparser.nextText());}}if (evenType==XmlPullParser.TEXT) {Log.i(TAG, "TEXT" +pullparser.getText());}if (evenType==XmlPullParser.END_TAG) {Log.i(TAG, "END_TAG"+pullparser.getName());if ("book".equals(pullparser.getName())) {booklist.add(book);book = null;}}evenType=pullparser.next();}if (evenType==XmlPullParser.END_DOCUMENT) {Log.i(TAG, "END_DOCUMENT");}for ( Book book2 : booklist) {Log.i(TAG, book2.toString() ); }} catch (FileNotFoundException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (XmlPullParserException e) {// TODO Auto-generated catch blocke.printStackTrace();} }}
5.JSON
<?xmlversion="1.0"encoding="utf-8"?><country> <name>中国</name> <province> <name>黑龙江</name> <cities> <city>哈尔滨</city> <city>大庆</city> </cities> </province> <province> <name>广东</name> <cities> <city>广州</city> <city>深圳</city> <city>珠海</city> </cities> </province> <province> <name>台湾</name> <cities> <city>台北</city> <city>高雄</city> </cities> </province> <province> <name>新疆</name> <cities> <city>乌鲁木齐</city> </cities> </province></country>
var pro ={ "name":"中国", "province":[{"name":"黑龙江","cities":{"city":["哈尔滨","大庆"]}}, {"name":"广东","cities":{"city":["广州","深圳","珠海"]}}, {"name":"台湾","cities":{"city":["台北","高雄"]}}, {"name":"新疆","cities":{"city":["乌鲁木齐"]}} ] }
可读性上,JSON更简洁,xml更规范
扩展性上没有区别
解析上,事先知道结构的时候,JSON显然更有优势
传输效率上,JSON无需闭合标签,总数据量会少一些,传输压力更小
查询手机号,利用网络上的服务提供数据,先看一下解析出来的数据格式
xml
http://api.k780.com:88/?app=phone.get&phone=13800138000&appkey=14114&sign=ede788f7bf8d0678e281f660654ef995&format=xml
JSON格式
public class MainActivity extends Activity {public static final String TAG = "phonenumberqurey";@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);}Handler hanlder = new Handler(){@Overridepublic void handleMessage(Message msg) {// TODO Auto-generated method stubsuper.handleMessage(msg);switch (msg.what) {case 1://正确的连到服务器就要获取出来,而不是toastTextView tv_loaction = (TextView) findViewById(R.id.tv_location);tv_loaction.setText((String)msg.obj);break;case 2:Toast.makeText(MainActivity.this, (String)msg.obj, 0).show();break;default:break;}}}; public void query(View v){ //先获取电话号码 EditText et_number = (EditText) findViewById(R.id.et_number); String number = et_number.getText().toString(); final String path ="http://api.k780.com:88/?app=phone.get&phone="+number+"&appkey=14114&sign=ede788f7bf8d0678e281f660654ef995&format=xml"; //发请求的线程 Thread thread = new Thread(){ public void run() { try { URL url = new URL(path); HttpURLConnection conn= (HttpURLConnection) url.openConnection(); // conn.setReadTimeout(5000); conn.setConnectTimeout(5000); conn.setRequestMethod("GET"); // conn.connect(); // String city =null; String operator = null; if(conn.getResponseCode()==200){ //登陆成功 //登陆失败? InputStream is= conn.getInputStream(); //String text = WebUtils.gettextFromInputStream(is, null); XmlPullParser pullparser = Xml.newPullParser(); pullparser.setInput(is, "UTF-8"); //得到读取到的某部分的类型 int evenType = pullparser.getEventType(); while(evenType!=XmlPullParser.END_DOCUMENT){ if (evenType==XmlPullParser.START_TAG) { Log.i(TAG, "START_TAG"+pullparser.getName()); if ("operators".equals(pullparser.getName())) { operator=pullparser.nextText(); } if ("style_citynm".equals(pullparser.getName())) { city=pullparser.nextText(); } } evenType=pullparser.next(); } Log.i(TAG,operator+":"+city); Message msg = hanlder.obtainMessage(); msg.what=1; if(city==null||operator==null) msg.obj="没有查询到结果"; else msg.obj= city+":"+operator; hanlder.sendMessage(msg); } else { Message msg = hanlder.obtainMessage(); msg.what=2; msg.obj="没有链接到服务器"; hanlder.sendMessage(msg); } } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } }; }; thread.start(); } public void querybyjson(View v){ //先获取电话号码 EditText et_number = (EditText) findViewById(R.id.et_number); String number = et_number.getText().toString(); final String path ="http://api.k780.com:88/?app=phone.get&phone="+number+"&appkey=14114&sign=ede788f7bf8d0678e281f660654ef995&format=json"; //发请求的线程Thread thread = new Thread(){public void run() {try {URL url = new URL(path);HttpURLConnection conn= (HttpURLConnection) url.openConnection();conn.setReadTimeout(5000);conn.setConnectTimeout(5000);conn.setRequestMethod("GET");conn.connect(); String city =null; String operator = null;if(conn.getResponseCode()==200){InputStream is= conn.getInputStream();//json需要提取出文本String text = WebUtils.gettextFromInputStream(is, null); JSONObject jsonObject = new JSONObject(text);JSONObject result = jsonObject.getJSONObject("result"); city= result.getString("style_citynm");operator = result.getString("operators"); Log.i(TAG,operator+":"+city);Message msg = hanlder.obtainMessage();msg.what=1;if(city==null||operator==null) msg.obj="没有查询到结果";else msg.obj= city+":"+operator;hanlder.sendMessage(msg);}else {Message msg = hanlder.obtainMessage();msg.what=2;msg.obj="没有链接到服务器";hanlder.sendMessage(msg);}} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();}};};thread.start(); } class Myhandler extends AsyncHttpResponseHandler {@Overridepublic void onSuccess(int statusCode, Header[] headers, byte[] responseBody) {// TODO Auto-generated method stub String city =null; String operator = null; //String text = WebUtils.gettextFromInputStream(is, null);XmlPullParser pullparser = Xml.newPullParser(); //onSuccess的最后一个参数传递的是数组,这里需要一个把数组转成流的方法~ByteArrayInputStream bais= new ByteArrayInputStream(responseBody); try {pullparser.setInput(bais, "utf-8");//得到读取到的某部分的类型int evenType = pullparser.getEventType();while(evenType!=XmlPullParser.END_DOCUMENT){ if (evenType==XmlPullParser.START_TAG) {Log.i(TAG, "START_TAG"+pullparser.getName());if ("operators".equals(pullparser.getName())) { operator=pullparser.nextText();}if ("style_citynm".equals(pullparser.getName())) {city=pullparser.nextText();}} evenType=pullparser.next();}} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();} //json JSONObject jsonObject =null;try {jsonObject = new JSONObject(new String(responseBody));JSONObject result = jsonObject.getJSONObject("result"); city= result.getString("style_citynm");operator = result.getString("operators");} catch (JSONException e) {// TODO Auto-generated catch blocke.printStackTrace();} TextView tv_loaction = (TextView) findViewById(R.id.tv_location);tv_loaction.setText(city+":"+operator);}@Overridepublic void onFailure(int statusCode, Header[] headers,byte[] responseBody, Throwable error) {// TODO Auto-generated method stub} } public void querybyxml_async(View v){ EditText et_number = (EditText) findViewById(R.id.et_number); String number = et_number.getText().toString(); final String path ="http://api.k780.com:88/?app=phone.get&phone="+number+"&appkey=14114&sign=ede788f7bf8d0678e281f660654ef995&format=xml"; AsyncHttpClient asyncHttpClient = new AsyncHttpClient(); asyncHttpClient.post(path, new Myhandler()); } public void querybyjson_aysnc(View v){ EditText et_number = (EditText) findViewById(R.id.et_number); String number = et_number.getText().toString(); final String path ="http://api.k780.com:88/?app=phone.get&phone="+number+"&appkey=14114&sign=ede788f7bf8d0678e281f660654ef995&format=json"; AsyncHttpClient asyncHttpClient = new AsyncHttpClient(); asyncHttpClient.post(path, new Myhandler()); }}
最后再对比下
关于轻量级和重量级
轻量级和重量级是相对来说的,那么XML相对于JSON的重量级体现在哪呢?应该体现在解析上,XML目前设计了两种解析方式:DOM和 SAX。
<1>.DOM
DOM是把一个数据交换格式XML看成一个DOM对象,需要把XML文件整个读入内存,这一点上JSON和XML的原理是一样的,但是XML要考虑父节点和子节点,这一点上JSON的解析难度要小很多,因为JSON构建于两种结构:key/value,键值对的集合;值的有序集合,可理解为数组;
<2>.SAX
SAX不需要整个读入文档就可以对解析出的内容进行处理,是一种逐步解析的方法。程序也可以随时终止解析。这样,一个大的文档就可以逐步的、一点一点的展现出来,所以SAX适合于大规模的解析。这一点,JSON目前是做不到得。
所以,JSON和XML的轻/重量级的区别在于:
JSON只提供整体解析方案,而这种方法只在解析较少的数据时才能起到良好的效果;
XML提供了对大规模数据的逐步解析方案,这种方案很适合于对大量数据的处理。
- xml及json解析
- JS 解析 JSON 及 XML
- JS 解析 JSON 及 XML
- JS 解析 JSON 及 XML
- JS 解析 JSON 及 XML
- JS 解析 JSON 及 XML
- xml解析及Json解析区别
- J2EE JS 解析 JSON 及 XML
- JSON,XML的解析及存储
- Android:json及xml解析示例
- python的XML及json解析
- Android--Json数据及Xml数据解析
- Android中XML文件解析、系列化及JSON解析
- 关于网络三 - XML 生成及解析、JSON 解析
- android中三种xml解析及Json解析方法
- JSON解析,XML解析
- JSON解析、XML解析
- XML解析 JSON解析
- Android安全--运行时验证签名
- 李大霄的黑五类
- rabbitmq helloword 例子
- Android消息队列模型——Thread,Handler,Looper,Massage Queue
- 天天刷水题~~~(此题题意有点难理解)
- xml及json解析
- 学写thinkPHP Mac10.10
- 【JavaWeb】(8)监听器
- git忽略已被跟踪的文件
- Android开发四大组件---Service详解
- 强连通分量分解 Kosaraju算法 (poj 2186 Popular Cows)
- Unity3D 与Android 相互传递消息
- [Eclispe] NDK内建include路径修改
- 子界类型、集合类型、记录类型、文件类型