XML与JSON解析
来源:互联网 发布:访问远程oracle数据库 编辑:程序博客网 时间:2024/05/17 08:00
1、什么是XML
XML(Extensible Markup Language 可扩展标记语言),XML是一个以文本来描述数据的文档。
<?xml version="1.0" encoding="UTF-8"?><people> <person personid="E01"> <name>Tony Blair</name> <address>10 Downing street,London,UK</address> <tel>(061) 98765</tel> <fax>(061) 98765</fax> <email>blair@everywhere.com</email> </person> <person personid="E02"> <name>Bill Clinton</name> <address>White House,USA</address> <tel>(001) 6400 98765</tel> <fax>(001) 6400 98765</fax> <email>bill@everywhere.com</email> </person></people>
2、XML的用途
XML技术的用途:
1、充当显示数据(以XML充当显示层)
2、存储数据(存储层)的功能
3、以XML描述数据,并在联系服务器与系统的其余部分之间传递。(传输数据一样的格式)
从某种角度讲,xml是数据封装和消息传递技术。
3、SAX解析XML
SAX是 Simple API for XML 的缩写。
SAX是读取和操作XML数据更快速、更轻量的方法。SAX允许您在读取文档时处理它,从而不必等待整个文档被存储以后才采取操作。不涉及DOM所必须的开销和概念跳跃。SAX API是一个基于事件的API,适用于处理数据流,即随着数据的流动而依次处理数据。SAX API在其解析文档时发生一定事件的时候会通知您。在您对其相应时,您不做保证的数据将会被抛弃。
SAX API 中主要有四种处理事件的接口,ContentHandler,DTDHandler,EntityResolver和 ErrorHandler。实际只要继承DefaultHandler类就可以,DefaultHandler实现了这四个事件处理器接口,然后提供了每个抽象方法的默认实现。
public class Person { private String personid; private String name; private String address; private String tel; private String fax; private String email; getter and setter ...}
/** * Created by zxm on 2017/7/24. * SAX 解析的特点: * 1、基于事件驱动 * 2、顺序读取,速度快 * 3、不能任意读取节点(灵活性较差) * 4、解析时占用的内存小 * 5、SAX更适用于在性能要求更高的设备上使用(如安卓开发中) */public class PersonHandler extends DefaultHandler { private List<Person> persons=null; private Person p;//当前正在解析的对象 private String tag;//当前解析的标签 public List<Person> getPersons() { return persons; } //开始解析文档时调用 @Override public void startDocument() throws SAXException { super.startDocument(); persons=new ArrayList<>(); System.out.println("开始解析文档。。。"); } //结束解析文档时调用 @Override public void endDocument() throws SAXException { super.endDocument(); System.out.println("结束解析文档。。。"); } /** * 解析开始元素时调用 * @param uri 命名空间 * @param localName 不带前缀的标签名 * @param qName 带前缀的标签名 * @param attributes 当前标签的属性集合 * @throws SAXException */ @Override public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { super.startElement(uri, localName, qName, attributes); if("person".equals(qName)){ p=new Person(); String personid=attributes.getValue("personid"); p.setPersonid(personid); } tag=qName; System.out.println("startElement:"+qName); } /** * 解析结束元素时调用 * @param uri * @param localName * @param qName * @throws SAXException */ @Override public void endElement(String uri, String localName, String qName) throws SAXException { super.endElement(uri, localName, qName); if ("person".equals(qName)){ persons.add(p); } tag=null; System.out.println("endElement:"+qName); } //解析文本内容时调用,包括标签之间的空格回车//char[] ch为整个文档的字符数组,start是每次的起始位置 @Override public void characters(char[] ch, int start, int length) throws SAXException { super.characters(ch, start, length); if(tag!=null){ if("name".equals(tag)){ p.setName(new String(ch,start,length)); }else if("address".equals(tag)){ p.setAddress(new String(ch,start,length)); }else if("tel".equals(tag)){ p.setTel(new String(ch,start,length)); }else if("fax".equals(tag)){ p.setFax(new String(ch,start,length)); }else if("email".equals(tag)){ p.setEmail(new String(ch,start,length)); } } }}
@Test public void saxParseXMl() throws ParserConfigurationException, SAXException, IOException { //1、创建一个SAX解析器工厂对象 SAXParserFactory saxParserFactory=SAXParserFactory.newInstance(); //2、通过工厂创建SAX解析器 SAXParser saxParser=saxParserFactory.newSAXParser(); //3、创建一个数据解析器(需要自己编写) PersonHandler personHandler=new PersonHandler(); //4、开始解析 InputStream is=Thread.currentThread().getContextClassLoader().getResourceAsStream("com/vince/xml/person.xml"); saxParser.parse(is,personHandler); List<Person> persons=personHandler.getPersons(); for(Person person:persons){ System.out.println(person); } }
4、DOM解析XML
DOM:Document Object Model(文档对象模型)
DOM的特性:
定义一组Java接口,基于对象,与语言和平台无关将XML文档表示为树,在内存中解析和存储XML文档,允许随机访问文档的不同部分。
DOM解析XML:
DOM的优点,由于树在内存中是持久的,因此可以修改后更新。它可以在任何时候在树中上下导航,API使用起来也比较简单。
/** * DOM 解析MXL * 1、基于树形结构,通过解析器一次性吧文档加载到内存中,所以会比较占用内存,可以随机访问 * 更加灵活,更适合在WEB开发中使用 */ @Test public void domPaeseXML() throws ParserConfigurationException, IOException, SAXException { //1.创建一个DOM解析器工厂对象 DocumentBuilderFactory factory=DocumentBuilderFactory.newInstance(); //2.通过工厂对象创建解析器对象 DocumentBuilder documentBuilder=factory.newDocumentBuilder(); //3.解析文档 InputStream is=Thread.currentThread().getContextClassLoader().getResourceAsStream("com/vince/xml/person.xml"); //此代码完成后,整个XML文档已经被加载到内存中,以树状形式存储 Document doc = documentBuilder.parse(is); //4.从内存中读取数据 //获取节点名称为person的所有节点,返回节点集合 NodeList personNodeList=doc.getElementsByTagName("person"); ArrayList<Person> persons=new ArrayList<>(); Person p=null; for (int i = 0; i < personNodeList.getLength(); i++) { Node personNode=personNodeList.item(i); p=new Person(); //获取节点的属性值 String personid=personNode.getAttributes().getNamedItem("personid").getNodeValue(); p.setPersonid(personid); //获取当前节点的所有子节点 NodeList childNodes=personNode.getChildNodes(); for (int j = 0; j < childNodes.getLength(); j++) { Node item=childNodes.item(j); String nodeName=item.getNodeName(); if("name".equals(nodeName)){ p.setName(item.getFirstChild().getNodeValue()); }else if("address".equals(nodeName)){ p.setAddress(item.getFirstChild().getNodeValue()); }else if("tel".equals(nodeName)){ p.setTel(item.getFirstChild().getNodeValue()); }else if("fax".equals(nodeName)){ p.setFax(item.getFirstChild().getNodeValue()); }else if("email".equals(nodeName)){ p.setEmail(item.getFirstChild().getNodeValue()); } } persons.add(p); } System.out.println(Arrays.toString(persons.toArray())); }
5、JDOM解析XML
JDOM是两位著名的 Java 开发人员兼作者,Brett Mclaughlin 和 Jason Hunter 的创作成果, 2000 年初在类似于Apache协议的许可下,JDOM作为一个开放源代码项目正式开始研发了。
JDOM简化了与XML的交互并且比使用DOM实现更快,JDOM与DOM主要有两方面不同。首先,JDOM仅使用具体类而不适用接口。这在某些方面简化API,但是也限制了灵活性。第二,API大量使用了Collections类,简化了那些已经熟悉这些类的Java开发者使用。
下载地址:http://www.jdom.org/downloads/index.html
/** * JDOM 解析XML * 1、与DOM类型基于树形结构。 * 2、与DOM的区别: * (1)第三方开源的组件 * (2)实现使用JAVA的Collection接口 * (3)效率比DOM更快 */ @Test public void jdomParseXML() throws JDOMException, IOException { //创建JDOM解析器 SAXBuilder builder=new SAXBuilder(); InputStream is=Thread.currentThread().getContextClassLoader().getResourceAsStream("com/vince/xml/person.xml"); org.jdom2.Document build=builder.build(is); Element rootElement=build.getRootElement(); List<Person> list=new ArrayList<>(); Person person=null; List<Element> children=rootElement.getChildren(); for(Element element:children){ person=new Person(); String personid=element.getAttributeValue("personid"); person.setPersonid(personid); List<Element> children1=element.getChildren(); for(Element e:children1){ String tag=e.getName(); if("name".equals(tag)){ person.setName(e.getText()); }else if("address".equals(tag)){ person.setAddress(e.getText()); }else if("tel".equals(tag)){ person.setTel(e.getText()); }else if("fax".equals(tag)){ person.setFax(e.getText()); }else if("email".equals(tag)){ person.setEmail(e.getText()); } } list.add(person); } System.out.println(Arrays.toString(list.toArray())); }
6、DOM4J解析XML
dom4j是一个非常优秀的Java XML API,具有性能优异、功能强大和极端易用的特点,同时它也是一个开放源代码的软件,可以在SourceForge上找到它。Sun的JAXM也在使用dom4j,Hibernate用它来读写配置文件。
下载地址:https://dom4j.github.io/
/** * DOM4J 解析XML * 基于树型结构,第三方组件 * 解析速度快,效率更高,使用Java中的迭代器实现数据读取,在web框架中使用较多(Hibernate) */ @Test public void dom4jParseXML() throws DocumentException { //1.创建DOM4J的解析器对象 SAXReader saxReader=new SAXReader(); InputStream is=Thread.currentThread().getContextClassLoader().getResourceAsStream("com/vince/xml/person.xml"); org.dom4j.Document document=saxReader.read(is); org.dom4j.Element rootElement=document.getRootElement(); Iterator<org.dom4j.Element> iterator=rootElement.elementIterator(); ArrayList<Person> persons=new ArrayList<>(); Person p=null; while (iterator.hasNext()){ p=new Person(); org.dom4j.Element e=iterator.next(); p.setPersonid(e.attributeValue("personid")); Iterator<org.dom4j.Element> iterator1=e.elementIterator(); while (iterator1.hasNext()){ org.dom4j.Element next=iterator1.next(); String tag=next.getName(); if("name".equals(tag)){ p.setName(next.getText()); }else if("address".equals(tag)){ p.setAddress(next.getText()); }else if("tel".equals(tag)){ p.setTel(next.getText()); }else if("fax".equals(tag)){ p.setFax(next.getText()); }else if("email".equals(tag)){ p.setEmail(next.getText()); } } persons.add(p); } System.out.println(Arrays.toString(persons.toArray())); }
7、各种XML解析方法比较
在处理DOM的时候,我们需要读入整个的XML文档,然后在内存中创建DOM树,生成DOM树上的每个Node对象。当文档比较小的时候,这不会造成什么问题,但是一旦文档大起来,处理DOM就会变得相当费时费力。特别是其对于内存的需求,也将是成倍的增长,JDOM和DOM 在文档超过10M时易发生内存溢出。
SAX较轻量,是事件驱动,它并不需要读入整个文档,而文档的读入过程也就是SAX的解析过程。
DOM4J性能优异、功能强大和极端易用,许多开源项目中大量使用DOM4J。
8、通过对象生成XML文件
/** * 把对象转化为xml */ @Test public void xmlEnCoder() throws FileNotFoundException { BufferedOutputStream bos=new BufferedOutputStream(new FileOutputStream("test.xml")); XMLEncoder xmlEncoder=new XMLEncoder(bos); Person p=new Person(); p.setName("zxm"); p.setPersonid("123"); p.setEmail("zxm@qq.com"); p.setFax("1306123456"); p.setTel("1306123456"); p.setAddress("北京"); xmlEncoder.writeObject(p); xmlEncoder.close(); } /** * 从XML文件读取对象 */ @Test public void xmlDeCoder() throws FileNotFoundException{ BufferedInputStream in=new BufferedInputStream(new FileInputStream("test.xml")); XMLDecoder decoder=new XMLDecoder(in); Person p= (Person) decoder.readObject(); System.out.println(p); } /** *使用第三方xStream组件实现XML的解析与生成,多用于传输数据时对字符串进行处理 * 需要导入xstream-1.4.10.jar和xpp3_min-1.1.4c.jar */ @Test public void XStream(){ Person p=new Person(); p.setName("zxm"); p.setPersonid("123"); p.setEmail("zxm@qq.com"); p.setFax("1306123456"); p.setTel("1306123456"); p.setAddress("北京"); XStream xStream = new XStream(new Xpp3Driver()); xStream.alias("person",Person.class);//为Person.class 设置别名为person xStream.useAttributeFor(Person.class,"personid");//将personid子项作为Person.class的属性 String xml= xStream.toXML(p); System.out.println(xml); //解析XML Person person = (Person)xStream.fromXML(xml); System.out.println(person); }
9、JSON
JSON(JavaScript Object Notation, JS 对象标记)是一种轻量级的数据交换格式。
JSON 构建于两种结构:
1、“名称/值”对的集合
如:{“firstName”:”vince”,”lastName”:”ma”,”age”:23}
2、值的有序列表(数组)
如:{“user”:[ {“firstName”:”vince”,”lastName”:”ma”,”age”:23} , {“firstName”:”Lily”,”lastName”:”Jack”,”age”:18} ]}
10、GSON组件的使用
GSON是Google开发的Java API,用于转换Java对象和Json对象。
下载地址:http://www.mvnrepository.com/artifact/com.google.code.gson/gson
解析json
例子:
解析message.json 文件
[ { "id":912345678901, "text":"How do I read a JSON stream in java?", "geo":null, "user":{ "name":"json_newb", "followers_count":41 } }, { "id":912345678902, "text":"@json_newb just use Json Reader!", "geo":[50.45645,-654.46], "user":{ "name":"jesse", "followers_count":2 } }]
根据要解析的json文件写实体类:
Message.java
public class Message { private long id; private String text; private ArrayList<Double> geo; private User user; getter and setter...}
User.java
public class User { private String name; private int followers_count; getter and setter...}
@Test public void parseJSONMessages(){ InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream("com/vince/json/message.json"); InputStreamReader in=new InputStreamReader(is); JsonReader jsonReader=new JsonReader(in); ArrayList<Message> list=readMessageArray(jsonReader); for (Message m:list) { System.out.println(m); } } //读取Message数组 private ArrayList<Message> readMessageArray(JsonReader jsonReader) { ArrayList<Message> list=new ArrayList<>(); try { jsonReader.beginArray(); while (jsonReader.hasNext()){ list.add(readMessage(jsonReader)); } jsonReader.endArray(); } catch (IOException e) { e.printStackTrace(); } return list; } //解析一个Message对象 private Message readMessage(JsonReader jsonReader) { Message m=new Message(); try { jsonReader.beginObject(); while (jsonReader.hasNext()){ String name=jsonReader.nextName(); if("id".equals(name)){ m.setId(jsonReader.nextLong()); }else if("text".equals(name)){ m.setText(jsonReader.nextString()); }else if ("geo".equals(name)&&jsonReader.peek()!= JsonToken.NULL){ m.setGeo(readGeo(jsonReader)); }else if ("user".equals(name)){ m.setUser(readUser(jsonReader)); }else { jsonReader.skipValue(); } } jsonReader.endObject(); } catch (IOException e) { e.printStackTrace(); } return m; } //解析User对象 private User readUser(JsonReader jsonReader) { User user=new User(); try { jsonReader.beginObject(); while (jsonReader.hasNext()){ String name=jsonReader.nextName(); if("name".equals(name)){ user.setName(jsonReader.nextString()); }else if ("followers_count".equals(name)){ user.setFollowers_count(jsonReader.nextInt()); }else { jsonReader.skipValue(); } } jsonReader.endObject(); } catch (IOException e) { e.printStackTrace(); } return user; } //解析geo数组 private ArrayList<Double> readGeo(JsonReader jsonReader) { ArrayList<Double> list=new ArrayList<>(); try { jsonReader.beginArray(); while (jsonReader.hasNext()){ list.add(jsonReader.nextDouble()); } jsonReader.endArray(); } catch (IOException e) { e.printStackTrace(); } return list; }
生成json
//将java对象转为json字符串 @Test public void createJSON(){ List<Name> list=new ArrayList<>(); list.add(new Name("vince","ma","17834641@qq.com")); list.add(new Name("jack","wang","jack@qq.com")); JsonArray array=new JsonArray(); for (Name n:list) { JsonObject obj=new JsonObject(); obj.addProperty("firstName",n.getFirstName()); obj.addProperty("lastName",n.getLastName()); obj.addProperty("email",n.getEmail()); array.add(obj); } System.out.println(array.toString()); }
JSON对象与JAVA对象的直接互转
//把一个JSON对象转换为JAVA对象,或把一个JAVA对象转换成JSON对象 @Test public void gson1(){ Gson gson=new Gson(); InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream("com/vince/json/name.json"); InputStreamReader in=new InputStreamReader(is); //把json转为name对象 Name name=gson.fromJson(in,Name.class); System.out.println(name); //将name对象转为json字符串 String json=gson.toJson(name); System.out.println(json); } //把一组JSON对象转换成一个JAVA对象集合,或者把一个JAVA对象集合转换为一组JSON对象 @Test public void gson2(){ Gson gson=new Gson(); InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream("com/vince/json/names.json"); InputStreamReader in=new InputStreamReader(is); TypeToken<List<Name>> typeToken = new TypeToken<List<Name>>(){};//相当于new了一个TypeToken的子类,为了指定泛型 List<Name> list=gson.fromJson(in,typeToken.getType()); System.out.println(list); String json=gson.toJson(list,typeToken.getType()); System.out.println(json); }
11、XML与JSON的比较
1、JSON和XML的数据可读性基本相同。
2、JSON和XML同样拥有丰富的解析手段
3、JSON相对于XML来讲,数据的体积小
4、JSON与JavaScript的交互更加方便
5、JSON对数据的描述性比XML较差
6、JSON的速度要远远快于XML
使用的场景:
数据传输:JSON速度更快
存储数据:MXL描述性更强
配置文件:用XML
- XML与JSON解析
- XML与JSON解析
- XML解析 与 JSON 解析
- PHP解析JSON与XML
- PHP解析JSON与XML
- XML与JSON的解析
- Android xml与json解析
- Unity Json与Xml解析
- Json解析与XML解析的demo
- json与xml创建与解析
- PHP解析JSON与XML(简介)
- android json与xml解析 例子
- XML文件解析&操作&与JSON比较
- 使用 C#合成解析XML与JSON
- Qt5中JSON与XML的解析
- XML和JSON解析-----定义与比较
- 数据解析之 XML与JSON
- Json与XML解析的区别比较
- C#知识积累
- LBG矢量量化算法
- 数组——找最大值
- d3 绘制中国地图城市及城市间的连线
- 【代码片-1】 Project Perfect让Swift在服务器端跑起来-引言(一)
- XML与JSON解析
- 斐波那契数列的两种实现
- 网易Emmagee简单改造
- Java EE编程技术学习笔记(4)-JDBC
- RxJava倒计时
- Large Division LightOJ
- POJ 3670
- HDU 2054 A==B?
- Linux--进程控制