XML
准备
-
junit依赖
- junit
- hamcrest-core
-
Person类
public class Person {
private String personid;
private String name;
private String address;
private String tel;
private String fax;
private String email;
@Override
public String toString() {
return "Person{" +
"personid='" + personid + '\'' +
", name='" + name + '\'' +
", address='" + address + '\'' +
", tel='" + tel + '\'' +
", fax='" + fax + '\'' +
", email='" + email + '\'' +
'}';
}
public String getPersonid() {
return personid;
}
public void setPersonid(String personid) {
this.personid = personid;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getTel() {
return tel;
}
public void setTel(String tel) {
this.tel = tel;
}
public String getFax() {
return fax;
}
public void setFax(String fax) {
this.fax = fax;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
}
- person.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>
SAX解析XML
自己编写一个数据处理器
public class PersonHandler extends DefaultHandler {
private List<Person> persons = null;
private Person p; //当前正在解析的person
private String tag; //用于记录当前正在解析的标签名
public List<Person> getPersons(){
return persons;
}
//开始解析文档时调用
@Override
public void startDocument() throws SAXException {
super.startDocument();
persons = new ArrayList<>();
System.out.println("开始解析文档...");
}
//在XML文档解析结束时调用
@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);
}
//解析结束元素时调用
@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);
}
//解析文本内容时调用
@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));
}
System.out.println(ch);
}
}
}
/**
* SAX解析的特点
* 基于事件驱动
* 顺序读取、速度快
* 不能任意读取节点(灵活性差)
* 解析时占用的内存小
* SAX更适用于在性能要求更高的设备上使用(Android开发中)
*/
@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 p : persons) {
System.out.println(p);
}
}
DOM解析(Web开发)
- 使用接口
/**
* DOM解析XML
* 基于树型结构,通过解析器一次性把文档加载到内存中,所以会比较占用内存,可以随机访问
* 更加灵活,更适合在web开发中使用
*/
@Test
public void domParseXML() 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("结果:");
System.out.println(Arrays.toString(persons.toArray()));
}
JDOM解析XML
- 使用具体的类
- 依赖
- jdom
/**
* JDOM解析XML
* 与DOM类似,基于树型结构
* 与DOM的区别: 第三方组件库、实现JAVA的Collection接口、效率比DOM更高
*/
@Test
public void jdomParseXML() throws IOException, JDOMException {
// 创建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> childen1 = element.getChildren();
for (Element e : childen1) {
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("结果:");
System.out.println(Arrays.toString(list.toArray()));
}
DOM4J解析XML
依赖
- dom4j
/**
* DOM4J解析XML
* 基于树型结构,第三方组件库
* 解析速度快、效率高,使用JAVA中的迭代器实现数据读取,在WEB框架中使用较多(Hibernate)
*/
@Test
public void dom4jParseXML() throws DocumentException {
// 1、创建DOM4J的解析器对象
SAXReader reader = new SAXReader();
InputStream is = Thread.currentThread().getContextClassLoader()
.getResourceAsStream("com/vince/xml/person.xml");
org.dom4j.Document doc = reader.read(is);
org.dom4j.Element rootElement = doc.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("结果:");
System.out.println(Arrays.toString(persons.toArray()));
}
通过对象生成XML
/**
* 把对象写入XML
*/
@Test
public void xmlEncode() {
try {
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("test.xml"));
XMLEncoder xmlEncoder = new XMLEncoder(bos);
Person p = new Person();
p.setPersonid("1212@qq.com");
p.setAddress("北京");
p.setEmail("12324@qq.com");
p.setFax("2716732472");
p.setTel("12432545");
p.setName("38");
xmlEncoder.writeObject(p);
xmlEncoder.close();
} catch (FileNotFoundException e) {
throw new RuntimeException(e);
}
}
从XML文件中读取对象
/**
* 从XML文件中读取对象
*/
@Test
public void xmlDecoder() {
try {
BufferedInputStream in = new BufferedInputStream(new FileInputStream("test.xml"));
XMLDecoder decoder = new XMLDecoder(in);
Person p = (Person) decoder.readObject();
System.out.println(p);
} catch (FileNotFoundException e) {
throw new RuntimeException(e);
}
}
使用第三方xstream组件实现XML的解析与生成
依赖
- xstream
- xpp3
@Test
public void xStream(){
Person p = new Person();
p.setPersonid("1212");
p.setPersonid("1212@qq.com");
p.setAddress("北京");
p.setEmail("12324@qq.com");
p.setFax("2716732472");
p.setTel("12432545");
p.setName("38");
XStream xStream = new XStream(new Xpp3Driver());
xStream.alias("person",Person.class);
xStream.useAttributeFor(Person.class,"personid");
String xml = xStream.toXML(p);
System.out.println(xml);
//解析XML
Person person = (Person) xStream.fromXML(xml);
System.out.println(person);
}
JSON
依赖
- gson
解析一个JSON数组
- names.json
[
{"firstName":"Vince","lastName":"Ma","email":"1791705739@qq.com"},
{"firstName":"Jason","lastName":"Hunter","email":"jason@google.com"}
]
- Name类
public class Name {
private String firstName;
private String lastName;
private String email;
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public Name() {
}
public Name(String firstName, String lastName, String email) {
this.firstName = firstName;
this.lastName = lastName;
this.email = email;
}
@Override
public String toString() {
return "Name{" +
"firstName='" + firstName + '\'' +
", lastName='" + lastName + '\'' +
", email='" + email + '\'' +
'}';
}
}
/**
* 解析一个JSON数组
*/
@Test
public void parseJSONNames(){
InputStream is = Thread.currentThread().getContextClassLoader()
.getResourceAsStream("com/vince/json/names.json");
InputStreamReader in = new InputStreamReader(is);
//JSON的解析工具(解析器)
JsonReader reader = new JsonReader(in);
ArrayList<Name> list = new ArrayList<>();
try {
//开始解析数组
reader.beginArray();
while(reader.hasNext()){
list.add(parseName(reader));
}
//结束解析数组
reader.endArray();
} catch (IOException e) {
throw new RuntimeException(e);
}
System.out.println(Arrays.toString(list.toArray()));
}
//解析对象Name
private Name parseName(JsonReader jsonReader){
Name name = null;
try {
//开始解析对象
jsonReader.beginObject();
name = new Name();
while(jsonReader.hasNext()){
String attrName = jsonReader.nextName();
if("firstName".equals(attrName)){
name.setFirstName(jsonReader.nextString());
}else if("lastName".equals(attrName)){
name.setLastName(jsonReader.nextString());
}else if("email".equals(attrName)){
name.setEmail(jsonReader.nextString());
}
}
//结束解析对象
jsonReader.endObject();
} catch (IOException e) {
throw new RuntimeException(e);
}
return name;
}
使用JsonReader解析复杂的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 JsonReader!",
"geo": [50.454722, -104.606667],
"user": {
"name": "jesse",
"followers_count": 2
}
}
]
- User类
public class User {
private String name;
private int followers_count;
public User() {
}
public User(String name, int followers_count) {
this.name = name;
this.followers_count = followers_count;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getFollowers_count() {
return followers_count;
}
public void setFollowers_count(int followers_count) {
this.followers_count = followers_count;
}
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", followers_count=" + followers_count +
'}';
}
}
- Message类
public class Message {
private long id;
private String text;
private ArrayList<Double> geo;
private User user;
public Message() {
}
public Message(long id, String text, ArrayList<Double> geo, User user) {
this.id = id;
this.text = text;
this.geo = geo;
this.user = user;
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
public ArrayList<Double> getGeo() {
return geo;
}
public void setGeo(ArrayList<Double> geo) {
this.geo = geo;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
@Override
public String toString() {
return "Message{" +
"id=" + id +
", text='" + text + '\'' +
", geo=" + geo +
", user=" + user +
'}';
}
}
- 测试解析
/**
* 使用JsonReader解析复杂的JSON数据
*/
@Test
public void parseJSONMessage(){
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) {
throw new RuntimeException(e);
}
return list;
}
/**
* 解析一个Message对象
* @param jsonReader
* @return
*/
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) {
throw new RuntimeException(e);
}
return m;
}
/**
* 解析User
* @param jsonReader
* @return
*/
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) {
throw new RuntimeException(e);
}
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) {
throw new RuntimeException(e);
}
return list;
}
创建JSON
@Test
public void createJSON(){
List<Name> list = new ArrayList<>();
list.add(new Name("vince","ma","123435@qq.com"));
list.add(new Name("April","Smily","12324@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对象,或把一个JAVA对象转换成JSON对象
- name.json
{"firstName":"Vince","lastName":"Ma","email":"1791705739@qq.com"}
- 测试
@Test
public void gson1(){
Gson gson = new Gson();
InputStream is = Thread.currentThread().getContextClassLoader()
.getResourceAsStream("com/vince/json/name.json");
InputStreamReader in = new InputStreamReader(is);
Name name = gson.fromJson(in,Name.class);
System.out.println(name);
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>>(){};
List<Name> list = gson.fromJson(in, typeToken.getType());
System.out.println(list);
String json = gson.toJson(list, typeToken.getType());
System.out.println(json);
}
class MyTypeToken extends TypeToken<List<Name>>{}