1. XML的简介
1.1 什么是xml:eXtensible Markup Language,可扩展标记型语言
(1)标记型语言:html是标记型语言,都是使用标签进行操作;xml里面的操作也是使用标签来进行的
(2)可扩展:html里面的标签,每个标签都有自己的特定的含义,比如<br/><hr/r>,在xml中标签自己定义的,比如<aa><猫>
(3)xml的主要功能是存储数据,而不是显示数据
(4)xml的版本1.0 1.1,一般使用的是1.0版本
1.2 xml的应用,主要应用在三个地方
(1)xml用于作为系统之间传输数据的格式
(2)xml用于表示生活中有关系的数据
比如:<中国><江苏><南京></南京><苏州></苏州></江苏></中国>
(3)xml经常使用在系统的配置文件中
2. xml的语法
2.1 xml的文档声明
(1)如果创建xml文件,在xml中必须要有一个文档声明
(2)写法:<?xml version="1.0" encoding="utf-8"?>
version:必须要有,xml的版本,一般是使用1.0
encoding:可选的,xml的编码方式
standalone:可选的,xml是否依赖其他文件 yes no
(3)注意:文档声明需要放在xml文件的第一行一列,否则文件不读
2.2 xml的元素的定义
(1)xml中的标签定义,有开始标签也要有结束标签
(2)有的标签没有内容(没有结束标签,类似html<br/>),需要在标签内结束
(3)xml中的标签可以嵌套,但是必须合理嵌套<a><b></a></b>:这样就是不对的。必须:<a><b></b></a>
(4)一个XML的文档必须有且仅有一个根标签,其他标签都是这个根标签的子标签或者孙标签
(5)命名规范
第一:xml区分大小写;
第二:xml的标签不能以数字或者下划线“_”开头。
第三:xml的标签不能以xml(xml,Xml等)开头
第四:在xml的标签里面不能包含空格。<a b>是错的
第五:在xml的标签里面不能包含冒号。<aa:bb>是错的
2.3 xml的属性的定义
(1)在xml的标签里面可以有多个属性,但是属性的名称不能相同
(2)属性和属性值之间需要使用=隔开,属性值需要使用引号抱起来(双引号或者单引号)
(3)属性名称的命名规范与元素的命名规范相同
2.4 xml的注释:
和html一样<!-- 注释内容 -->,注释是不可以嵌套的
2.5 xml的CDATA区
(1)格式:< ! [CDATA[ 内容 ] ] >
(2)把CDATA区里面的内容当做普通文本内容,二不是标签来进行处理
3. xml的解析简介
3.1 xml解析的分类
(1)解析xml有三种方式
第一种方式:dom解析
第二种方式:sax解析
第三种方式:pull解析(重点,Android使用这个解析)
3.2 dom解析xml
(1)根据xml的层级结构在内存中分配一个树形结构
document:代表整个文档
element:代表元素对象(标签)
属性对象
文本对象
node节点对象,是上面对象的父对象
(2)dom解析xml的优点:
因为分配了一个树形结构,很方便的实现增加 修改 删除的操作
(3)dom解析的缺点:
如果需要解析的文件过大,一次性在内存中分配一个树形结构,造成内存溢出
3.3 sax解析xml
(1)sax解析的方式:边读边解析
当使用sax解析督导特定标签的时候,自动调用相应的方法进行操作
(2)sax解析xml的优点:不会造成内存的溢出
(3)sax解析xml的缺点:不能实现增加、修改、删除的操作
3.4 pull解析xml:首先,导入pull的jar包(两个jar包)
· 使用pull解析xml文件,可以把xml中的内容放到集合里面
步骤:
1. 创建解析器工厂
XmlPullParserFactory
2. 根据解析器工厂创建解析器
3. 把要操作的文件放到解析器
代码:
· xml文件:存放在myeclise工具的src目录下的
· 并且创建一个User的javbean对象,根据xml文件,里面有username和age属性<?xml version="1.0" encoding="UTF-8"?> <users> <user> <username>赵云</username> <age>20</age> </user> <user> <username>刘备</username> <age>50</age> </user> <user> <username>关羽</username> <age>35</age> </user> </users>
· 解析代码(反序列化):
//创建解析器工厂 XmlPullParserFactory factory = XmlPullParserFactory.newInstance(); //根据工厂创建解析器 XmlPullParser parser = factory.newPullParser(); //把要解析的xml文件放到解析器中 parser.setInput(new FileInputStream("src/data.xml"), "utf-8"); List<User> list = null; User user = null; int type; //根据xml文件开始解析 //获取每个标签的int值,当这个值不等于文档结束标签时继续运行 while((type=parser.getEventType()) != XmlPullParser.END_DOCUMENT) { String tagName = parser.getName();//获取标签的名字 switch (type) { //当标签的值读到开始元素时 case XmlPullParser.START_TAG : if(tagName.equals("users")) { list = new ArrayList<User>(); } else if(tagName.equals("user")) { user = new User(); } else if(tagName.equals("username")) { String name = parser.nextText(); user.setName(name); } else if(tagName.equals("age")) { int age = Integer.parseInt(parser.nextText()); user.setAge(age); } break; //当标签的值读到结束元素时 case XmlPullParser.END_TAG : if(tagName.equals("user")) { list.add(user); } break; } parser.next(); } //输出到控制台 for(User u : list) { System.out.println(u); }
4. xml的序列化:将存储的数据写到xml文件中
· 输出的结构和反序列化的过程基本一致
· 换行代码;serializer.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output",true);
· 具体代码实现:
//提前写好一个对象的数据,存到xml文件 List<User> list = new ArrayList<User>(); list.add(new User("关羽",35)); list.add(new User("张飞",38)); list.add(new User("刘备",40)); //获取解析器工厂 XmlPullParserFactory factory = XmlPullParserFactory.newInstance(); //根据工厂获取解析器 XmlSerializer serializer = factory.newSerializer(); //把要操作的xml文件 放到解析器中 serializer.setOutput(new FileOutputStream("newData.xml"), "utf-8"); //解析xml //开头 serializer.startDocument(null, true); serializer.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output",true); serializer.startTag(null, "users"); for(User u : list) { serializer.startTag(null, "user"); serializer.startTag(null, "name"); serializer.text(u.getName()); serializer.endTag(null, "name"); serializer.startTag(null, "age"); serializer.text(u.getAge()+""); serializer.endTag(null, "age"); serializer.endTag(null, "user"); } serializer.endTag(null, "users"); serializer.endDocument();