XML
W3C( 万维网联盟 )先定义出来的是HTML ,XML推出初衷是为了替换HTML ,因为HTML语法太过松散, XML规定非常严格。XML 用做配置文件 封装数据
HTML:超文本标记语言 定义网页元素
1.概念:
可扩展标记语言,标签名可以自己定义 <student></student>
命名规范:不能用数字开头,不能使用纯数字,区分大小写 。
2. 功能:
a.用作配置文件 ;
b.用作网络数据传输的载体,xml 用于PC端数据传输的载体,JSON {"username":"张三","age":23,"sex":"1"} 一般用于移动端的数据传输载体,因为体积小。
3. 语法:
新建一个文本文件 后缀名必须为 .xml
4. 组成部分:
文档声明:<?xml version="1.0" encoding="utf-8"?>
endoing 告诉浏览用什么编码去解析
文档声明:必须顶行写,还有顶格写。
根标签:有且仅有一个根标签 其他标签 有开始标签 一定要有结束标签
5. 文本:
CDATA区:该区域的文本,会按照纯文本解析
格式: <![CDATA[ 内容 ]]>
处理指令: <?xml-stylesheet type="text/css" href="1.css"?>
6.解析XML
a. DOM: Document Object Model 文档对象模型,将文档的各个组成部分抽取一个对象
Element 标签对象
Attribute 属性对象
Text 文本对象
Comment 注释对象
Node 节点对象
Document 文档对象
解析:将文档一次性 加载进内存 然后将文档各个组成不封抽取为对象
优点: 能够对文档进行增删改查
缺点:耗内存 适用于PC 端
b. SAX :基于事件 逐行解析,一次读取一行,释放一行
优点 :不占内存 适用于移动端;
缺点:只能查 不能增删改.
7. 常用的XML解析器
DOM4J:第三方jar包,实现了DOM思想
Pull解析器:第三方jar包,实现了SAX思想
8. 主要方法
a.修改xml文件
1)先把xml文件文件读进内存,
2) 找到你要修改的节点,去修改;
setText(); 设置文本
3)再写入硬盘 覆盖掉源文件.
b. 删除xml属性/标签
detach();删除标签/属性
c. 修改文本
setText();设置文本
d. 写入硬盘覆盖原文件
//设置格式,二选一,默认紧凑格式 OutputFormat format = OutputFormat.createCompactFormat();// 紧凑的格式 OutputFormat prettyPrint = OutputFormat.createPrettyPrint();//漂亮格式 //覆盖原文件 XMLWriter writer = new XMLWriter(new FileOutputStream("students.xml"), format); writer.write(doc); writer.close();
------------------------------------------------------------------------------------
DOM4J解析器
1.获取节点对象的主要方法
// 创建解析器对象
SAXReader reader = new SAXReader();
// 加载xml文件
Document doc = reader.read(new FileInputStream("students.xml"));
//获取节点标签,只能获取一个子节点
Node node = doc.node(0);
// 获取根标签对象 getRootElement();
Element rootElement = doc.getRootElement();
// 获取根标签下的子标签 默认获取的是第一个子标签
Element stuElement = rootElement.element("student");
// 通过集合获取所有的子标签
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());
}
// 获取所有的节点
Iterator<Node> iterator = doc.nodeIterator();
while (iterator.hasNext()) {
Node nodes = iterator.next();
System.out.println(nodes.getName());
}
2.获取属性对象的相关方法
//获取属性对象
Element element = rootElement.element("student");
//获取id属性
Attribute attribute = element.attribute("id");
//获得属性值
String value = attribute.getValue();
//获取属性名
String name = attribute.getName();
// 直接获取属性值
String value2 = rootElement.element("student").attributeValue("id");
// 获取所有的属性对象
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());
}
3.获取标签之间的文本
//方式1 String text = doc.getRootElement().element("student").element("name").getText(); //方式2 String text2 = doc.getRootElement().element("student").elementText("name");
4.封装XML代码实现如下,student.xml和Student对象类省略不写:
package org.xxxx.xml; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.util.ArrayList; import java.util.Iterator; import org.dom4j.Document; import org.dom4j.DocumentException; import org.dom4j.Element; import org.dom4j.io.SAXReader; import bean.Student; public class XmlDemo { public static void main(String[] args) throws FileNotFoundException, DocumentException { ArrayList<Student> arr=new ArrayList<>(); //创建解析器对象 SAXReader reader=new SAXReader(); //读取xml文件 Document doc=reader.read(new FileInputStream("students.xml")); //获取根标签 Element rootElement = doc.getRootElement(); //获取所有子标签 Iterator<Element> iterator = rootElement.elementIterator(); //遍历封装 while(iterator.hasNext()){ Element element = iterator.next(); // String id = element.attributeValue("id"); String name = element.elementText("name"); String age = element.elementText("age"); String tel = element.elementText("tel"); Student stu=new Student(id, name, age, tel); arr.add(stu); } System.out.println(arr); } }
------------------------------------------------------------------------------------
Pull解析器
序列化与反序列化
将students.xml文件先反序列化到内存中,再序列化到stu.xml中。
package org.xxxx.xml; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.util.ArrayList; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; import org.xmlpull.v1.XmlPullParserFactory; import org.xmlpull.v1.XmlSerializer; import bean.Student; public class PullDemo { private static ArrayList<Student> list; private static Student student; public static void main(String[] args) throws XmlPullParserException, IOException { //获取解析器工厂对象 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 name = parser.getName(); switch(type){ case XmlPullParser.START_TAG: if("students".equals(name)){ list = new ArrayList<Student>(); }else if("student".equals(name)){ student=new Student(); String id = parser.getAttributeValue(0); student.setId(id); }else if("name".equals(name)){ String text = parser.nextText(); student.setName(text); }else if("age".equals(name)){ String age = parser.nextText(); student.setAge(age); }else if("tel".equals(name)){ String tel = parser.nextText(); student.setTel(tel); } break; case XmlPullParser.END_TAG: if("student".equals(name)){ list.add(student); } break; } //指针指向下一行 type=parser.next(); } System.out.println(list); //抽取一个方法,进行序列化 saveDataToXML(factory); } private static void saveDataToXML(XmlPullParserFactory factory) throws XmlPullParserException, IllegalArgumentException, IllegalStateException, FileNotFoundException, IOException { //获取序列化器 XmlSerializer serializer = factory.newSerializer(); //设置输出流关联xml文件 serializer.setOutput(new FileOutputStream("stu.xml"), "utf-8"); //写入文档声明 serializer.startDocument("utf-8", true); //写入根标签 serializer.startTag(null, "students"); //循环写入 for(Student s:list){ //写入student标签 serializer.startTag(null, "student"); //写入属性 serializer.attribute(null, "id", s.getId()); //写入开始标签 serializer.startTag(null, "name"); //写入标签之间的文本 serializer.text(s.getName()); serializer.endTag(null, "name"); serializer.startTag(null, "age"); serializer.text(s.getAge()); serializer.endTag(null, "age"); serializer.startTag(null, "tel"); serializer.text(s.getTel()); serializer.endTag(null, "tel"); serializer.endTag(null, "student"); } serializer.endTag(null, "students"); //写入文档结束事件 serializer.endDocument(); } }
------------------------------------------------------------------------------------
XPath
1.概述
路径规则书写的一门技术,他的作用是用来快速找到 XML文档中的一个或多个标签;
一般来说如果要找深层级的标签 那么使用xPath找起来非常快。
2.具体方法
a. 导入DOM4J的jar包和XPath的jar包;
b. 普通方法查找标签
XPath查找标签List<Element> elements = doc.getRootElement().elements(); Element element = elements.get(1);
String path = "//student[@id='s002']"; // selectSingleNode(path) 配合xPath 找到单个节点对象 Element selectSingleNode = (Element) doc.selectSingleNode(path);
// 找到根标签下的所有标签 selectNodes(path);配合xPath 找到多个节点 path = "//student"; List<Node> selectNodes = doc.selectNodes(path); for (Node node : selectNodes) { System.out.println(node.getName()); }
3.简单语法
last() 选最后一个节点
text() 文本
@ 定位一个属性名
* 统配符
/ 绝对路径 一级一级往下定位
// 不分层级 相对定位
and 并且
not() 取反