XML_概述,DOM4J解析器,Pull解析器,DOM4J增删改
2017-10-18 17:55
381 查看
xml概述
1.起源
W3C万维网联盟,先定义出来的是HTML,XML推出初衷是为了替换HTML 因为HTML语法太过松散,为了规范,推出了XML语言 后来,XML语言用做配置文件,封装数据,版本只有一个v1.0
2.概念
可扩展标记语言:标签可以自定义 命名规范:不能用数字开头,不能使用纯数字,区分大小写
3.功能
用作配置文件 用作网络数据传输的载体
4.组成部分
文档声明:<?xml version="1.0" encoding="utf-8"?> endoing 写的编码是规定哪里的编码? 告诉浏览用什么编码去解析 文档声明:必须顶行写,还有顶格写。 根标签:有且仅有一个根标签 其他标签 有开始标签 一定要有结束标签 文本: CDATA区:该区域的文本,会按照纯文本解析 格式: <![CDATA[ 内容 ]]> 处理指令:了解 已经过时 <?xml-stylesheet type="text/css" href="1.css"?>
5.解析
a.DOM解析
Document Object Model 文档对象模型 DOM:将文档的各个组成部分 抽取一个对象 Element 标签对象 Attribute 属性对象 Text 文本对象 Comment 注释对象 Node 节点对象 Document· 文档对象 怎么解析:将文档一次性 加载进内存 然后将文档各个组成不封抽取为对象 优点: 能够对文档进行增删改查 缺点:耗内存 适用于PC 端
b.SAX解析
SAX :基于事件 逐行解析,一次读取一行,释放一行 优点 :不占内存 适用于移动端 缺点:只能查 不能增删改
c.常用的解析器:
DOM4J:第三方jar包 实现了DOM思想 Pull 解析器:第三方jar包 实现了SAX思想
DOM4J解析器
1.步骤
1.导入jar包,并build path 2.创建解析器对象 3.代码实现获得标签和属性对象
2.获得标签对象的方法和具体代码
1.node() 获取单个节点对象 2.nodeIterator(); 获取多个节点对象 只能获取子节点 2.获取根标签对象 getRootElement() 3.Element();获取第一个子标签 Elements() 获取所有的子标 elememtesIterator() 获取所有子标签对象 4.attribute() 获取单个属性对象 getName()获取属性的键 getValue()获取属性的值attributes()获取所有的属性对象attributeIterator() 获取所有的属性对象直接获取属性对象的值 attributeValue() 5.先获取到文本所在的标签对象 通过getText()拿出这个标签直接的文本elementText("name");
public class Dom4JTest { public static void main(String[] args) throws Exception { // 1.导入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()); System.out.println("-------------以下是获取所有子标签---------------------"); // 获取所有的子标签 List<Element> eles = rootElement.elements(); for (Element ele : eles) { System.out.println(ele.getName()); } // 方式三 获取所有子标签 System.out.println("-------------通过迭代器获取所有子标签---------------------"); Iterator<Element> elementIterator = rootElement.elementIterator(); while (elementIterator.hasNext()) { Element element = elementIterator.next(); System.out.println(element.getName()); }
3.获得属性对象的方法和具体代码
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); // 方式2:直接获取属性值 System.out.println("------------------------------------------"); 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); } System.out.println("---------------通过迭代器获取所有的属性对象--------------------------"); Iterator<Attribute> attributeIterator = rootElement.element("student").attributeIterator(); while(attributeIterator.hasNext()){ Attribute attribute2 = attributeIterator.next(); System.out.println(attribute2.getName()+"=="+attribute2.getValue()); }
4.获得标签之间的文本的方法和具体代码
String text = doc.getRootElement().element("student").element("name").getText(); System.out.println(text); //方式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.xupt.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); } } } }
Pull解析器
1.概述
SAX:逐行解析,读取一行,释放一行,不占内存
2.需求(序列化与反序列化)
将students.xml文件读取到内存中(反序列化),然后保存到stu.xml文件中去(序列化) 主要方法在代码中注释 注意:写入文档,标签要成对的写 serializer.startDocument("utf-8", true); // standalone='yes' 文档是否独立 在此写根标签,子标签,都是成对写 serializer.endDocument(); // 文档结束
package org.xupt.pull; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.util.ArrayList; import org.westos.pull.bean.Student; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; import org.xmlpull.v1.XmlPullParserFactory; import org.xmlpull.v1.XmlSerializer; public class PullParserDemo { private static ArrayList<Student> list; private static Student student; public static void main(String[] args) throws Exception { // SAX:逐行解析 读取一行,释放一行 不占内存 // 导入第三方jar包 // 获取解析器工厂对象 XmlPullParserFactory factory = XmlPullParserFactory.newInstance(); // 从工厂里面 获取解析器对象 XmlPullParser parser = factory.newPullParser(); // 关联xml文件 // 参数1 要解析的xml文件 参2:编码格式 parser.setInput(new FileInputStream("students.xml"), "utf-8"); // 获取事件类型 // 指针默认的位置在文档开始 // 从硬盘中把文件数据读取到 内存中 这个动作叫反序列化 // 把内存中的数据写到硬盘上 这个动作叫序列化 int type = parser.getEventType();// 0 while (type != XmlPullParser.END_DOCUMENT) { // 获取标签名称 String tagName = parser.getName(); switch (type) { case XmlPullParser.START_TAG:// 开始标签事件 if ("students".equals(tagName)) { // 做了一些准备 工作 创建了一个集合 因为我要装javabean list = new ArrayList<Student>(); } else if ("student".equals(tagName)) { // 创建javabean 对象 student = new Student(); // 获取id String id = parser.getAttributeValue(0);// 从0数 student.setId(id); } else if ("name".equals(tagName)) { // 获取标签之间的文本 // String text = 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();// 让指针下移一行,获取到的新的事件类型,记得重新赋值给type 不然就会死循环 } // type=parser.next();//让指针下一行 // System.out.println(type); // System.out.println(XmlPullParser.START_DOCUMENT);//文档开始事件 // System.out.println(XmlPullParser.END_DOCUMENT);//文档结束事件 // System.out.println(XmlPullParser.START_TAG);// 开始标签事件 // System.out.println(XmlPullParser.END_TAG);// 结束标签事件 // System.out.println(list); // 现在的要求是我想把内存中的数据序列化到硬盘上去永久保存 SavaDataToXMl(factory); } private static void SavaDataToXMl(XmlPullParserFactory factory) throws XmlPullParserException, IllegalArgumentException, IllegalStateException, FileNotFoundException, IOException { // 获取序列化器 XmlSerializer serializer = factory.newSerializer(); // 设置输出流关联xml文件 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");// 写入开始标签 // 写入属性 参1 命名空间,参数2 属性名 参数3属性值 serializer.attribute(null, "id", stu.getId()); serializer.startTag(null, "name");// 写入开始标签 // 写入标签直接的文本 serializer.text(stu.getName()); serializer.endTag(null, "name");// 写入结束标签 serializer.startTag(null, "age");// 写入开始标签 // 写入标签直接的文本 serializer.text(stu.getAge()); serializer.endTag(null, "age");// 写入结束标签 serializer.startTag(null, "tel");// 写入开始标签 // 写入标签直接的文本 serializer.text(stu.getTel()); serializer.endTag(null, "tel");// 写入结束标签 serializer.endTag(null, "student");// 写入结束标签 } serializer.endTag(null, "students");// 写入结束标签 serializer.endDocument(); } }
DOM4J解析实现增删改
修改删除
1.先读取到内存中,进行修改主要方法:setText();就是设置文本
detach();删除标签
2.重新写入硬盘覆盖原文件
XMLWriter 类
3.代码实现
要求:修改以下xml文件,修改张三的姓名为王五,性别为空;删除id=”002”的属性;
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>
代码实现需求package org.xupt.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(); } }增加属性
添加标签:用文档帮助类DocumentHelper,创建一个文档,最后记得XMLWriter 写到硬盘
添加标签:addElement(“标签名”);
添加属性:addAtrriburte(“属性”,”属性值”)
添加文本:addText(“文本”);package org.xupt.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(); } }
相关文章推荐
- 【JavaEE学习笔记】XML_概述,DOM4J解析器,Pull解析器,DOM4J增删改,xPath
- XML的四种解析器(dom,sax,jdom,dom4j)原理及性能比较
- JavaWeb系列之四(XML的解析技术(dom,sax)和解析器(jaxp,dom4j))
- Dom4j对XML文档的增删改查操作
- dom4j对XML进行增删改查(详细)
- XML的四种解析器(dom,sax,jdom,dom4j)原理及性能比较:
- Java_xml_dom4j对xml文件增删读写操作
- DRP项目(七)----XML的四种解析器之DOM4J解析XML
- dom4j解析XML之【增删改查】
- XML的四种解析器(dom,sax,jdom,dom4j)原理及性能比较(转自zsq)
- 迁徙3_使用DOM解析器完成XML的增删改查(可做广告)_2016-5-16
- 利用dom4j编写XML解析器
- dom4j解析xml文档(增删改查)
- DRP项目(七)----XML应用和XML的四种解析器(dom,sax,jdom和dom4j)原理及实例
- 进入黑马day2-解析xml三种方法(3)dom4j解析器
- XML“数据库”:简单的通讯录系统(用dom4j完成增删改查)
- 使用Dom4j对XML进行增删改查
- XML的四种解析器(dom,sax,jdom,dom4j)原理及性能比较(转自zsq)
- 进入黑马day2-解析xml三种方法(3)dom4j解析器
- XML利用dom4j进行增删查改等方法