XML:可扩展标记语言,标签名可以自定义,但不能以数字开头,不能是纯数字,区分大小写。
(一)功能:
1)用作配置文件;
2)用作网络数据传输的载体,用作PC端数据传输的载体(JSON一般用于移动端的数据传输的载体)。
(二)组成部分:
1)文档声明:<?xml veersion="1.0" encoding="utf-8"?> ,文档声明必须顶行顶格写;
2)根标签:有且仅有一个根标签;
3)其他标签:标签必须成对出现,有开始标签就必须要有结束标签;
4)文本
(三)Xml与Html区别:
1)html的标签是固定的,不能扩展。xml的标签是不固定的,可扩展的。
2)html侧重于显示的信息。xml侧重于标识信息的结构。
3)html是不区分大小写的。xml是区分大小写的。xml的语法比html更严谨。
(四)XML解析思想
1)DOM(Document Object Model)---文档对象模型:将文档一次性加载进内存,将文档的各个组成部分抽取为一个对象。
Element ---标签对象;Attribute---属性对象;Text---文本对象;Commen---注释对象;Node---节点对象;Document---文档对象。
优点:能够对文档进行增删改查;
缺点:耗内存,适用于PC端。
2)SAX:基于事件,逐行解析,一次读取一行解析一行。
SAX在概念上与DOM完全不同。首先,不同于DOM的文档驱动,它是事件驱动的, 也就是说,它并不需要先读入整个文档,文档
的读入过程也就是SAX的解析过程。
所谓事件驱动,是指一种基于回调(callback)机制的程序运行方法。 在XMLReader接受XML文档,在读入XML文档的过程中就
进行解析,也就是说读入文档的过程和解析的过程是同时进行的,这和DOM区别很大。
优点:不占内存,适用于移动端;
缺点:只能查,不能增删改。
(五)常用的XML解析器
DOM4J:第三方jar包,实现了DOM思想
SAX:第三方jar包,实现了SAX思想
Pull解析器:第三方jar包,实现了SAX思想
1)DOM4J
// 导入DOM4J jar包
// 创建解析器对象
SAXReader reader = new SAXReader();
Document doc = reader.read(new FileInputStream("students.xml"));
// 获取根标签对象
Element rootElement = doc.getRootElement();
// 获取根标签下的子标签 默认获取的是第一个子标签
Element stuElement = rootElement.element("student");
System.out.println(stuElement.getName());
// 获取所有的子标签
List<Element> eles = rootElement.elements();
for (Element ele : eles) {
System.out.println(ele.getName());
}
// 获取所有子标签,通过迭代器获取
Iterator<Element> elementIterator = rootElement.elementIterator();
while (elementIterator.hasNext()) {
Element element = elementIterator.next();
System.out.println(element.getName());
}
//获取属性对象
Element element = rootElement.element("student");
Attribute attribute = element.attribute("id");
String value = attribute.getValue();
String name = attribute.getName();
System.out.println(name);
System.out.println(value);
//获取属性值
String value2 = rootElement.element("student").attributeValue("id");
System.out.println(value2);
//获取所有的属性对象
List<Attribute> attributes = rootElement.element("student").attributes();
for (Attribute atr : attributes) {
String name2 = atr.getName();
String value3 = atr.getValue();
System.out.println(name2 + "======" + value3);
}
//通过迭代器获取所有的属性对象
Iterator<Attribute> attributeIterator = rootElement.element("student").attributeIterator();
while(attributeIterator.hasNext()){
Attribute attribute2 = attributeIterator.next();
System.out.println(attribute2.getName()+"=="+attribute2.getValue());
}
//获取标签之间的文本
String text = doc.getRootElement().element("student").element("name").getText();
System.out.println(text);
String text2 = doc.getRootElement().element("student").elementText("name");
System.out.println(text2);
// 获取所有的节点
getNodes(rootElement);
// 获取节点对象
Node node = doc.node(0);
System.out.println(node.getName());
// 获取所有的节点
Iterator<Node> iterator = doc.nodeIterator();
while (iterator.hasNext()) {
Node nodes = iterator.next();
System.out.println(nodes.getName());}
2)SAX解析: sax解析有两个部分,解析器和事件处理器,解析器就是XMLReader接口,负责读取XML文档,和向事件处理器发送事
件(也是事件源),事件处理器ContentHandler接口,负责对发送的事件响应和进行XML文档处理,是编程核心代码。
1.ContentHandler接口的常用方法:
public abstract void startDocument () 文档解析开始时调用,该方法只会调用一次
public abstract void startElement (String uri, String localName, String qName, Attributes atts)标签(节点)解析开
始时调用(uri:xml文档的命名空间,localName:标签的名字,qName:带命名空间的标签的名字, attributes:标签的属性集)
public abstract void characters (char[] ch, int start, int length) 解析标签的内容的时候调用(ch:当前读取到的,
TextNode:文本节点的字节数组,start:字节开始的位置,为0则读取全部,length:当前TextNode的长度)
public abstract void endElement (String uri, String localName, String qName) 标签(节点)解析结束后调用
public abstract void endDocument () 文档解析结束后调用,该方法只会调用一次
2.步骤
(1)获取SAXParserFactory解析工厂。
(2)根据SAXParserFactory对象获取SAXParser对象。
(3)创建继承自DefaultHandler的解析处理器(ContentHandler的实现类DefaultHandler类)。
(4)使用SAXParser对象的parse()方法进行解析,传入xml文档和解析处理器对象。
3)Pull
XmlPull和Sax类似,是基于流(stream)操作文件,然后根据节点事件回调开发者编写的处理程序。因为是基于流的处理,因
此Xmlpull和 Sax都比较节约内存资源,不会象Dom那样要把所有节点以对橡树的形式展现在内存中。 但Xmlpull比Sax更简明,而且
不需要扫描完整个流。
// 获取解析器工厂对象
XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
// 获取解析器对象
XmlPullParser parser = factory.newPullParser();
// 关联xml文件
parser.setInput(new FileInputStream("students.xml"), "utf-8");
// 获取事件类型
int type = parser.getEventType();
while (type != XmlPullParser.END_DOCUMENT) {
// 获取标签名称
String tagName = parser.getName();
switch (type) {
case XmlPullParser.START_TAG:
if ("students".equals(tagName)) {
list = new ArrayList<Student>();
} else if ("student".equals(tagName)) {
stu = new Student();
String id = parser.getAttributeValue(0);
stu.setId(id);
} else if ("name".equals(tagName)) {
//获取标签之间的文本(注意:不是getText(),而是nextText())
String name = parser.nextText();
stu.setName(name);
} else if ("age".equals(tagName)) {
String age = parser.nextText();
stu.setAge(age);
} else if ("tel".equals(tagName)) {
String tel = parser.nextText();
stu.setTel(tel);
}
break;
case XmlPullParser.END_TAG:
if ("student".equals(tagName)) {
list.add(stu);
}
break;
}
type = parser.next();
}
System.out.println(list);
(五)写XML文件以及修改XML文件
/*
* 1.使用dom4j的api来生成以下的xml文件
<Students>
<Student id="1">
<name>张三</name>
<gender>男</gender>
<grade>JAVA1班</grade>
<address>西部开源总部</address>
</Student>
<Student id="2">
<name>李四</name>
<gender>女</gender>
<grade>JAVA2班</grade>
<address>西部开源东区</address>
</Student>
</Students>
2.修改id为2的学生的姓名,改为“王五”
3.删除id为2的学生
* */
Document doc = DocumentHelper.createDocument();
Element rootEle = doc.addElement("Students");
Element stuEle = rootEle.addElement("Student");
stuEle.addAttribute("id","1");
Element nameEle = stuEle.addElement("name");
nameEle.addText("张三");
Element genderEle = stuEle.addElement("gender");
genderEle.addText("男");
Element gradeEle = stuEle.addElement("grade");
gradeEle.addText("AVA1班");
Element addressEle = stuEle.addElement("address");
addressEle.addText("西部开源总部");
Element stuEle2 = rootEle.addElement("Student");
stuEle2.addAttribute("id","2");
Element nameEle2 = stuEle2.addElement("name");
nameEle2.addText("李四");
Element genderEle2 = stuEle2.addElement("gender");
genderEle2.addText("女");
Element gradeEle2 = stuEle2.addElement("grade");
gradeEle2.addText("AVA2班");
Element addressEle2 = stuEle2.addElement("address");
addressEle2.addText("西部开源东区");
//2.修改id为2的学生的姓名,改为“王五”
// List<Element> elements = doc.getRootElement().elements();
// Element element = elements.get(1);
// element.element("name").setText("王五");
//3.删除id为2的学生
List<Element> elements = doc.getRootElement().elements();
Element element = elements.get(1);
element.detach();
//把内存中的doc写到硬盘中
XMLWriter writer = new XMLWriter(new FileOutputStream("my.xml"));
writer.write(doc);
writer.close();