DOM解析与SAX解析来读取和修改xml文件
2017-04-05 08:07
621 查看
1 XML入门
2 XML作用
DOM解析把xml文档信息封装到对象中
总结
/* 1.1 引入 HTML: 负责网页的结构 CSS: 负责网页的样式(美观) Javascript: 负责在浏览器端与用户进行交互。 负责静态的网页制作的语言 HTML语言特点: 1)由标签组成。 <title> <p> <hr/> <br/> 2)语法结构松散的 <p></p> <p> <P> 大小写不区分 结束标签和开始标签不一定匹配 <html> <head> <title>this is title</title> </head> <body> <p>html标签</p> <P>html标签</P> <abc>abc标签</abc> 自定义标签 </body> </html> 这种自定义标签可以把他们叫做xml标签。 1.2 HTML和XML的区别 HTML: XML 名称:HyperText Markup Languae(超文本标记语言) 标签:标签是w3c组成指定,固定的,约100来个 作用:负责网页的结构 XML: 名称:Extend Markup Languge(可扩展标签语言) 标签:标签由开发者自己制定的(要按照一定的语法定义) 作用:1)描述带关系的数据(作为软件的配置文件): 包含与被包含的关系 properties文件: key-value name=eric password=123456 <user> <name>eric</name> <password>123456</password> </user> 场景: tomcat struts Hibernate spring (三大框架) 2)作为数据的载体(存储数据,小型的“数据库”) */
2 XML作用
/* 2.1 描述带关系的数据(软件的配置文件) web服务器(PC): 学生管理系统 -> 添加学生功能 -> 添加学生页面 -> name=eric&email=eric@qq.com 前提: 网络(IP地址: oracle:255.43.12.54 端口:1521 ) java代码:使用ip(255.43.12.54)地址和端口(1521),连接oracle数据库,保存学生数据。 把ip地址端口配置到xml文件: host.xml <host> <ip>255.43.12.55</ip> <port>1521</port> </host> 数据库服务器(PC): 主服务器(255.43.12.54):Oracle数据库软件(负载) 副服务器(255.43.12.55):Oracle数据库软件 2.2 数据的载体(小型的“数据库”) 教师管理系统: 姓名 工龄+1 邮箱 发教师数据给财务管理系统: String teacher = name=张三&email=zhangsan@qq.com&workage=2 字符串 (问题: 1)不好解析 2)不是规范) teacher.xml <teacher> <name>张三</name> <email>zhangsan@qq.com</email> <workage>2</workage> </teacher> 这种一种规范 财务管理系统: 姓名 工龄+1 邮箱 发奖金: 统计奖金。 工龄 发邮件功能: 邮箱 姓名 金额 方案一: 在财务管理系统中维护了一套教师信息。 每年 : 工龄增加 维护了两个系统的信息。 方案二: 教师信息只在教学管理系统中维护。 */3 XML语法
/* xml文件以xml后缀名结尾。 xml文件需要使用xml解析器去解析。浏览器内置了xml解析器。 3.1 标签 语法: <student></student> 开始标签 标签体内容 结束标签 1)<student/> 或 <student></student> 空标签。没有标签体内容 2)xml标签名称区分大小写。 3)xml标签一定要正确配对。 4)xml标签名中间不能使用空格 5)xml标签名不能以数字开头 6)注意: 在一个xml文档中,有且仅有一个根标签 3.2 属性 语法: <Student name="eric">student</Student> 注意: 1)属性值必须以引号包含,不能省略,也不能单双引号混用!!! 2)一个标签内可以有多个属性,但不能出现重复的属性名!!! 3.3 注释 语言: <!-- xml注释 --> 3.4 文档声明 语法: <?xml version="1.0" encoding="utf-8"?>(文件保存也需要已同样的编码保存) version: xml的版本号 encoding: 解析xml文件时查询的码表(解码过程时查询的码表) 注意: 1)如果在ecplise工具中开发xml文件,保存xml文件时自动按照文档声明的encoding来保存文 件。 2)如果用记事本工具修改xml文件,注意保存xml文件按照文档声明的encoding的码表来保存。 3.5 转义字符 在xml中内置了一些特殊字符,这些特殊字符不能直接被浏览器原样输出。如果希望把这些特殊字符按照原样输出到浏览器,对这些特殊字符进行转义。转义之后的字符就叫转义字节。 特殊字符 转义字符 < < > > " " & & 空格 &nsbp; 3.6 CDATA块 作用: 可以让一些需要进行包含特殊字符的内容统一进行原样输出。 <![CDATA[ <html><head>head</head><body>body</body></html> ]]> 3.7 处理指令 作用: 告诉xml解析如果解析xml文档 案例: <?xml-stylesheet type="text/css" href="1.css"?> 告诉xml解析该xml文档引用了哪个css文件 需要提前xml内容可以使用xml-stylesheet指令指令 */4 DOM解析XML
/* 4.1 引入 xml文件除了给开发者看,更多的情况使用程序读取xml文件的内容。这叫做xml解析 4.2 XML解析方式(原理不同) DOM解析 SAX解析 4.3 XML解析工具 DOM解析原理: 1)JAXP (oracle-Sun公司官方) 2)JDOM工具(非官方) 3)Dom4J工具(非官方) 三大框架(默认读取xml的工具就是Dom4j) ....... SAX解析原理: 1)Sax解析工具(oracle-sun公司官方) 4.4 什么是DOM解析 DOM解析原理:xml解析器一次性把整个xml文档加载进内存,然后在内存中构建一颗Document的对象树, 通过Document对象,得到树上的节点对象,通过节点对象访问(操作)到xml文档的内容。 4.5 Dom4j工具 非官方,不在jdk中。 使用步骤: 1)导入dom4j的核心包。 dom4j-1.6.1.jar 2)编写Dom4j读取xml文件代码 public static void main(String[] args) { try { //1.创建一个xml解析器对象 SAXReader reader = new SAXReader(); //2.读取xml文档,返回Document对象 Document doc = reader.read(new File("./src/contact.xml")); System.out.println(doc); } catch (DocumentException e) { e.printStackTrace(); throw new RuntimeException(e); } } 4.6 Domj4读取xml文件 节点: Iterator Element.nodeIterator(); //获取当前标签节点下的所有子节点 标签: Element Document.getRootElement(); //获取xml文档的根标签 Element ELement.element("标签名") //指定名称的第一个子标签 Iterator<Element> Element.elementIterator("标签名");// 指定名称的所有子标签 List<Element> Element.elements(); //获取所有子标签 属性: String Element.attributeValue("属性名") //获取指定名称的属性值 Attribute Element.attribute("属性名");//获取指定名称的属性对象 Attribute.getName() //获取属性名称 Attibute.getValue() //获取属性值 List<Attribute> Element.attributes(); //获取所有属性对象 Iterator<Attribute> Element.attibuteIterator(); //获取所有属性对象 文本: Element.getText(); //获取当前标签的文本 Element.elementText("标签名") //获取当前标签的指定名称的子标签的文本内容 */DOM解析读取xml文件内容:节点、标签、属性、文本
import java.io.File; import java.util.Iterator; import java.util.List; import org.dom4j.Attribute; import org.dom4j.Document; import org.dom4j.Element; import org.dom4j.Node; import org.dom4j.io.SAXReader; import org.junit.Test; /** * DOM解析读取xml文件内容:节点、标签、属性、文本 */ public class Demo2 { /** * 得到节点信息 */ @Test pub 4000 lic void test1() throws Exception{ //1.读取xml文档,返回Document对象 SAXReader reader = new SAXReader(); Document doc = reader.read(new File("./src/contact.xml")); //2.nodeIterator: 得到当前节点下的所有子节点对象(不包含孙以下的节点) Iterator<Node> it = doc.nodeIterator(); while(it.hasNext()){//判断是否有下一个元素 Node node = it.next();//取出元素 String name = node.getName();//得到节点名称 //System.out.println(name); //System.out.println(node.getClass()); //继续取出其下面的子节点 //只有标签节点才有子节点 //判断当前节点是否是标签节点 if(node instanceof Element){ Element elem = (Element)node; Iterator<Node> it2 = elem.nodeIterator(); while(it2.hasNext()){ Node n2 = it2.next(); System.out.println(n2.getName()); } } } } /** * 遍历xml文档的所有节点 * @throws Exception */ @Test public void test2() throws Exception{ //1.读取xml文档,返回Document对象 SAXReader reader = new SAXReader(); Document doc = reader.read(new File("./src/contact.xml")); //得到根标签 Element rooElem = doc.getRootElement(); getChildNodes(rooElem); } /** * 获取传入的标签下的所有子节点 */ private void getChildNodes(Element elem){ System.out.println(elem.getName()); //得到子节点 Iterator<Node> it = elem.nodeIterator(); while(it.hasNext()){ Node node = it.next(); //1.判断是否是标签节点 if(node instanceof Element){ Element el = (Element)node; //递归 getChildNodes(el); } }; } /** * 获取具体的标签 */ @Test public void test3() throws Exception{ //1.读取xml文档,返回Document对象 SAXReader reader = new SAXReader(); Document doc = reader.read(new File("./src/contact.xml")); //2.得到根标签 Element rootElem = doc.getRootElement(); //得到根标签名称 String name = rootElem.getName(); System.out.println(name); //3.得到当前标签下指定名称的第一个子标签 /* Element contactElem = rootElem.element("contact"); System.out.println(contactElem.getName()); */ //4.通过标签名得到当前标签下指定名称的所有子标签 /* Iterator<Element> it = rootElem.elementIterator("contact"); while(it.hasNext()){ Element elem = it.next(); System.out.println(elem.getName()); } */ //5.得到当前标签下的的所有子标签 List<Element> list = rootElem.elements(); //遍历List的方法 //1)传统for循环 2)增强for循环 3)迭代器 /*for(int i=0;i<list.size();i++){ Element e = list.get(i); System.out.println(e.getName()); }*/ /* for(Element e:list){ System.out.println(e.getName()); }*/ /* Iterator<Element> it = list.iterator(); //ctrl+2 松开 l while(it.hasNext()){ Element elem = it.next(); System.out.println(elem.getName()); }*/ //获取更深层次的标签(方法只能一层层地获取) Element nameElem = doc.getRootElement().element("contact").element("name"); System.out.println(nameElem.getName()); } /** * 获取属性 */ @Test public void test4() throws Exception{ //1.读取xml文档,返回Document对象 SAXReader reader = new SAXReader(); Document doc = reader.read(new File("./src/contact.xml")); //获取属性:(先获的属性所在的标签对象,然后才能获取属性) //1.得到标签对象 Element contactElem = doc.getRootElement().element("contact"); //2.得到属性 //2.1 得到指定名称的属性值 /* String idValue = contactElem.attributeValue("id"); System.out.println(idValue); */ //2.2 得到指定属性名称的属性对象 /*Attribute idAttr = contactElem.attribute("id"); //getName: 属性名称 getValue:属性值 System.out.println(idAttr.getName() +"=" + idAttr.getValue());*/ //2.3 得到所有属性对象,返回List集合 /*List<Attribute> list = contactElem.attributes(); //遍历属性 for (Attribute attr : list) { System.out.println(attr.getName()+"="+attr.getValue()); }*/ //2.4 得到所有属性对象,返回迭代器 Iterator<Attribute> it = contactElem.attributeIterator(); while(it.hasNext()){ Attribute attr = it.next(); System.out.println(attr.getName()+"="+attr.getValue()); } } /** * 获取文本 */ @Test public void test5() throws Exception{ //1.读取xml文档,返回Document对象 SAXReader reader = new SAXReader(); Document doc = reader.read(new File("./src/contact.xml")); /** * 注意: 空格和换行也是xml的内容 */ String content = doc.getRootElement().getText(); System.out.println(content); //获取文本(先获取标签,再获取标签上的文本) Element nameELem = doc.getRootElement().element("contact").element("name"); //1. 得到文本 String text = nameELem.getText(); System.out.println(text); //2. 得到指定子标签名的文本内容 String text2 = doc.getRootElement().element("contact").elementText("phone"); System.out.println(text2); } }DOM解析完整读取xml文档内容
import java.io.File; import java.util.Iterator; import java.util.List; import org.dom4j.Attribute; import org.dom4j.Document; import org.dom4j.Element; import org.dom4j.Node; import org.dom4j.Text; import org.dom4j.io.SAXReader; import org.junit.Test; /** * 练习-完整读取xml文档内容 */ public class Demo3 { @Test public void test() throws Exception{ //读取xml文档 SAXReader reader = new SAXReader(); Document doc = reader.read(new File("./src/contact.xml")); //读取根标签 Element rootELem = doc.getRootElement(); StringBuffer sb = new StringBuffer(); // 获取当前标签的所有子标签 getChildNodes(rootELem,sb); System.out.println(sb.toString()); } /** * 获取当前标签的所有子标签 */ private void getChildNodes(Element elem,StringBuffer sb){ //System.out.println(elem.getName()); /* List<Element> list = elem.elements(); for(Element element : list){ getChildNodes(element); }*/ //开始标签 sb.append("<"+elem.getName()); //得到标签的属性列表 List<Attribute> attrs = elem.attributes(); if(attrs!=null){ for (Attribute attr : attrs) { //System.out.println(attr.getName()+"="+attr.getValue()); sb.append(" "+attr.getName()+"=\""+attr.getValue()+"\""); } } sb.append(">"); //得到文本 //String content = elem.getText(); //System.out.println(content); Iterator<Node> it = elem.nodeIterator(); while(it.hasNext()){ Node node = it.next(); //标签 if(node instanceof Element){ Element el = (Element)node; getChildNodes(el,sb); } //文本 if(node instanceof Text){ Text text = (Text)node; sb.append(text.getText()); } } //结束标签 sb.append("</"+elem.getName()+">"); } }
DOM解析把xml文档信息封装到对象中
import java.io.File; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import org.dom4j.Document; import org.dom4j.Element; import org.dom4j.io.SAXReader; /** * 把xml文档信息封装到对象中 */ public class Demo4 { public static void main(String[] args) throws Exception{ List<Contact> list = new ArrayList<Contact>(); //读取xml,封装对象 SAXReader reader = new SAXReader(); Document doc = reader.read(new File("./src/contact.xml")); //读取contact标签 Iterator<Element> it = doc.getRootElement().elementIterator("contact"); while(it.hasNext()){ Element elem = it.next(); //创建Contact Contact contact = new Contact(); contact.setId(elem.attributeValue("id")); contact.setName(elem.elementText("name")); contact.setAge(elem.elementText("age")); contact.setPhone(elem.elementText("phone")); contact.setEmail(elem.elementText("email")); contact.setQq(elem.elementText("qq")); list.add(contact); } for (Contact contact : list) { System.out.println(contact); } } }5 Dom解析修改xml文档
/* 5.1 写出内容到xml文档 XMLWriter writer = new XMLWriter(OutputStream, OutputForamt) wirter.write(Document); 5.2 修改xml文档的API 增加: DocumentHelper.createDocument() 增加文档 addElement("名称") 增加标签 addAttribute("名称",“值”) 增加属性 修改: Attribute.setValue("值") 修改属性值 Element.addAtribute("同名的属性名","值") 修改同名的属性值 Element.setText("内容") 修改文本内容 删除 Element.detach(); 删除标签 Attribute.detach(); 删除属性 */
import java.io.File; import java.io.FileOutputStream; import org.dom4j.Attribute; import org.dom4j.Document; import org.dom4j.DocumentHelper; import org.dom4j.Element; import org.dom4j.io.OutputFormat; import org.dom4j.io.SAXReader; import org.dom4j.io.XMLWriter; import org.junit.Test; /** * 修改xml内容 * 增加:文档,标签 ,属性 * 修改:属性值,文本 * 删除:标签,属性 */ public class Demo3 { /** * 增加:文档,标签 ,属性 */ @Test public void test1() throws Exception{ /** * 1.创建文档 */ Document doc = DocumentHelper.createDocument(); /** * 2.增加标签 */ Element rootElem = doc.addElement("contactList"); //doc.addElement("contactList"); Element contactElem = rootElem.addElement("contact"); contactElem.addElement("name"); /** * 3.增加属性 */ contactElem.addAttribute("id", "001"); contactElem.addAttribute("name", "eric"); //把修改后的Document对象写出到xml文档中 FileOutputStream out = new FileOutputStream("e:/contact.xml"); OutputFormat format = OutputFormat.createPrettyPrint(); //漂亮的格式.有空格和换行.开发调试的时候 //OutputFormat format = OutputFormat.createCompactFormat(); //紧凑的格式.去除空格换行.项目上线的时候 /** * 2.指定生成的xml文档的编码 * 同时影响了xml文档保存时的编码和xml文档声明的encoding的编码(xml解析时的编码) * 结论: 使用该方法生成的xml文档避免中文乱码问题。 */ format.setEncoding("utf-8"); XMLWriter writer = new XMLWriter(out,format); writer.write(doc); writer.close(); } /** * 修改:属性值,文本 * @throws Exception */ @Test public void test2() throws Exception{ Document doc = new SAXReader().read(new File("./src/contact.xml")); /** * 方案一: 修改属性值 1.得到标签对象 2.得到属性对象 3.修改属性值 */ //1.1 得到标签对象 /* Element contactElem = doc.getRootElement().element("contact"); //1.2 得到属性对象 Attribute idAttr = contactElem.attribute("id"); //1.3 修改属性值 idAttr.setValue("003"); */ /** * 方案二: 修改属性值 */ //1.1 得到标签对象 /* Element contactElem = doc.getRootElement().element("contact"); //1.2 通过增加同名属性的方法,修改属性值 contactElem.addAttribute("id", "004"); */ /** * 修改文本 1.得到标签对象 2.修改文本 */ Element nameElem = doc.getRootElement().element("contact").element("name"); nameElem.setText("李四"); FileOutputStream out = new FileOutputStream("e:/contact.xml"); OutputFormat format = OutputFormat.createPrettyPrint(); format.setEncoding("utf-8"); XMLWriter writer = new XMLWriter(out,format); writer.write(doc); writer.close(); } /** * 删除:标签,属性 * @throws Exception */ @Test public void test3() throws Exception{ Document doc = new SAXReader().read(new File("./src/contact.xml")); /** * 1.删除标签 1.1 得到标签对象 1.2 删除标签对象 */ // 1.1 得到标签对象 /* Element ageElem = doc.getRootElement().element("contact").element("age"); //1.2 删除标签对象 ageElem.detach(); //ageElem.getParent().remove(ageElem); */ /** * 2.删除属性 2.1得到属性对象 2.2 删除属性 */ //2.1得到属性对象 //得到第二个contact标签 Element contactElem = (Element)doc.getRootElement().elements().get(1); //2.2 得到属性对象 Attribute idAttr = contactElem.attribute("id"); //2.3 删除属性 idAttr.detach(); //idAttr.getParent().remove(idAttr); FileOutputStream out = new FileOutputStream("e:/contact.xml"); OutputFormat format = OutputFormat.createPrettyPrint(); format.setEncoding("utf-8"); XMLWriter writer = new XMLWriter(out,format); writer.write(doc); writer.close(); } }
import java.io.File; import java.io.FileOutputStream; import java.util.Iterator; import org.dom4j.Document; import org.dom4j.DocumentHelper; import org.dom4j.Element; import org.dom4j.io.OutputFormat; import org.dom4j.io.SAXReader; import org.dom4j.io.XMLWriter; import org.junit.Test; /** * 练习: * 1.使用dom4j的api来生成以下的xml文件 <Students> <Student id="1"> <name>张三</name> <gender>男</gender> <grade>计算机1班</grade> <address>广州天河</address> </Student> <Student id="2"> <name>李四</name> <gender>女</gender> <grade>计算机2班</grade> <address>广州越秀</address> </Student> </Students> 2.修改id为2的学生的姓名,改为“王丽” 3.删除id为2的学生 * @author APPle * */ public class Demo4 { /** * 1.生成指定xml文档 * @throws Exception */ @Test public void test1() throws Exception{ //1.内存创建xml文档 Document doc = DocumentHelper.createDocument(); //2.写入内容 Element rootElem = doc.addElement("Students"); //2.1 增加标签 Element studentElem1 = rootElem.addElement("Student"); //2.2 增加属性 studentElem1.addAttribute("id", "1"); //2.3 增加标签,同时设置文本 studentElem1.addElement("name").setText("张三"); studentElem1.addElement("gender").setText("男"); studentElem1.addElement("grade").setText("计算机1班"); studentElem1.addElement("address").setText("广州天河"); //2.1 增加标签 Element studentElem2 = rootElem.addElement("Student"); //2.2 增加属性 studentElem2.addAttribute("id", "2"); //2.3 增加标签,同时设置文本 studentElem2.addElement("name").setText("李四"); studentElem2.addElement("gender").setText("女"); studentElem2.addElement("grade").setText("计算机2班"); studentElem2.addElement("address").setText("广州越秀"); //3.内容写出到xml文件 //3.1 输出位置 FileOutputStream out = new FileOutputStream("e:/student.xml"); //3.2 指定格式 OutputFormat format = OutputFormat.createPrettyPrint(); // 设置编码 format.setEncoding("utf-8"); XMLWriter writer = new XMLWriter(out,format); //3.3 写出内容 writer.write(doc); //3.4关闭资源 writer.close(); } /** * 2.修改id为2的学生姓名 * @throws Exception */ @Test public void test2() throws Exception{ //1.查询到id为2的学生 Document doc = new SAXReader().read(new File("e:/student.xml")); //1.1 找到所有的Student标签 Iterator<Element> it = doc.getRootElement().elementIterator("Student"); while(it.hasNext()){ Element stuElem = it.next(); //1.2 查询id为id的学生标签 if(stuElem.attributeValue("id").equals("2")){ stuElem.element("name").setText("王丽"); break; } } //3.1 输出位置 FileOutputStream out = new FileOutputStream("e:/student.xml"); //3.2 指定格式 OutputFormat format = OutputFormat.createPrettyPrint(); // 设置编码 format.setEncoding("utf-8"); XMLWriter writer = new XMLWriter(out,format); //3.3 写出内容 writer.write(doc); //3.4关闭资源 writer.close(); } /** * 3.删除id为2的学生 * @throws Exception */ @Test public void test3() throws Exception{ //1. f971 查询到id为2的学生 Document doc = new SAXReader().read(new File("e:/student.xml")); //1.1 找到所有的Student标签 Iterator<Element> it = doc.getRootElement().elementIterator("Student"); while(it.hasNext()){ Element stuElem = it.next(); //1.2 查询id为id的学生标签 if(stuElem.attributeValue("id").equals("2")){ //1.3 删除该学生标签 stuElem.detach(); break; } } //3.1 输出位置 FileOutputStream out = new FileOutputStream("e:/student.xml"); //3.2 指定格式 OutputFormat format = OutputFormat.createPrettyPrint(); // 设置编码 format.setEncoding("utf-8"); XMLWriter writer = new XMLWriter(out,format); //3.3 写出内容 writer.write(doc); //3.4关闭资源 writer.close(); } }6 xPath技术
/* 6.1 引入 问题:当使用dom4j查询比较深的层次结构的节点(标签,属性,文本),比较麻烦!!! 6.2 xPath作用 主要是用于快速获取所需的节点对象。 6.3 在dom4j中如何使用xPath技术 1)导入xPath支持jar包 。 jaxen-1.1-beta-6.jar 2)使用xpath方法 List<Node> selectNodes("xpath表达式"); 查询多个节点对象 Node selectSingleNode("xpath表达式"); 查询一个节点对象 // 删除id值为2的学生标签 Document doc = new SAXReader().read(new File("e:/student.xml")); //1.查询id为2的学生标签 //使用xpath技术 Element stuElem = (Element)doc.selectSingleNode("//Student[@id='2']"); //2.删除标签 stuElem.detach(); 6.4 xPath语法 / 绝对路径 表示从xml的根位置开始或子元素(一个层次结构) // 相对路径 表示不分任何层次结构的选择元素。 * 通配符 表示匹配所有元素 [] 条件 表示选择什么条件下的元素 @ 属性 表示选择属性节点 and 关系 表示条件的与关系(等价于&&) text() 文本 表示选择文本内容 6.5 案例 用户登录功能: 用户输入用户名和密码 -> 到“数据库”查询是否有对应的用户 -> 有: 则表示登录成功 没有: 则表示登录失败 用xml当做数据库 user.xml 用来存储用户的数据 */
import java.io.File; import java.util.List; import org.dom4j.Document; import org.dom4j.Node; import org.dom4j.io.SAXReader; /** * 学习xPath表达式语法 */ public class Demo2 { public static void main(String[] args) throws Exception { Document doc = new SAXReader().read(new File("./src/contact.xml")); String xpath = ""; /** * 1. / 绝对路径 表示从xml的根位置开始或子元素(一个层次结构) */ xpath = "/contactList"; xpath = "/contactList/contact"; /** * 2. // 相对路径 表示不分任何层次结构的选择元素。 */ xpath = "//contact/name"; xpath = "//name"; /** * 3. * 通配符 表示匹配所有元素 */ xpath = "/contactList/*"; //根标签contactList下的所有直接子标签 xpath = "/contactList//*";//根标签contactList下的所有标签(不分层次结构) /** * 4. [] 条件 表示选择什么条件下的元素 */ //带有id属性的contact标签 xpath = "//contact[@id]"; //第二个的contact标签 xpath = "//contact[2]"; //选择最后一个contact标签 xpath = "//contact[last()]"; /** * 5. @ 属性 表示选择属性节点 */ xpath = "//@id"; //选择id属性节点对象,返回的是Attribute对象 xpath = "//contact[not(@id)]";//选择不包含id属性的contact标签节点 xpath = "//contact[@id='002']";//选择id属性值为002的contact标签 xpath = "//contact[@id='001' and @name='eric']";//选择id属性值为001,且name属性为eric的contact标签 /** *6. text() 表示选择文本内容 */ //选择name标签下的文本内容,返回Text对象 xpath = "//name/text()"; xpath = "//contact/name[text()='张三']";//选择姓名为张三的name标签 List<Node> list = doc.selectNodes(xpath); for (Node node : list) { System.out.println(node); } } }xpath案例: 模拟用户登录效果
import java.io.BufferedReader; import java.io.File; import java.io.InputStreamReader; import org.dom4j.Document; import org.dom4j.Element; import org.dom4j.io.SAXReader; /** * xpath案例: 模拟用户登录效果 */ public class Demo3 { public static void main(String[] args)throws Exception{ //1.获取用户输入的用户名和密码 BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); System.out.println("请输入用户名:"); String name = br.readLine(); System.out.println("请输入密码:"); String password = br.readLine(); //2.到“数据库”中查询是否有对应的用户 //对应的用户: 在user.xml文件中找到一个 //name属性值为‘用户输入’,且password属性值为‘用户输入’的user标签 Document doc = new SAXReader().read(new File("./src/user.xml")); Element userElem = (Element)doc.selectSingleNode("//user[@name='" +name +"' and @password='"+password+"']"); if(userElem!=null){ //登录成功 System.out.println("登录成功"); }else{ //登录失败 System.out.println("登录失败"); } } }使用xpath技术读取一个规范的html文档
import java.io.File; import java.util.Iterator; import java.util.List; import org.dom4j.Document; import org.dom4j.Element; import org.dom4j.io.SAXReader; /** * 使用xpath技术读取一个规范的html文档 */ public class Demo4 { public static void main(String[] args) throws Exception{ Document doc = new SAXReader().read(new File("./src/personList.html")); //System.out.println(doc); //读取title标签 Element titleElem = (Element)doc.selectSingleNode("//title"); String title = titleElem.getText(); System.out.println(title); /** * 练习:读取联系人的所有信息 * 按照以下格式输出: * 编号:001 姓名:张三 性别:男 年龄:18 地址:xxxx 电话: xxxx * 编号:002 姓名:李四 性别:女 年龄:20 地址:xxxx 电话: xxxx * ...... */ //1.读取出所有tbody中的tr标签 List<Element> list = (List<Element>)doc.selectNodes("//tbody/tr"); //2.遍历 for (Element elem : list) { //编号 //String id = ((Element)elem.elements().get(0)).getText(); String id = elem.selectSingleNode("td[1]").getText(); //姓名 String name = ((Element)elem.elements().get(1)).getText(); //性别 String gender = ((Element)elem.elements().get(2)).getText(); //年龄 String age = ((Element)elem.elements().get(3)).getText(); //地址 String address = ((Element)elem.elements().get(4)).getText(); //电话 String phone = ((Element)elem.elements().get(5)).getText(); System.out.println("编号:"+id+"\t姓名:"+name+"\t性别:"+ gender+"\t年龄:"+age+"\t地址:"+address+"\t电话:"+phone); } } }7 SAX解析
/* 7.1回顾DOM解析 DOM解析原理:一次性把xml文档加载进内存,然后在内存中构建Document树。对内存要求比较要。 缺点:不适合读取大容量的xml文件,容易导致内存溢出。 SAX解析原理:加载一点,读取一点,处理一点。对内存要求比较低。 7.2 SAX解析工具 SAX解析工具- Sun公司提供的。内置在jdk中。org.xml.sax.* 核心的API: SAXParser类: 用于读取和解析xml文件对象 parse(File f, DefaultHandler dh)方法: 解析xml文件 参数一: File:表示 读取的xml文件。 参数二: DefaultHandler: SAX事件处理程序。使用DefaultHandler的子类 例如: 1.创建SAXParser对象 SAXParser parser=SAXParserFactory.newInstance().newSAXParser(); 2.调用parse方法 parser.parse(new File("./src/contact.xml"), new MyDefaultHandler()); [一个类继承class 类名(extends DefaultHandler) 在调用是创建传进去 DefaultHandler类的API: void startDocument(): 在读到文档开始时调用 void endDocument():在读到文档结束时调用 void startElement(String uri, String localName, String qName, Attributes attributes):读到开始标签时调用 void endElement(String uri, String localName, String qName):读到结束标签时调用 void characters(char[] ch, int start, int length): 读到文本内容时调用 DOM解析 vs SAX解析 DOM解析 原理:一次性加载xml文档,不适合大容量的文件读取 DOM解析可以任意进行增删改查 DOM解析任意读取任何位置的数据,甚至往回读 DOM解析面向对象的编程方法(Node,Element,Attribute),Java开发者编码比较简单。 SAX解析 原理: 加载一点,读取一点,处理一点。适合大容量文件的读取 SAX解析只能读取 SAX解析只能从上往下,按顺序读取,不能往回读 SAX解析基于事件的编程方法。java开发编码相对复杂。 */SAX读取xml文件程序
import java.io.File; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; /** * SAX读取xml文件程序 */ public class Demo1 { public static void main(String[] args) throws Exception{ //1.创建SAXParser对象 SAXParser parser = SAXParserFactory.newInstance().newSAXParser(); //2.调用parse方法 /** * 参数一: xml文档 * 参数二: DefaultHandler的子类 */ parser.parse(new File("./src/contact.xml"), new MyDefaultHandler()); } } import org.xml.sax.Attributes; import org.xml.sax.SAXException; import org.xml.sax.helpers.DefaultHandler; /** * SAX处理程序(如何解析xml文档) */ public class MyDefaultHandler extends DefaultHandler { /** * 开始文档时调用 */ @Override public void startDocument() throws SAXException { System.out.println("MyDefaultHandler.startDocument()"); } /** * 开始标签时调用 * @param qName: 表示开始标签的标签名 * @param attributes: 表示开始标签内包含的属性列表 */ @Override public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { System.out.println("MyDefaultHandler.startElement()-->"+qName); } /** * 结束标签时调用 * @param qName: 结束标签的标签名称 */ @Override public void endElement(String uri, String localName, String qName)throws SAXException { System.out.println("MyDefaultHandler.endElement()-->"+qName); } /** * 读到文本内容的时调用 * @param ch: 表示当前读完的所有文本内容 * @param start: 表示当前文本内容的开始位置 * @param length: 表示当前文本内容的长度 */ @Override public void characters(char[] ch, int start, int length) throws SAXException { //得到当前文本内容 String content = new String(ch,start,length); System.out.println("MyDefaultHandler.characters()-->"+content); } /** * 结束文档时调用 */ @Override public void endDocument() throws SAXException { System.out.println("MyDefaultHandler.endDocument()"); } }SAX解析读取完整文档内容
import java.io.File; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; /** * 读取contact.xml文件,完整输出文档内容 */ public class Demo2 { public static void main(String[] args)throws Exception { //1.创建SAXParser SAXParser parser = SAXParserFactory.newInstance().newSAXParser(); //2.读取xml文件 MyDefaultHandler2 handler = new MyDefaultHandler2(); parser.parse(new File("./src/contact.xml"), handler); String content = handler.getContent(); System.out.println(content); } } import org.xml.sax.Attributes; import org.xml.sax.SAXException; import org.xml.sax.helpers.DefaultHandler; /** * SAX处理器程序 */ public class MyDefaultHandler2 extends DefaultHandler { //存储xml文档信息 private StringBuffer sb = new StringBuffer(); //获取xml信息 public String getContent(){ return sb.toString(); } /** * 开始标签 */ @Override public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { sb.append("<"+qName); //判断是否有属性 if(attributes!=null){ for(int i=0;i<attributes.getLength();i++){ //得到属性名称 String attrName = attributes.getQName(i); //得到属性值 String attrValue = attributes.getValue(i); sb.append(" "+attrName+"=\""+attrValue+"\""); } } sb.append(">"); } /** * 文本内容 */ @Override public void characters(char[] ch, int start, int length) throws SAXException { //得到当前读取的文本 String content = new String(ch,start,length); sb.append(content); } /** * 结束标签 */ @Override public void endElement(String uri, String localName, String qName) throws SAXException { sb.append("</"+qName+">"); } }sax解析封装成对象
import java.io.File; import java.util.List; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; /** * 使用sax解析把 xml文档封装成对象 */ public class Demo3 { public static void main(String[] args)throws Exception { SAXParser parser = SAXParserFactory.newInstance().newSAXParser(); MyDefaultHandler3 handler = new MyDefaultHandler3(); parser.parse(new File("./src/contact.xml"), handler); List<Contact> list = handler.getList(); for (Contact contact : list) { System.out.println(contact); } } } import java.util.ArrayList; import java.util.List; import org.xml.sax.Attributes; import org.xml.sax.SAXException; import org.xml.sax.helpers.DefaultHandler; /** * SAX处理程序 */ public class MyDefaultHandler3 extends DefaultHandler { //存储所有联系人对象 private List<Contact> list = new ArrayList<Contact>(); public List<Contact> getList(){ return list; } //保存一个联系人信息 private Contact contact; /** * 思路: * 1)创建Contact对象 * 2)把每个contact标签内容存入到Contact对象 * 3)把Contact对象放入List中 */ //用于临时存储当前读到的标签名 private String curTag; @Override public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { curTag = qName; //读取到contact的开始标签创建Contact对象 if("contact".equals(qName)){ contact = new Contact(); //设置id值 contact.setId(attributes.getValue("id")); } } @Override public void characters(char[] ch, int start, int length) throws SAXException { //当前文本内容 String content = new String(ch,start,length); if("name".equals(curTag)){ contact.setName(content); } if("age".equals(curTag)){ contact.setAge(content); } if("phone".equals(curTag)){ contact.setPhone(content); } if("email".equals(curTag)){ contact.setEmail(content); } if("qq".equals(curTag)){ contact.setQq(content); } } @Override public void endElement(String uri, String localName, String qName) throws SAXException { //设置空时为了避免空格换行设置到对象的属性中 curTag = null; //读到contact的结束标签放入List中 if("contact".equals(qName)){ list.add(contact); } } }
总结
/* 1)Dom4j修改XML文档 写出xml文档: XMLWriter writer = new XMLWriter() writer.wrtite(doc); 增加: DocumentHelper.createDocument() 增加新文档 Element.addElement("name"); 增加子标签 Element.addAtrribute(“name”,“value”) 增加属性 修改: Attribute.setValue("value"); 修改属性值 Element.setText("value"); 修改文本内容 删除: Element.detach(); 删除标签 Attribute.detach(); 删除属性 2)XPath技术: 快速找到xml元素(标签,属性,文本) 2.1 dom4j使用xpath: List<Node> list = Element.selectNodes("xpath表达式"); 多个节点对象 Node node = Element.selectSingleNode("xpath表达式"); 一个节点对象 xpath表达式: / 表示根位置 或者 子标签 // 表示后代标签(不分层次结构) * 表示所有元素 [ ] 表示条件 @ 表示选择属性 text() 表示选择文本 and 表示与条件 3)SAX解析: 原理: 加载一点,解析一点,处理一点,对内存要求不高!!!(基于事件) SAXPasser 类: parser(File file, DefaultHandler handler):该方法使用sax解析方式去解析xml文档 DefaultHandler类:重写该类中的一些方法,用于处理xml文档 startElement( .... String qName): 读到开始标签时调用 characterrs(char[] ch,int start,int length); 读到文本内容时调用(包括空格和换行) endElement(.....String qName): 读到结束标签时调用 */8 XML约束
/* 2.1 引入 XML语法: 规范的xml文件的基本编写规则。(由w3c组织制定的) XML约束: 2.2 XML约束技术 DTD约束:语法相对简单,功能也相对简单 Schema约束:语法相对复杂,功能也相对强大。名称空间) 2.3 DTD约束 1)导入dtd方式 内部导入: <!DOCTYPE note [ <!ELEMENT note (to,from,heading,body)> <!ELEMENT to (#PCDATA)> <!ELEMENT from (#PCDATA)> <!ELEMENT heading (#PCDATA)> <!ELEMENT body (#PCDATA)> ]> 外部导入 本地文件系统: <!DOCTYPE note SYSTEM "note.dtd"> 公共的外部导入: <!DOCTYPE 根元素 PUBLIC "http://gz.itcast.cn/itcast.dtd"> 2)DTD语法 约束标签 <!ELEMENT 元素名称 类别> 或 <!ELEMENT 元素名称 (元素内容)> 类别: 空标签: EMPTY。 表示元素一定是空元素。 普通字符串: (#PCDATA)。表示元素的内容一定是普通字符串(不能含有子标签)。 任何内容: ANY。表示元素的内容可以是任意内容(包括子标签) (元素内容): 顺序问题: <!ELEMENT 元素名称 (子元素名称 1,子元素名称 2,.....)>: 按顺序出现子标签 次数问题: 标签 : 必须且只出现1次。 标签+ : 至少出现1次 标签* : 0或n次。 标签? : 0 或1次。 约束属性 <!ATTLIST 元素名称 属性名称 属性类型 默认值> 默认值: #REQUIRED 属性值是必需的 #IMPLIED 属性不是必需的 #FIXED value 属性不是必须的,但属性值是固定的 属性类型:控制属性值的 CDATA :表示普通字符串 (en1|en2|..): 表示一定是任选其中的一个值 ID:表示在一个xml文档中该属性值必须唯一。值不能以数字开头 <?xml version="1.0"?> <!DOCTYPE note SYSTEM "note.dtd"> <note> <to id="a1"></to> <to id="a2"></to> <to id="a3"></to> <heading>Reminder</heading> <heading>Reminder</heading> <heading>Reminder</heading> <body>Don't forget me this weekend</body> <body>Don't forget me this weekend</body> <body>Don't forget me this weekend</body> </note> <!ELEMENT note (from?,to+,heading*,body+)> <!ELEMENT to EMPTY> <!ELEMENT from (#PCDATA)> <!ELEMENT heading (#PCDATA)> <!ELEMENT body (#PCDATA)> <!ATTLIST to id ID #REQUIRED> 2.4 Schema约束 名称空间:告诉xml文档的哪个元素被哪个schema文档约束。 在一个xml文档中,不同的标签可以受到不同的schema文档的约束。 1)一个名称空间受到schema文档约束的情况 2)多个名称空间受到多个schema文档约束的情况 3)默认名称空间的情况 4)没有名称空间的情况 <?xml version="1.0" encoding="UTF-8"?> <itcast:书架 xmlns:itcast="http://www.itcast.cn" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.itcast.cn book.xsd"> <itcast:书> <itcast:书名>JavaScript网页开发</itcast:书名> <itcast:作者>张孝祥</itcast:作者> <itcast:售价>28</itcast:售价> </itcast:书> </itcast:书架> <?xml version="1.0" encoding="UTF-8" ?> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.itcast.cn" elementFormDefault="qualified"> <xs:element name='书架' > <xs:complexType> <xs:sequence maxOccurs='unbounded' > <xs:element name='书' > <xs:complexType> <xs:sequence> <xs:element name='书名' type='xs:string' /> <xs:element name='作者' type='xs:string' /> <xs:element name='售价' type='xs:integer' /> </xs:sequence> </xs:complexType> </xs:element> </xs:sequence> </xs:complexType> </xs:element> </xs:schema> */
相关文章推荐
- 学习笔记-Java中的xml文件读取之DOM解析
- Java解析XML(一) 使用DOM读取XML文件
- 运用java读取xml文件---DOM 解析
- TestDom读取XML文件解析DOM
- 在Java下使用DOM来读取/修改Xml文件
- Android数据存储之DOM解析XML文件(读取部分)
- xml文件读取的4种解析方式(DOM和SAX)
- 在Java下使用DOM来读取/修改Xml文件
- 利用AJAX解析XML文件并且用 DOM呈现
- java写的用DOM来解析、修改、删除XML
- 读取,添加,修改xml文件
- jom写文件实现,jdom读取XML文件,解析某一element并改值存入文
- dom解析xml文件
- jQuery 行级解析读取XML文件(附源码)
- 对XML文件的CRUD(添加,读取,搜索,修改,删除)的例子
- java解析xml文件的2种方法:sax,dom
- 用DOM读取XML文件例子(JAVA)
- asp.net 实现对xml文件的 读取,添加,删除,修改
- libxml2对XML文件的创建、解析、查找、修改
- 使用Dom解析xml文件