XML/JSON
XML文档编写
XML & HTML
XML:extensible markup language可扩展标记语言
XML | HTML | |
后缀 | .xml | .html .htm |
可扩展性 | 支持自定义标签 | 不支持自定义标签,都是预定义的 |
严谨性 | 更严谨: 必须有合理的闭合符号 只能有一个根标签 属性值必须有单双引号 区分大小写 | 不严谨: 标签闭合符/可不写 属性单双引号可不写 不区分大小写 |
作用 | 文件配置 | 浏览器页面展示 |
语法
xml的第一行必须是命名空间(如下,限制了版本号和编码格式)
<? xml version="1.0" encoding="UTF-8"?>属性值必须由单双引号包裹
必须有合理的闭合符号
有且只能有一个根标签
标签区分大小写
组成
命名空间
引入使用的dtd约束文档 XXX.dtd
标签及内容
自定义标签的约束限制
dtd
描述自定义标签约束,是一种简单的约束
约束内容
有哪些标签
标签间的嵌套关系
标签属性
标签出现次数
dtd示例 | 解释 | 相关标签 | 标签用途 |
---|---|---|---|
<! ELEMENT users(user*)> | users是整个xml的根标签,users下可以有user这个子标签(0-无数次) | ELEMENT (XX) + * | 定义标签名 标签下可以存在XX子标签 正则标准,表示出现次数 |
<! ELEMENT user(username+,password)> | user下可以有username和password两个标签,其中username至少出现1次 | + * | 正则标准,表示出现次数 |
<! ELEMENT username(#PCDATA)> | username标签内容为字符串 | #PCDATA | 内容为字符串 |
<! ELEMENT password(#PCDATA)> | password标签内容为字符串 | #PCDATA | 内容为字符串 |
<! ATTLIST user number ID #REQUEIRED> | user标签下必须由number这个属性,且number属性是唯一标识 | ATTLIST #REQUEIRED #ID | 用于定义标签的属性 该属性是必写的 该属性是唯一标识(不可重复) |
Schema(xsd)
在xml的基础上限制了标签内容&属性的取值范围合理性
定义可出现在文档中的元素
定义可出现在文档中的属性
定义哪个元素是子元素
定义子元素的次序
定义子元素的数目
定义元素是否为空,或者是否可包含文本
定义元素和属性的数据类型
定义元素和属性的默认值以及固定值
对标签的属性通过type=""进行定义,再对该type进行额外定义
xml解析
将xml中的内容读取到内存
解析方式
-
dom解析
将xml内容整体解析到内存,形成一颗dom树,可删改属性但耗内存;
适用场景:解析服务器中的xml(服务器内存大且增删改需求大) -
sax解析
将xml内容逐行解析到内存(事件驱动),不可删改属性但省内存;
适用场景:解析移动设备中的xml(内存小且增删改需求少)
解析器
解析工具/解析器 | 介绍 | 解析方式 |
---|---|---|
dom4j | 可以使用dom/sax方式解析 | |
jsoup | 类似js/jQuery的方法 | 用dom方式解析 |
pull | Android自带的解析器 | 使用sax方式解析 |
Jsoup解析使用
方式1:
页面元素对象的类:Node–Element–Document
document对象的方法:
getElementById
getElemenstByClass
getElementsByTagName
attr
getElementByAttribute
getElementByAttributevalue
方式2:选择器
Element对象.select( “#2” );
选择器名 | 写法 | 含义 |
---|---|---|
id选择器 | #2 | id值为指定值 的元素 id=“2” |
类选择器 | .t | class=“t” 指定类的元素 |
标签选择器 | name | <name>标签对应元素 |
后代选择器 | .t > name | class=“t” 标签对应元素下<name>子标签对应的元素 |
属性选择器 | span[id=2] | 标签span下存在id属性且属性值为2的元素 |
方式3:JsoupXpath.jar
导包,创建jxdocument对象,调用selN selNOne 等方法,根据匹配规则 配置路径的规则 获取元素对象
JSON
含义:JS 对象表示法(JavaScript Object Notation),是一种 对象在前端页面进行传输和表示的形式
比xml更小更快更易解析
用于存储、交换文本信息
语法
标准形式
var person={"键1":"值1","键2":"值2","键3":"值3"...};
键 可以使用"" 或 ‘’ 包裹或不包裹
值 字符/字符串必须使用"" 或 ‘’ 包裹;数字无需包裹,数组用[1,2,3]表示
键值间用:连接
JSON数组嵌套JSON对象
var persons = [
{"键1":"值1","键2":"值2"...},
{"键1":"值1","键2":"值2"...},
{"键1":"值1","键2":"值2"...},
...
];
JSON对象嵌套JSON数组
var school={
"grade":[{"gradelevel":"7","classnum":"8",...},{"gradelevel":"8","classnum":"12",...},{}...],
"location":{"privince":"Shanghai","city":"Baoshan",...},
"employee":[{"level":"4","name":"工人","empNums":"300"},
{"level":"5","name":"主管","empNums":"60"},
{"level":"6","name":"普通教师","empNums":"39"},
{"level":"7","name":"教学主管","empNums":"8"},
{"level":"8","name":"教务主任","empNums":"3"},
{}...],
...
}
多层嵌套
{"nation":[
{"nationname":"China",
"province":[
{"provincename":"Henan",
"provincenum":"20",
"city":[
{"cityname":"郑州",
"area":"20",
"street":[{},{}]},
{"cityname":"开封",
"area":"20",
"street":[{},{}]}
]},
{"provincename":"上海",
"provincenum":"20",
"city":[]},
{"provincename":"北京",
"provincenum":"20",
"city":[]},
{"provincename":"深圳",
"provincenum":"20",
"city":[]},
{"provincename":"广州",
"provincenum":"20",
"city":[]},
{"provincename":"江苏",
"provincenum":"20",
"city":[]}
]
},
{"nationname":"American","province":[]},
{"nationname":"England","province":[]}
]
}
获取
获取单个元素
json对象.键
json对象[“键”]
遍历
function f(x){
//如果是json对象,需要使用in遍历其中的属性键值对
for(var y in x){
//每次进入此处是新的一层,换行
document.writeln("<br>");
var ele = x[y];
//如果其属性值是简单的数字或字符,直接输出属性名和属性值(递归出口)
if(typeof(ele)=='string'||typeof(ele)=='number' ){
document.writeln(y+"====="+ele);
continue;
}
//如果属性的值不是简单的数字或字符,而是对象数组,则遍历数组,得到数组中的json对象,再调用方法本身
for(var j = 0;j<ele.length;j++){
var ele2 = ele[j];
f(ele2);
}
//大循环走到最后,即最开始进入循环的地方走完(一个国家走完),换行
document.writeln("<br>");
}
}
此key获取到就自带“”,故无需再加双引号,也不能用.获得
解析:java对象< — >json数据
java对象与json数据的转换,即获取json对象的属性值再封装
常用解析器
Jackson:spring内置
jsonlib:java自带
gson:Google(读作 go Son)
fastjson:阿里巴巴
Jackson
使用步骤:
- 导包
- 创建核心类对象 ObjectMapper对象
- 调用方法读取Json文本->java对象 / 将java对象以json形式写入文本
- java对象 —> json文本
- writeValue(输出流对象,java对象)
- writeValueasString(java对象)
- Json文本 —> java对象
- readValue(输出流对象,java对象)
- java对象 —> json文本
用于属性的注解
@JsonIgnore(将对象写成json时忽视此属性)
@JsonFormat(pattern=“yyyy-MM-dd”)(将对象写成json时按此格式化)
双引号需要转义 \"
示例:
public class demo1 {
public static void main(String[] args) throws Exception{
User user = new User("aa", 28,new Date());
User user1 = new User("ab", 13,new Date(2013,1,1));
User user2 = new User("bb", 32,new Date(2014,4,3));
User user3 = new User("bc", 55,new Date(2015,7,19));
List<User> users =new ArrayList<User>();
users.add(user);
users.add(user1);
users.add(user2);
users.add(user3);
//创建核心类对象,用于调取解析的方法
ObjectMapper mapper = new ObjectMapper();
mapper.writeValue(new FileOutputStream("D://kk.txt"), users);
mapper.writeValue(new FileOutputStream("D://kk2.txt"), user);
mapper.writeValue(new FileOutputStream("D://kk3.txt"), user1);
//对象-->json文本
String usersString = mapper.writeValueAsString(users);
System.out.println("1====="+usersString);
//json字符串-->java对象
User jackson = mapper.readValue("{\"username\":\"ca\",\"age\":62}", User.class);
System.out.println("2====="+jackson);
//json字符串(复杂)-->java对象
List list = mapper.readValue("[{\"aa\": 28},{\"bb\":22}]", List.class);
for (Object object : list) {
System.out.println("5====="+object);
}
System.out.println("6====="+list);
//json文本(文本中只有一个简单对象)-->java对象
User jackson3 = mapper.readValue(new FileInputStream("D://kk2.txt"), User.class);
System.out.println("4====="+jackson3);
//json文本(涉及泛型)-->java对象
List<User> jackson2 = mapper.readValue(new FileInputStream("D://kk.txt"), new TypeReference<List<User>>(){});
System.out.println("3====="+jackson2);
//json文本-->List对象(内容只是打印出来没有封装成User对象)
List<User> jackson21 = mapper.readValue(new FileInputStream("D://kk.txt"), users.getClass());
System.out.println("301====="+jackson21);
}
}