4 XML
1 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标签。
2 HTML和XML的区别
HTML
名称: 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)作为数据的载体(存储数据,小型的“数据库”)
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注释 -->
练习:
通讯录系统
联系人数据:编号 (唯一的) 姓名 年龄 电话 邮箱 QQ
要求:
contact.xml
1)设计一个xml文件,用于存储联系人数据
2)这个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块
作用: 可以让一些需要进行包含特殊字符的内容统一进行原样输出。
3.7 处理指令
作用: 告诉xml解析如果解析xml文档
案例: <?xml-stylesheet type="text/css" href="1.css"?> 告诉xml解析该xml文档引用了哪个css文件
需要提前xml内容可以使用xml-stylesheet指令指令
4 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 Dom4j读取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("标签名") //获取当前标签的指定名称的子标签的文本内容
读取XML文件
public class Demo5 { //把xml文档信息封装到对象中 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 Dom4j修改xml文档
5.1 写出内容到xml文档
XMLWriter writer = new XMLWriter(OutputStream, OutputForamt)
wirter.write(Document);
//写出内容到xml文档 public static void main(String[] args) throws Exception { Document doc = new SAXReader().read(new File("./src/AndroidManifest.xml")); //指定文件输出的位置 FileOutputStream out = new FileOutputStream("C:/Users/Administrator/Desktop/contact.xml"); //C:\Users\Administrator\Desktop\ 改写成C:/Users/Administrator/Desktop/contact.xml /** * 1.指定写出的格式 */ OutputFormat format = OutputFormat.createCompactFormat(); //紧凑的格式.去除空格换行.项目上线的时候 //OutputFormat format = OutputFormat.createPrettyPrint(); //漂亮的格式.有空格和换行.开发调试的时候 /** * 2.指定生成的xml文档的编码 * 同时影响了xml文档保存时的编码 和 xml文档声明的encoding的编码(xml解析时的编码) * 结论: 使用该方法生成的xml文档避免中文乱码问题。 */ format.setEncoding("utf-8"); //1.创建写出对象 XMLWriter writer = new XMLWriter(out,format); //2.写出对象 writer.write(doc); //3.关闭流 writer.close(); }
5.2 修改xml文档的API
增加:
DocumentHelper.createDocument() 增加文档
addElement("名称") 增加标签
addAttribute("名称",“值”) 增加属性
//增加:文档,标签 ,属性 public static void main(String[] args) throws Exception { //1.创建文档 Document doc = DocumentHelper.createDocument(); //2.增加标签 Element rootElem = doc.addElement("contactList"); Element contactElem = rootElem.addElement("contact"); contactElem.addElement("name"); //3.增加属性 contactElem.addAttribute("id", "003"); contactElem.addAttribute("name", "demo7"); //把修改后的Document对象写出到xml文档中 FileOutputStream out = new FileOutputStream("C:/Users/Administrator/Desktop/contact.xml"); OutputFormat format = OutputFormat.createPrettyPrint(); format.setEncoding("utf-8"); XMLWriter writer = new XMLWriter(out,format); writer.write(doc); writer.close(); }
修改:
Attribute.setValue("值") 修改属性值
Element.addAtribute("同名的属性名","值") 修改同名的属性值
Element.setText("内容") 修改文本内容
//修改:属性值,文本 public static void main(String[] args) throws Exception { Document doc = new SAXReader().read(new File("C:/Users/Administrator/Desktop/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 contactElem1 = doc.getRootElement().element("contact"); //1.2 通过增加同名属性的方法,修改属性值 contactElem.addAttribute("id", "004"); //修改文本 1.得到标签对象 2.修改文本 Element nameElem = doc.getRootElement().element("contact").element("name"); nameElem.setText("demo7"); FileOutputStream out = new FileOutputStream("C:/Users/Administrator/Desktop/test/contact.xml"); OutputFormat format = OutputFormat.createPrettyPrint(); format.setEncoding("utf-8"); XMLWriter writer = new XMLWriter(out,format); writer.write(doc); writer.close(); }
删除
Element.detach(); 删除标签
Attribute.detach(); 删除属性
//删除:标签,属性 public static void main(String[] args) throws Exception { Document doc = new SAXReader().read(new File("C:/Users/Administrator/Desktop/contact.xml")); //1.删除标签 1.1 得到标签对象 1.2 删除标签对象 Element ageElem = doc.getRootElement().element("contact").element("age"); //1.2 删除标签对象 ageElem.detach(); //ageElem.getParent().remove(ageElem); //2.删除属性 2.1得到属性对象 2.2 删除属性 //得到第二个contact标签 Element contactElem = (Element)doc.getRootElement().elements().get(1); //2.2 得到属性对象 Attribute idAttr = contactElem.attribute("id"); //2.3 删除属性 idAttr.detach(); FileOutputStream out = new FileOutputStream("C:/Users/Administrator/Desktop/test/contact.xml"); OutputFormat format = OutputFormat.createPrettyPrint(); format.setEncoding("utf-8"); XMLWriter writer = new XMLWriter(out,format); writer.write(doc); writer.close(); }
一个小练习
需求
* 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的学生
public static void main(String[] args) 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文件 save(doc); //修改id为2的学生姓名 //1.查询到id为2的学生 Document doc1 = new SAXReader().read(new File("C:/Users/Administrator/Desktop/test/student.xml")); //1.1 找到所有的Student标签 Iterator<Element> it = doc1.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; } } save(doc1); //删除id为2的学生 Document doc2 = new SAXReader().read(new File("C:/Users/Administrator/Desktop/test/student.xml")); //1.1 找到所有的Student标签 Iterator<Element> it2 = doc2.getRootElement().elementIterator("Student"); while(it2.hasNext()){ Element stuElem = it2.next(); //1.2 查询id为id的学生标签 if(stuElem.attributeValue("id").equals("2")){ //1.3 删除该学生标签 stuElem.detach(); break; } } save(doc2); } private static void save(Document doc) throws Exception{ //3.1 输出位置 FileOutputStream out = new FileOutputStream("C:/Users/Administrator/Desktop/test/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技术
3.1 引入
问题:当使用dom4j查询比较深的层次结构的节点(标签,属性,文本),比较麻烦!!!
3.2 xPath作用
主要是用于快速获取所需的节点对象。
public static void main(String[] args) 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文件 save(doc); //删除除id值为2的学生标签 使用xpath Document doc1 = new SAXReader().read(new File("C:/Users/Administrator/Desktop/test/student.xml")); Element stuElem = (Element)doc1.selectSingleNode("//Student[@id='2']"); stuElem.detach(); save(doc1); } private static void save(Document doc) throws Exception{ //3.1 输出位置 FileOutputStream out = new FileOutputStream("C:/Users/Administrator/Desktop/test/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.3 在dom4j中如何使用xPath技术
1)导入xPath支持jar包 。 jaxen-1.1-beta-6.jar
2)使用xpath方法
List<Node> selectNodes("xpath表达式"); 查询多个节点对象
Node selectSingleNode("xpath表达式"); 查询一个节点对象
3.4 xPath语法
/ 绝对路径 表示从xml的根位置开始或子元素(一个层次结构)
// 相对路径 表示不分任何层次结构的选择元素。
* 通配符 表示匹配所有元素
[] 条件 表示选择什么条件下的元素
@ 属性 表示选择属性节点
and 关系 表示条件的与关系(等价于&&)
text() 文本 表示选择文本内容
//学习xPath表达式语法 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.getName()); } }
模拟用户登录效果
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文档
public static void main(String[] args) throws Exception { Document doc = new SAXReader().read(new File("./src/personList.html")); 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解析
4.1回顾DOM解析
DOM解析原理:一次性把xml文档加载进内存,然后在内存中构建Document树。
对内存要求比较要。
缺点: 不适合读取大容量的xml文件,容易导致内存溢出。
SAX解析原理: 加载一点,读取一点,处理一点。对内存要求比较低。
4.2 SAX解析工具
SAX解析工具- Sun公司提供的。内置在jdk中。org.xml.sax.*
核心的API:
SAXParser类: 用于读取和解析xml文件对象
parse(File f, DefaultHandler dh)方法: 解析xml文件
参数一: File:表示 读取的xml文件。
参数二: DefaultHandler: SAX事件处理程序。使用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) : 读到文本内容时调用
第一个例子
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()); }
MyDefaultHandler
public class MyDefaultHandler extends DefaultHandler{ //开始文档时调用 @Override public void startDocument() throws SAXException { super.startDocument(); System.out.println("MyDefaultHandler.startDocument()"); } //开始标签时调用 @Override public void endElement(String uri, String localName, String qName) throws SAXException { super.endElement(uri, localName, qName); System.out.println("MyDefaultHandler.startElement()-->"+qName); } //结束标签时调用 @Override public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { super.startElement(uri, localName, qName, attributes); System.out.println("MyDefaultHandler.endElement()-->"+qName); } //读到文本内容的时调用 //ch: 表示当前读完的所有文本内容 //start: 表示当前文本内容的开始位置 //length: 表示当前文本内容的长度 @Override public void characters(char[] ch, int start, int length) throws SAXException { super.characters(ch, start, length); String content = new String(ch,start,length); System.out.println("MyDefaultHandler.characters()-->"+content); } @Override public void endDocument() throws SAXException { super.endDocument(); System.out.println("MyDefaultHandler.endDocument()"); } }
第二个例子
读取contact.xml文件,完整输出文档内容
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); }
MyDefaultHandler2
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 { super.startElement(uri, localName, qName, attributes); 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 { super.characters(ch, start, length); //得到当前读取的文本 String content = new String(ch,start,length); sb.append(content); } //结束标签 @Override public void endElement(String uri, String localName, String qName) throws SAXException { super.endElement(uri, localName, qName); sb.append("</"+qName+">"); } }
最后一个例子
使用sax解析把 xml文档封装成对象
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); } }
MyDefaultHandler3
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 startDocument() throws SAXException { super.startDocument(); System.out.println("MyDefaultHandler.startDocument()"); } //开始标签时调用 @Override public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { super.startElement(uri, localName, qName, attributes); curTag = qName; //读取到contact的开始标签创建Contact对象 if("contact".equals(qName)){ contact = new Contact(); //设置id值 contact.setId(attributes.getValue("id")); } } //读到文本内容的时调用 //ch: 表示当前读完的所有文本内容 //start: 表示当前文本内容的开始位置 //length: 表示当前文本内容的长度 @Override public void characters(char[] ch, int start, int length) throws SAXException { super.characters(ch, start, length); //当前文本内容 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 { super.endElement(uri, localName, qName); //设置空时为了避免空格换行设置到对象的属性中 curTag = null; //读到contact的结束标签放入List中 if("contact".equals(qName)){ list.add(contact); } } @Override public void endDocument() throws SAXException { super.endDocument(); System.out.println("MyDefaultHandler.endDocument()"); } }
DOM解析 vs SAX解析
原理: 一次性加载xml文档,不适合大容量的文件读取
DOM解析可以任意进行增删改查
DOM解析任意读取任何位置的数据,甚至往回读
DOM解析面向对象的编程方法(Node,Element,Attribute),Java开发者编码比较简单。
SAX解析
原理: 加载一点,读取一点,处理一点。适合大容量文件的读取
SAX解析只能读取
SAX解析只能从上往下,按顺序读取,不能往回读
SAX解析基于事件的编程方法。java开发编码相对复杂。
以上所有代码见Giihub https://github.com/huanyi0723/Xml/