【JavaEE学习笔记】XML_概述,DOM4J解析器,Pull解析器,DOM4J增删改,xPath
来源:互联网 发布:湖南网络工程学院宿舍 编辑:程序博客网 时间:2024/06/01 18:26
XML
A.概述
1.起源
W3C万维网联盟,先定义出来的是HTML,XML推出初衷是为了替换HTML
因为HTML语法太过松散,为了规范,推出了XML语言
后来,XML语言用做配置文件,封装数据,版本只有一个v1.0
2.概念
可扩展标记语言:标签可以自定义
命名规范:不能用数字开头,不能使用纯数字,区分大小写
3.功能
a.用做配置文件
b.用做网络数据传输的载体
4.语法
新建一个文本文件,后缀名必须为.xml
5.组成部分
a.文档声明:<?xml version="1.0" encoding="utf-8"?>
encoding告诉浏览用什么编码去解析
文档声明必须在第一行,顶格
b.根标签:有且仅有一个根标签
c.其他标签:有开始标签,一定要有结束标签
d.文本:CDATA区:该区域的文本,会按照纯文本解析
格式:<![CDATA[内容]]>
<?xml version="1.0" encoding="UTF-8"?><students><student id="s001"><name>张三</name><age>23</age><tel>110</tel></student><student id="s002"><name>李四</name><age>24</age><tel>119</tel></student></students>
6.解析xml
a.DOM
将文档的各个组成部分 抽取一个对象
Element 标签对象
Attribute 属性对象
Text 文本对象
Comment 注释对象
Node 节点对象
Doucment 文档对象
解析过程:将文档一次性,加载进内存,然后将文档各个组成不封抽取为对象
优点:能够对文档进行增删改查
缺点:耗内存,适用于PC端
b.SAX
基于事件,逐行解析,一次读取一行,释放一行
优点:不占内存,适用于移动端
缺点:只能查,不能增删改
7.常用解析器
a.DOM4J:第三方jar包,实现了DOM思想
b.Pull解析器:第三方jar包,实现了SAX思想
B.DOM4J解析器
1.步骤
a.导入DOM4J jar包
b.将上一条的students.xml文件,放入工程根目录
<?xml version="1.0" encoding="UTF-8"?><students><!-- 根标签 --><student id = "s001"><!-- 子标签 --><name>张三</name><age>23</age><tel>110</tel></student><student id = "s002"><name>李四</name><age>24</age><tel>120</tel></student></students>
c.代码实现
2.获取标签对象
创建解析器对象
SAXReader reader = new SAXReader();
具体方法在代码中注释
package org.xxxx.dom4j;import java.io.FileInputStream;import java.util.Iterator;import java.util.List;import org.dom4j.Document;import org.dom4j.Element;import org.dom4j.io.SAXReader;public class DOM4JDemo {public static void main(String[] args) throws Exception {// 导入DOM4J jar包// 创建解析器对象SAXReader reader = new SAXReader();// 加载xml文件Document doc = reader.read(new FileInputStream("students.xml"));// 获取根标签对象 getRootElement();Element rootElement = doc.getRootElement();// 获取根标签下的子标签,默认获取的是第一个子标签 element();Element stuElement = rootElement.element("student");System.out.println("根标签下的子标签(默认第一个):" + stuElement.getName());System.out.println("----------获取所有子标签----------");// 1)elements();返回结果集List<Element> ele = rootElement.elements();for (Element e : ele) {System.out.println(e.getName());}// 2)迭代器获取 elementIterator();System.out.println("----------迭代器获取所有子标签----------");Iterator<Element> elementIterator = rootElement.elementIterator();while (elementIterator.hasNext()) {Element element = elementIterator.next();System.out.println(element.getName());}}}
3.获取属性对象和标签之间的文本
三种方式,代码中实现
package org.xxxx.dom4j;import java.io.FileInputStream;import java.util.Iterator;import java.util.List;import org.dom4j.Attribute;import org.dom4j.Document;import org.dom4j.Element;import org.dom4j.io.SAXReader;public class DOM4JDemo {public static void main(String[] args) throws Exception {// 导入DOM4J jar包// 创建解析器对象SAXReader reader = new SAXReader();// 加载xml文件Document doc = reader.read(new FileInputStream("students.xml"));// 方式1:分布获取属性对象// 获取跟标签对象Element rootElement = doc.getRootElement();// 获取属性对象Element element = rootElement.element("student");// 获取属性id attribute("id");Attribute attribute = element.attribute("id");// 获取值String value = attribute.getValue();String name = attribute.getName();System.out.println(name + "---" + value);// 方式2:直接获取属性值System.out.println("--------------------------");String value2 = rootElement.element("student").attributeValue("id");System.out.println(value2);// 方式3:获取所有属性对象 attributes();System.out.println("------------------");List<Attribute> attributes = rootElement.element("student").attributes();for (Attribute attr : attributes) {String name2 = attr.getName();String value3 = attr.getValue();System.out.println(name2 + "---" + value3);}// 通过迭代器获取所有属性对象System.out.println("------------------");Iterator<Attribute> attributeIterator = rootElement.element("student").attributeIterator();while (attributeIterator.hasNext()) {Attribute attribute2 = attributeIterator.next();System.out.println(attribute2.getName() + "---" + attribute2.getValue());}// 获取标签之间的文本System.out.println("------------------");// 方式1:层层往下拿String text1 = doc.getRootElement().element("student").element("name").getText();System.out.println(text1);// 方式2:一步到位String text2 = doc.getRootElement().element("student").elementText("name");System.out.println(text2);}}
4.获取所有节点
a.node():获取单个节点对象;nodeIterator(); 获取多个节点对象,只能获取子节点
b.获取根标签对象 getRootElement()
c.Element()获取第一个子标签
Elements() 获取所有的子标签
elememtesIterator() 获取所有子标签对象
d.attribute() 获取单个属性对象 getName()获取属性的键 getValue()获取属性的值
attributes()获取所有的属性对象
attributeIterator() 获取所有的属性对象
直接获取属性对象的值 attributeValue()
e.先获取到文本所在的标签对象 通过getText()拿出这个标签直接的文本elementText("name");
package org.xxxx.dom4j;import java.io.FileInputStream;import java.util.Iterator;import org.dom4j.Document;import org.dom4j.Element;import org.dom4j.Node;import org.dom4j.io.SAXReader;public class DOM4JDemo {public static void main(String[] args) throws Exception {// 导入DOM4J jar包// 创建解析器对象SAXReader reader = new SAXReader();// 加载xml文件Document doc = reader.read(new FileInputStream("students.xml"));// 方式1:分布获取属性对象// 获取跟标签对象Element rootElement = doc.getRootElement();// 使用递归获取所有节点getNodes(rootElement);}private static void getNodes(Element ele) {// 输出当前节点System.out.println(ele.getName());// 迭代器获取所有子节点Iterator<Node> iterator = ele.nodeIterator();// 遍历while (iterator.hasNext()) {Node nodes = iterator.next();// 判断节电是否属于标签if (nodes instanceof Element) {Element eles = (Element) nodes;// 调用递归getNodes(eles);}}}}
5.封装数据
把从xml中解析的数据封装起来
a.创建javabean存放对象
package org.xxxx.dom4j.bean;import java.io.Serializable;public class Student implements Serializable {private static final long serialVersionUID = 1L;private String id;private String name;private String age;private String tel;public Student() {super();// TODO Auto-generated constructor stub}public Student(String id, String name, String age, String tel) {super();this.id = id;this.name = name;this.age = age;this.tel = tel;}public String getId() {return id;}public void setId(String id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getAge() {return age;}public void setAge(String age) {this.age = age;}public String getTel() {return tel;}public void setTel(String tel) {this.tel = tel;}@Overridepublic String toString() {return "Student [id=" + id + ", name=" + name + ", age=" + age + ", tel=" + tel + "]";}}b.测试类
package org.xxxx.dom4j;import java.io.FileInputStream;import java.util.ArrayList;import java.util.Iterator;import org.dom4j.Document;import org.dom4j.Element;import org.dom4j.io.SAXReader;import org.xxxx.dom4j.bean.Student;public class FZStudent {public static void main(String[] args) throws Exception {// 创建集合存储对象ArrayList<Student> list = new ArrayList<>();// 创建解析器SAXReader reader = new SAXReader();// 加载xml文件Document doc = reader.read(new FileInputStream("students.xml"));// 获取根标签对象Element rootElement = doc.getRootElement();// 获取所有的子标签对象Iterator<Element> elementIterator = rootElement.elementIterator();// 遍历取出数据并封装while (elementIterator.hasNext()) {Element element = elementIterator.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);// 添加到集合中list.add(stu);}// 遍历集合for (Student s : list) {System.out.println(s.getId() + "---" + s.getName() + "---" + s.getAge() + "---" + s.getTel());}}}
C.Pull解析器
1.概述
SAX:逐行解析,读取一行,释放一行,不占内存
2.需求(序列化与反序列化)
将students.xml文件读取到内存中(反序列化),然后保存到stu.xml文件中去(序列化)
主要方法在代码中注释
注意:写入文档,标签要成对的写
serializer.startDocument("utf-8", true); // standalone='yes' 文档是否独立
在此写根标签,子标签,都是成对写
serializer.endDocument(); // 文档结束
package org.xxxx.pull;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 org.xxxx.pull.bean.Student;public class PullParseDemo {// 创建集合,存放对象private static ArrayList<Student> list;private static Student student;public static void main(String[] args) throws Exception {// 导入jar包// 获取解析器工厂对象XmlPullParserFactory factory = XmlPullParserFactory.newInstance();// 获取解析器XmlPullParser parser = factory.newPullParser();// 读取文件内容到内存中:反序列化// 加载文件// 参数1:要解析的文件 参数2:编码格式parser.setInput(new FileInputStream("students.xml"), "utf-8");// 获取事件类型// 指针默认的位置在文档开始// 从硬盘中把文件数据读取到内存中,即反序列化// 获取起始位置int type = parser.getEventType();// 一次读取,当判断条件为1,则表示读取到最后一行,结束循环// 使用XmlPullParse.END_DOCUMENT结束标记,不要直接写1while (type != XmlPullParser.END_DOCUMENT) {// 获取标签名称String tagName = parser.getName();// 判断switch (type) {case XmlPullParser.START_TAG: // 标签开始事件if ("students".equals(tagName)) {// 是根标签,创建集合list = new ArrayList<>();} else if ("student".equals(tagName)) {// 子标签,创建javabean对象student = new Student();// 获取idString id = parser.getAttributeValue(0); // 从0开始// 写入对象student.setId(id);} else if ("name".equals(tagName)) {// 获取标签之间的文本// String name = parser.getText(); 这个获取不到,注意String name = parser.nextText();// 写入对象student.setName(name);} else if ("age".equals(tagName)) {// 获取年龄String age = parser.nextText();student.setAge(age);} else if ("tel".equals(tagName)) {String tel = parser.nextText();student.setTel(tel);}break;case XmlPullParser.END_TAG: // 结束标签时间if ("student".equals(tagName)) {list.add(student);}break;}type = parser.next(); // 让指针下移,获取新的事件类型,并重新赋值,防止死循环}// 遍历集合,查看是否读取完毕for (Student stu : list) {System.out.println(stu.getId() + "---" + stu.getName() + "---" + stu.getAge() + "---" + stu.getTel());}System.out.println("--------------------------------");// 接下来,开始存储数据到stu.xml文件中,也就是序列化// 抽取一个方法SavaDataToXML(factory);}private static void SavaDataToXML(XmlPullParserFactory factory) throws XmlPullParserException, IllegalArgumentException, IllegalStateException, FileNotFoundException, IOException {// 获取序列化器XmlSerializer serializer = factory.newSerializer();// 设置输出流关联文件serializer.setOutput(new FileOutputStream("stu.xml"), "utf-8");// 写入文档声明// 参数1:编码 参数2:文档是否独立// 文档开始,也要有文档结束,成对去写serializer.startDocument("utf-8", true);// standalone='yes' 文档是否独立// 写入根标签// 参数1 命名空间,一般给null 参数2 标签名称serializer.startTag(null, "students");// 写入开始标签// 遍历集合,写子标签for (Student stu : list) {// 写入student标签serializer.startTag(null, "student");// 写入id属性 参数1 命名空间 参数2 属性名 参数3 属性值serializer.attribute(null, "id", stu.getId());// 写入name标签serializer.startTag(null, "name");// 写入文本nameserializer.text(stu.getName());serializer.endTag(null, "name");// 写入age标签serializer.startTag(null, "age");// 写入文本ageserializer.text(stu.getAge());serializer.endTag(null, "age");// 写入tel标签serializer.startTag(null, "tel");// 写入文本telserializer.text(stu.getTel());serializer.endTag(null, "tel");// studeng结束标签serializer.endTag(null, "student");}serializer.endTag(null, "students");// 写入结束标签serializer.endDocument();// 文档结束}}
运行完毕,刷新工程,查看stu.xml文件
D.DOM4J解析实现增删改
1.修改删除
a.先读取到内存中,进行修改
主要方法
setText();就是设置文本
detach();删除标签
b.重新写入硬盘覆盖掉源文件
XMLWriter 类
c.代码实现
修改以下xml文件
<?xml version="1.0" encoding="UTF-8"?><students> <student id="s001"> <name>张三</name> <gender>男</gender> </student> <student id="s002"> <name>李四</name> <gender>女</gender> </student></students>修改张三的姓名为王五,性别为空删除id="002"的属性
package org.xxxx.xml;import java.io.FileInputStream;import java.io.FileOutputStream;import java.util.List;import org.dom4j.Document;import org.dom4j.Element;import org.dom4j.io.OutputFormat;import org.dom4j.io.SAXReader;import org.dom4j.io.XMLWriter;public class Demo01 {public static void main(String[] args) throws Exception {// 读取xml文件SAXReader reader = new SAXReader();Document doc = reader.read(new FileInputStream("students.xml"));// 修改文本// 第一个标签,直接获取doc.getRootElement().element("student").element("name").setText("王五");doc.getRootElement().element("student").element("gender").setText("");// 删除属性// 获取根标签Element rootElement = doc.getRootElement();// 获取属性集List<Element> elements = rootElement.elements();// 遍历for (Element ele : elements) {// 获取属性String value = ele.attributeValue("id");if (value.equals("s002")) {ele.attribute("id").detach();}}// 重新写入硬盘XMLWriter writer = new XMLWriter(new FileOutputStream("students.xml"));writer.write(doc);writer.close();}}
2.增加属性
添加标签:用文档帮助类DocumentHelper,创建一个文档,最后记得XMLWriter 写到硬盘
添加标签:addElement("标签名");
添加属性:addAtrriburte("属性","属性值")
添加文本:addText("文本");
package org.xxxx.xml;import java.io.FileOutputStream;import org.dom4j.Document;import org.dom4j.DocumentHelper;import org.dom4j.Element;import org.dom4j.io.XMLWriter;public class Demo02 {public static void main(String[] args) throws Exception {// 用代码写一个xml// 文档帮助类写一个声明Document doc = DocumentHelper.createDocument();// 添加一个根标签Element rootEle = doc.addElement("students");// 添加一个子标签// 根标签的子标签,用根标签调,后面同理Element stuELe = rootEle.addElement("student");// 添加属性stuELe.addAttribute("id", "s001");// 添加名字标签Element name = stuELe.addElement("name");// 添加名字name.addText("张三");// 添加年龄Element age = stuELe.addElement("age");age.addText("20");// 添加电话Element tel = stuELe.addElement("tel");tel.addText("110");// 写到硬盘上XMLWriter writer = new XMLWriter(new FileOutputStream("mydoc.xml"));writer.write(doc);writer.close();}}运行程序,刷新工程
E.xPath
1.概述
路径规则书写的一门技术,它的作用是用来快速找到
XML文档中一个或多个标签,不需要一层一层标签去获取
直接通过标签的特征检索
2.步骤
a.导入DOM4J jar包和支持xPath技术的jar包
b.定义path语句
比如寻找id="s002"的student标签
String path = "//student[@id='s002']";
寻找name为王五的人标签
String path = "//name[text()='王五']";
c.配合xPath找到单个节点对象
Element selectSingleNode = (Element) doc.selectSingleNode(path);System.out.println(selectSingleNode.getName());
d.找到根标签下的所有标签 selectNodes(path);配合xPath 找到多个节点
String path = "//student";List<Node> selectNodes = doc.selectNodes(path);for (Node node : selectNodes) {System.out.println(node.getName());}
3.还有很多方法,可以查阅官方文档
- 【JavaEE学习笔记】XML_概述,DOM4J解析器,Pull解析器,DOM4J增删改,xPath
- XML_概述,DOM4J解析器,Pull解析器,DOM4J增删改
- xml_用dom4j解析文档
- 使用dom4j解析、增删改xml文档,xPath技和SAX解析
- dom4j解析xml增删改查
- dom4j解析XML之【增删改查】
- DOM4J+XPath 解析XML
- dom4j +xpath 解析问题
- XML_使用dom4j对文档增删查改
- sax解析、dom4j解析、xpath
- XML语言学习5--DOM4J解析+xpath
- xml解析dom4j xpath方式
- dom4j使用XPath解析xml
- xpath和dom4j解析xml
- xml解析-pull和dom4j
- web day6 DOM&XML(JAXP的SAX解析XML,schema入门,dom4j&XPath的增删改查)
- dom4j 解析器
- DOM4j解析器详解
- Sublime Text3 3143 注册码,亲测可用!
- NYOJ的矩形嵌套问题
- Django框架下使用ajax模拟用户登录验证
- 2017.10.14
- 网页爬虫--scrapy进阶
- 【JavaEE学习笔记】XML_概述,DOM4J解析器,Pull解析器,DOM4J增删改,xPath
- 数组相关知识
- 201710142150->利用www类完成网页get请求
- Makefile 结构
- Kattis
- Java 注解
- 单例模式
- 如何解决error: failed to push some refs to 'xxx(远程库)'
- Random类以及Random种子