本章节我们要学习XML三种解析方式:
1、JAXP DOM 解析
2、JAXP SAX 解析
3、XML PULL 进行 STAX 解析
XML 技术主要企业应用
1、存储和传输数据
2、作为框架的配置文件
使用xml 存储和传输数据
1、通过程序生成xml
2、读取xml 中数据 ---- xml 解析
什么是DOM和SAX ?
DOM Document Object Model ----- 文档对象模型
DOM思想: 将整个xml 加载内存中,形成文档对象,所有对xml操作都对内存中文档对象进行
DOM 是官方xml解析标准
* 所有开发语言都支持的
Java、JavaScript 都支持DOM
SAX Simple API for XML ----- XML 简单 API
程序员为什么发明sax解析方式?? 当xml 文档非常大,不可能将xml所有数据加载到内存
SAX 思想:一边解析 ,一边处理,一边释放内存资源 ---- 不允许在内存中保留大规模xml 数据
StAX The Stream API for XML ----- XML 流 API
STAX 是一种 拉模式 xml 解析方式,SAX 是一种 推模式 XML 解析方式
推push模式:由服务器为主导,向客户端主动发送数据
拉pull模式: 由客户端为主导,主动向服务器申请数据
程序员在实际开发中,使用已经开发好工具包 ----- JAXP 、DOM4j 、XML PULL
解析方式 与 解析开发包 关系?
解析方式是解析xml 思想,没有具体代码,解析开发包是解析xml思想具体代码实现
JAXP 是sun官方推出实现技术 同时支持 DOM SAX STAX
DOM4j 是开源社区开源框架 支持 DOM 解析方式
XML PULL Android 移动设备内置xml 解析技术 支持 STAX 解析方式
当SAX和STAX 读取xml数据时,如果读取到内存数据不释放 ----- 内存中将存在整个xml文档数据
(类似DOM 支持修改和回写)。
DOM、SAX、STAX 在实际开发中选择?
在javaee日常开发中 ---- 优先使用DOM (编程简单)
当xml 文档数据非常多,不可能使用DOM ---造成内存溢出 ------ 优先使用STAX
移动开发 使用 STAX ---- Android XML PULL
JAXP 开发 进行 xml解析 :
javax.xml.parsers 存放 DOM 和 SAX 解析器
javax.xml.stream 存放 STAX 解析相关类
org.w3c.dom 存放DOM解析时 数据节点类
org.xml.sax 存放SAX解析相关工具类
DOM 解析快速入门
1、创建 xml 文档 books.xml
在企业实际开发中,为了简化xml 生成和解析 ---- xml 数据文件通常不使用约束的
2、使用DOM解析xml
将整个xml文档加载到内存中 : 工厂 --- 解析器 --- 解析加载
3、Document通过 getElementsByTagName 获得 节点集合 NodeList
通过 NodeList 提供 getLength 和 item 遍历 节点集合
遍历ArrayList
for (int i=0;i<arraylist.size();i++){
arraylist.get(i);
}
遍历NodeList
for (int i=0;i<nodelist.getLength();i++){
nodelist.item(i); ----- 将遍历每个节点转换子接口类型
}
什么是 Node? 对于xml 来说,xml所有数据都是node节点包括:
(元素节点、属性节点、文本节点、注释节点、CDATA节点、文档节点)。
Element Attr Text Comment CDATASection Document ----- 都是 Node 子接口
node有三个通用API :
getNodeName():返回节点的名称
getNodeType():返回节点的类型
getNodeValue():返回节点的值 ---- 所有元素节点value都是 null
------------------------------------------------------------------------------------
DOM 编程思路小结
1、装载XML文档 ---- Document
2、Document 获得指定元素 ----- getElementsByTagName (返回 NodeList)
3、遍历NodeList 获得 每个 Node
4、将每个Node 强制转换 Element
5、通过元素节点API 操作属性和文本内容
getAttribute 获得属性值
getTextContent 获得元素内部文本内容
<?xml version="1.0" encoding="UTF-8"?> <books> <book> <name>java编程思想</name> <price>88</price> </book> <book> <name>java编程高手</name> <price>99</price> </book> </books>
package com.shellway.javase; import java.io.IOException; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import org.junit.Test; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.NodeList; import org.xml.sax.SAXException; public class demo1 { @Test public void getElement() throws ParserConfigurationException, SAXException, IOException{ DocumentBuilderFactory douBuilderFactory = DocumentBuilderFactory.newInstance(); DocumentBuilder documentBuilder = douBuilderFactory.newDocumentBuilder(); Document document = documentBuilder.parse("xml/books2.xml"); //通过父节点获得相应书籍《java编程思想》图书的价格 NodeList nodeList = document.getElementsByTagName("book"); for (int i = 0; i < nodeList.getLength(); i++) { Element element = (Element) nodeList.item(i); Element element1 = (Element) element.getChildNodes().item(1); if (element1.getTextContent().equals("java编程思想")) { System.out.println(element.getChildNodes().item(3).getTextContent()); } } } @Test public void getElement2() throws ParserConfigurationException, SAXException, IOException{ DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance(); DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder(); Document document = documentBuilder.parse("xml/books2.xml"); //通过兄弟节点获得相应书籍《java编程高手》的价格 NodeList nodeList = document.getElementsByTagName("name"); for (int i = 0; i < nodeList.getLength(); i++) { Element element = (Element) nodeList.item(i); if (element.getTextContent().equals("java编程高手")) { String str = element.getNextSibling().getNextSibling().getTextContent(); System.out.println(str); } } } }
通过id来找到对应的元素节点,是通过id的值。前提还必须要求本此元素节点所在的xml文档有约束。
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE books [ <!ELEMENT books (book+) > <!ELEMENT book (name,price)> <!ELEMENT name (#PCDATA)> <!ELEMENT price (#PCDATA)> <!ATTLIST name id ID #REQUIRED> ]> <books> <book> <name id="b001">java编程思想</name> <price>88</price> </book> <book> <name id ="b002">java编程高手</name> <price>99</price> </book> </books>
@Test
public void getElement3() throws Exception {
//通过id借助它的值找到对应的元素节点
DocumentBuilderFactory documentBuilderFactory =
DocumentBuilderFactory.newInstance();
DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
Document document = documentBuilder.parse("xml/books2.xml");
Element element = document.getElementById("b001");
System.out.println(element.getTextContent());
System.out.println(element.getNextSibling().getNextSibling().getTextContent());
}
先用全局查找锁定范围,再用相对关系查找 得到需要数据
getElementById 方法 必须用于带有约束 xml文档中 !!!!!!!
所以开发语言默认支持DTD,当使用Schema时,单独编程导入schema !
XML DOM 增加 、修改 和 删除操作 ------ 操作 内存中文档对象
XML的回写
XML元素添加 : 1、创建节点元素 2、将节点元素加入指定位置
XML元素修改 : 查询到指定元素 1、修改属性 setAttribute
2、修改元素文本内容 setTextContent
XML元素删除 :删除节点.getParentNode().removeChild(删除节点)
<?xml version="1.0" encoding="UTF-8" standalone="no"?><books> <book> <name id="b001">java编程思想</name> <price>88</price> </book> <book> <name id="b002">java编程高手</name> <price>100</price> </book> <book> <name id="b002">编程高手秘笈</name> <price>120.0</price> </book> </books>
package com.shellway.javase; import java.io.File; import java.io.IOException; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerFactory; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; import org.junit.Test; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; public class demo2 { @Test public void testAddForDom() throws Exception{ //加载XML文档到内存中:创建工厂---加载器---加载文档 DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance(); DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder(); Document document = documentBuilder.parse("xml/books2.xml"); //获得根节点 Element root = document.getDocumentElement(); //创建一个新节点 Element user = document.createElement("user"); root.appendChild(user); //设置name的内容,并且添加为元素user的子节点 Element name = document.createElement("name"); name.setTextContent("张三"); user.appendChild(name); //为name添加一个属性 name.setAttribute("id", "b003"); //回写内容到XML中 TransformerFactory transformerFactory = TransformerFactory.newInstance(); Transformer transformer = transformerFactory.newTransformer(); DOMSource domSourse = new DOMSource(document); StreamResult stream = new StreamResult("xml/books2_bak.xml"); transformer.transform(domSourse,stream ); } @Test public void testUpdateForDom() throws Exception{ DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance(); DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder(); Document document = documentBuilder.parse("xml/books2.xml"); NodeList nodeList = document.getElementsByTagName("name"); for (int i = 0; i < nodeList.getLength(); i++) { Element name = (Element) nodeList.item(i); if (name.getTextContent().equals("java编程高手")) { Element priceN = (Element) name.getNextSibling().getNextSibling(); Double price = Double.parseDouble(priceN.getTextContent()); price = price * 1.2; priceN.setTextContent(price+""); } } //回写到xml TransformerFactory transformerFactory = TransformerFactory.newInstance(); Transformer transformer = transformerFactory.newTransformer(); DOMSource domSource = new DOMSource(document); StreamResult streamResult = new StreamResult(new File("xml/books2.xml")); transformer.transform(domSource, streamResult); } @Test public void testDeleteForDom() throws Exception{ DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance(); DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder(); Document document = documentBuilder.parse("xml/books2.xml"); NodeList nodeList = document.getElementsByTagName("name"); for (int i = 0; i < nodeList.getLength(); i++) { Element name = (Element) nodeList.item(i); //删除包含有java的书籍 if (name.getTextContent().contains("java")) { //得到此节点的父节点,因为删除必须通过父节点才能删除自己 Element element = (Element) name.getParentNode(); element.getParentNode().removeChild(element); //注意:当删除第一个节点后,第二个节点会变成第一个节点,所以要i-- i--; } } //回写到xml TransformerFactory transformerFactory = TransformerFactory.newInstance(); Transformer transformer = transformerFactory.newTransformer(); DOMSource domSource = new DOMSource(document); StreamResult streamResult = new StreamResult(new File("xml/books2.xml")); transformer.transform(domSource, streamResult); } }
--------------------------------------------------------------------------
SAX 和 STAX 都是 基于事件驱动 ----- SAX推模式 STAX拉模式
SAX常用事件
startDocument() ---- 文档开始事件
startElemen() ---- 元素开始事件
characters() ---- 文本元素事件
endElement() ---- 元素结束事件
endDocument() ----- 文档结束事件
为什么说SAX是推模式解析? 解析器控制xml文件解析,由解析器调用相应事件方法
在startElemen() endElement() 获得开始和结束元素名称
在characters() 获得读取到文本内容
在startElemen() 读取属性值
JAXP SAX的原理和使用练习:
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <books> <book> <name id="b001">java编程思想</name> <price>88</price> </book> <book> <name id="b002">java编程高手</name> <price>100</price> </book> <book> <name id="b003">编程高手秘笈</name> <price>120.0</price> </book> </books>
package com.shellway.javase; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; import org.junit.Test; import org.xml.sax.Attributes; import org.xml.sax.SAXException; import org.xml.sax.helpers.DefaultHandler; public class demo3 { @Test public void testSax() throws Exception{ SAXParserFactory saxParserFactory = SAXParserFactory.newInstance(); SAXParser saxParser = saxParserFactory.newSAXParser(); myHandler handler = new myHandler(); saxParser.parse("xml/books2.xml",handler); } } class myHandler extends DefaultHandler { @Override public void startDocument() throws SAXException { System.out.println("startDocument..."); } @Override public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { System.out.println("startElement:"+qName); if (qName.equals("name")) { String str = attributes.getValue("id"); System.out.println(str+"-------"); } } @Override public void characters(char[] ch, int start, int length){ String str = new String(ch,start,length); System.out.println("characters:"+str); } @Override public void endElement(String uri, String localName, String qName){ System.out.println("endElement:"+qName); } @Override public void endDocument() throws SAXException { System.out.println("endDocument..."); } }
STAX 拉模式xml 解析方式 ----- 客户端程序,自己控制xml事件,主动调用相应事件方法
当使用XML PULL 如果使用Android系统,系统内置无需下载任何开发包,如果想JavaSE JavaEE
使用pull 解析技术 下载单独pull 开发工具包。
xpp3 ----- XML Pull Parser 3 是pull API 代码实现
使用pull 解析器
1、去网站上 下载 pull 解析器实现 xpp3 (Android 内置)
2、将 xpp3-1.1.3.4.C.jar 导入 java工程
导入jar包 位于 当前工程内部 , 在工程内新建 lib ,将jar复制过来 , 将pull 解析器 jar 添加build path
jar 包就是.class文件 集合压缩包 (采用zip格式压缩)
Pull解析器 使用 stax 解析方式 ---- 拉模式解析
Pull采用将xml文档传递 解析器,手动通过next触发文档解析事件,在客户端代码中获取当前事件 ,从而调用相应事件处理方法
3、创建pull 解析器
4、将xml 文档内容传递 pull 解析器
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <books> <book> <name id="b001">java编程思想</name> <price>88</price> </book> <book> <name id="b002">java编程高手</name> <price>100</price> </book> <book> <name id="b003">编程高手秘笈</name> <price>120.0</price> </book> </books>
import java.io.FileInputStream; import org.junit.Test; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; import org.xmlpull.v1.XmlPullParserFactory; public class demo4 { @Test public void testPull2() throws Exception{ XmlPullParserFactory xmlPullParserFactory = XmlPullParserFactory.newInstance(); XmlPullParser xmlPullParser = xmlPullParserFactory.newPullParser(); xmlPullParser.setInput(new FileInputStream("xml/books2.xml"), "utf-8"); int event; boolean flag = false; while((event = xmlPullParser.getEventType())!=XmlPullParser.END_DOCUMENT){ if(event==XmlPullParser.START_TAG&&xmlPullParser.getName().equals("name")){ String name = xmlPullParser.nextText(); if(name.equals("java编程高手")){ flag = true; // xmlPullParser.next(); // xmlPullParser.next(); // System.out.println(xmlPullParser.nextText()); } } if(event == xmlPullParser.START_TAG&&xmlPullParser.getName().equals("price")&&flag){ System.out.println(xmlPullParser.nextText()); //flag = false;或者推出循环 break; } xmlPullParser.next(); } } @Test public void testPull() throws Exception{ XmlPullParserFactory xmlPullParserFactory = XmlPullParserFactory.newInstance(); XmlPullParser xmlPullParser = xmlPullParserFactory.newPullParser(); xmlPullParser.setInput(new FileInputStream("xml/books2.xml"), "utf-8"); int event; while((event = xmlPullParser.getEventType())!=XmlPullParser.END_DOCUMENT){ // if(event == XmlPullParser.START_TAG){ System.out.println(xmlPullParser.getEventType()); // } //处理下一个事件 event = xmlPullParser.next(); } } }
为什么 STAX 解析方式 效率 好于 SAX ?
1、SAX 无选择性的,所有事件都会处理 解析方式,Stax 由用户控制需要处理事件类型
2、在使用Stax进行数据解析时,随时终止解析
Pull 解析器 生成 xml 文档功能 ---- 通过 XmlSerializer 生成 xml 文档
解析xml : 文档开始、元素开始、文本元素、元素结束、文档结束
生成xml :生成文档声明(文档开始),元素开始、文本内容、元素结束 、文档结束
1、生成简单xml
2、通过对象数据生成xml
3、通过对象List数据生成xml
在程序中抽取两个方法 ----- 1. xml --- List对象 2. List对象生成xml
1 package com.shellway.javase; 2 3 import java.io.FileOutputStream; 4 import java.util.ArrayList; 5 import java.util.List; 6 import org.junit.Test; 7 import org.xmlpull.v1.XmlPullParserFactory; 8 import org.xmlpull.v1.XmlSerializer; 9 import com.shellway.domain.Company; 10 11 public class demo4 { 12 /** 13 * 按照多个对象生成XML文档 14 * @throws Exception 15 */ 16 @Test 17 public void demo3() throws Exception{ 18 List<Company> companies = new ArrayList<Company>(); 19 Company company = new Company(); 20 company.setName("shellway"); 21 company.setPnum(200); 22 company.setAddress("深圳西丽"); 23 Company company2 = new Company(); 24 company2.setName("Jerry"); 25 company2.setPnum(500); 26 company2.setAddress("深圳西丽"); 27 companies.add(company); 28 companies.add(company2); 29 30 XmlSerializer xmlSerializer = XmlPullParserFactory.newInstance().newSerializer(); 31 xmlSerializer.setOutput(new FileOutputStream("xml/company.xml"), "utf-8"); 32 xmlSerializer.startDocument("utf-8", true); 33 34 xmlSerializer.startTag(null, "companies"); 35 36 for (Company c : companies) { 37 xmlSerializer.startTag(null, "company"); 38 39 xmlSerializer.startTag(null, "name"); 40 xmlSerializer.text(c.getName()); 41 xmlSerializer.endTag(null, "name"); 42 43 xmlSerializer.startTag(null, "pnum"); 44 xmlSerializer.text(c.getPnum()+""); 45 xmlSerializer.endTag(null, "pnum"); 46 47 xmlSerializer.startTag(null, "address"); 48 xmlSerializer.text(c.getAddress()); 49 xmlSerializer.endTag(null, "address"); 50 51 xmlSerializer.endTag(null, "company"); 52 } 53 xmlSerializer.endTag(null, "companies"); 54 xmlSerializer.endDocument(); 55 } 56 57 /** 58 * 按照一个对象生成XML文档 59 * @throws Exception 60 */ 61 @Test 62 public void demo2() throws Exception{ 63 Company company = new Company(); 64 company.setName("shellway"); 65 company.setPnum(200); 66 company.setAddress("深圳西丽"); 67 68 XmlPullParserFactory xmlPullParserFactory = XmlPullParserFactory.newInstance(); 69 XmlSerializer xmlSerializer = xmlPullParserFactory.newSerializer(); 70 71 xmlSerializer.setOutput(new FileOutputStream("xml/company.xml"), "utf-8"); 72 xmlSerializer.startDocument("utf-8", true); 73 74 xmlSerializer.startTag(null, "company"); 75 76 xmlSerializer.startTag(null, "name"); 77 xmlSerializer.text(company.getName()); 78 xmlSerializer.endTag(null, "name"); 79 80 xmlSerializer.startTag(null, "pnum"); 81 xmlSerializer.text(company.getPnum()+""); 82 xmlSerializer.endTag(null, "pnum"); 83 84 xmlSerializer.startTag(null, "address"); 85 xmlSerializer.text(company.getAddress()); 86 xmlSerializer.endTag(null, "address"); 87 88 xmlSerializer.endTag(null, "company"); 89 xmlSerializer.endDocument(); 90 } 91 92 /** 93 * 生成简单的XML文档 94 * @throws Exception 95 */ 96 @Test 97 public void testXmlSerializer() throws Exception{ 98 XmlPullParserFactory xmlPullParserFactory = XmlPullParserFactory.newInstance(); 99 XmlSerializer xmlSerializer = xmlPullParserFactory.newSerializer(); 100 101 //设置序列化输出文档 102 //第二个参数是保存的编码 103 xmlSerializer.setOutput(new FileOutputStream("xml/company.xml"), "utf-8"); 104 //开始文档 105 //第二个参数为查看的编码,第二个参数为文档是否是alone 106 xmlSerializer.startDocument("utf-8", true); 107 //开始元素 108 xmlSerializer.startTag(null, "name");//第一个参数为名称空间,若没有则 ""或者null 109 //文本内容 110 xmlSerializer.text("我们的公司"); 111 //结束元素 112 xmlSerializer.endTag(null, "name"); 113 //结束文档 114 xmlSerializer.endDocument(); 115 } 116 }
对内存中List进行CURD操作
1 @Test 2 public void demo5() throws Exception{ 3 List<Company> list = new ArrayList<Company>(); 4 Company company = null; 5 XmlPullParserFactory xmlPullParserFactory = XmlPullParserFactory.newInstance(); 6 XmlPullParser xmlPullParser = xmlPullParserFactory.newPullParser(); 7 8 xmlPullParser.setInput(new FileInputStream("xml/company.xml"), "utf-8"); 9 int event; 10 while((event=xmlPullParser.getEventType())!=XmlPullParser.END_DOCUMENT){ 11 12 if(event==XmlPullParser.START_TAG&&xmlPullParser.getName().equals("name")){ 13 company = new Company();//注意这句不能放在外面,因为有空文本,结果将是空对象 14 company.setName(xmlPullParser.nextText()); 15 } 16 if(event==XmlPullParser.START_TAG&&xmlPullParser.getName().equals("pnum")){ 17 company.setPnum(Integer.parseInt(xmlPullParser.nextText())); 18 } 19 if(event==XmlPullParser.START_TAG&&xmlPullParser.getName().equals("address")){ 20 company.setAddress(xmlPullParser.nextText()); 21 } 22 if (event==XmlPullParser.END_TAG&&xmlPullParser.getName().equals("company")) { 23 list.add(company); 24 } 25 xmlPullParser.next(); 26 } 27 for (Company c : list) { 28 System.out.println(c.getName()); 29 System.out.println(c.getPnum()); 30 System.out.println(c.getAddress()); 31 System.out.println("---------------------------------------"); 32 } 33 34 }
1 package com.shellway.domain; 2 3 import java.util.List; 4 import org.junit.Test; 5 6 public class XmlCURD { 7 //删除数据 8 @Test 9 public void testDeleteFromXml() throws Exception{ 10 List<Company> companies = PullUtils.getDataForXml("xml/company_bak.xml"); 11 for (Company c : companies) { 12 if(c.getName().equals("Jerry")){ 13 companies.remove(c); 14 //因为forech不允许改变长度,所以删了要一个break,且只能删除一个 15 break; 16 } 17 } 18 //回写 19 PullUtils.setOutputForXml(companies, "xml/company_bak.xml"); 20 } 21 22 //修改:要求名为shellway的公司人数增加到200% 23 @Test 24 public void testModifyFromXml() throws Exception{ 25 List<Company> companies = PullUtils.getDataForXml("xml/company.xml"); 26 for (Company c : companies) { 27 if(c.getName().equals("shellway")){ 28 c.setPnum(c.getPnum()*2); 29 } 30 } 31 //回写 32 PullUtils.setOutputForXml(companies, "xml/company_bak.xml"); 33 } 34 35 //增加数据 36 @Test 37 public void testAddFromXml() throws Exception{ 38 //获取XML中的数据在内存中存放到List 39 List<Company> companies = PullUtils.getDataForXml("xml/company.xml"); 40 Company company = new Company(); 41 company.setName("kkk"); 42 company.setPnum(1000); 43 company.setAddress("南山区"); 44 companies.add(company); 45 //回写 46 PullUtils.setOutputForXml(companies, "xml/company_bak.xml"); 47 } 48 //读取数据 49 @Test 50 public void testReadFromXml() throws Exception{ 51 List<Company> companies = PullUtils.getDataForXml("xml/company.xml"); 52 for (Company company : companies) { 53 System.out.println(company.getName()); 54 System.out.println(company.getPnum()); 55 System.out.println(company.getAddress()); 56 System.out.println("--------------------------"); 57 } 58 } 59 60 @Test 61 public void testPull() throws Exception{ 62 List<Company> companies = PullUtils.getDataForXml("xml/company.xml"); 63 PullUtils.setOutputForXml(companies, "xml/company_bak.xml"); 64 } 65 }
作业:
1、整理 DOM 、SAX 、STAX 原理和区别
2、编写商品xml文件 --- 通过JAXP DOM 完成CURD操作
3、编写SAX运行案例 ----- 了解
4、编写商品XML文件 --- 通过Pull解析器完成 CURD操作 ---- 重点 xml2List list2xml 两个方法