




已阅读5页,还剩11页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
第三天 XML数据解析(重点)1XML数据解析简介1XML解析数据的原理1JAXP解析技术2DOM解析2SAX解析6DOM4J解析技术10XPath13DOM4J+XPath14总结15练习15第三天 XML数据解析(重点)在很多的项目中我们都需要将XML中描述好的数据通过程序拿出来加以操作。如:JavaEE和Androdi。那么其实在XML语言的学习中最重要的两个技术是:XML描述数据、XML数据解析。因此在这一章节我们重点给大家讲解XML的数据解析技术。XML数据解析简介由于从XML中解析数据一个比较普遍的操作,那么SUN API中一定定义好了操作XML的相关类和方法。SUN公司使用JAXP进行XML的数据解析。SUN提供的解析技术:JAXP : Java Api for Xml Processing 解析XML的API架构,JAXP中主要包含DOM解析和SAX解析,主要设计的包如下:javax.xml.parsers 、org.w3c.dom、org.xml.sax因此下面的学习我们将围绕以上三个包进行学习。开源解析技术:DOM4J:主要结合DOM和SAX解析的优势构建了开源的DOM4J解析技术。XML解析数据的原理在实际的开发中没有开发者直接写解析器进行XML文件的解析,一般开发者都是通过通过解析器提供者提供的API获取解析器进而快速的操作XML数据。从上图中发现解析XML数据第一步应该先获取解析器对象,第二步是通过获取到的解析器对称进行数据的获取。JAXP解析技术SUN提供了两种不同的解析XML数据的方式,一种是DOM解析。另一种是SAX解析。DOM解析原理: 在内存中构XML文件的DOM树。SAX解析原理: 使用事件机制和方法回调的技术实现。DOM解析DOM解析主要会用到java中的以下包:javax.xml.parsers 主要是获取DOM解析器主要的类如下:DocumentBuilderFactory DOM解析器的工厂类。DocumentBuilder DOM解析器org.w3c.dom 提供DOM树支持主要的接口如下:-| Node 描述的是所有的XML元素的共性-| Attr 描述的是所有的XML中的属性元素的共性-| Document 描述整个XML文档-| Element 描述XML中的元素-| Text 描述的是Element或Attr中包含的文本内容体验:编写如下的users.xml文件在项目根路径 jack编写一个Test.java文件如下public static void main(String args) throws Exception DocumentBuilderFactory fac = DocumentBuilderFactory.newInstance();DocumentBuilder parser = fac.newDocumentBuilder();Document doc = parser.parse(new File(users.xml);String str = doc.getElementsByTagName(users).item(0).getTextContent();System.out.println(str);通过体验,发现解析XML其实十分简单,因此我们必须学会。u 开发前奏1、获取解析器/ 1. 获取DOM解析器对象public static DocumentBuilder getParser()throws Exception / 1.1 创建解析器的工厂类对象 DocumentBuilderFactory fac = DocumentBuilderFactory.newInstance(); / 1.2获取解析器 DocumentBuilder parser = fac.newDocumentBuilder(); / 1.3返回解析器对象 return parser;2、获取解析好的DOM树/ 2. 使用解析器进行XML的解析,返回解析好的DOM树public static Document getDOM(File xml)throws Exception/ 2.1 获取解析器DocumentBuilder parser = getParser();/ 2.2使用解析器解析指定的xml文件Document dom = parser.parse(xml);/ 2.3返回解析好的DOM树return dom;3、将dom转换为xml / 3. 将内存中的DOM树持久化写入到XML文件public static void writeDOM2XML( Document dom, File xml )throws Exception / 3.1 创建转换器工厂类对象 TransformerFactory fac = TransformerFactory.newInstance(); / 3.2创建转换器对象 Transformer trans = fac.newTransformer(); / 3.3转换 trans.transform(new DOMSource(dom), new StreamResult( new FileOutputStream(xml) );u 查看元素获取根节点的几种不同的方式public static void getRoot(File xml)throws Exception / 3.1 获取DOM树 Document dom = getDOM(xml); / 3.2从DOM中获取根节点 Node root = dom.getFirstChild(); root = dom.getLastChild(); root = dom.getElementsByTagName(linkmans).item(0); / 3.3获取根元素的所有孩子节点 NodeList list = dom.getChildNodes(); System.out.println(list.getLength(); System.out.println(list.item(0).getNodeName(); / 3.4获取到更元素的名称 System.out.println( root.getNodeName() ); 查看非根元素public static void getElement(File xml)throws Exception / 4.1 获取DOM树 Document dom = getDOM(xml); / 4.2从DOM中获取第一个linkman Node linkman = dom.getElementsByTagName(linkman).item(0); / 4.3获取第一个linkman元素的所有孩子 NodeList list = linkman.getChildNodes(); for (int i = 0; i list.getLength(); i+) System.out.println(list.item(i).getNodeName(); / 4.4 获取第一个linkman的邮箱 System.out.println( linkman.getLastChild().getTextContent() ); / 4.5 使用孩子集合节点获取第一个linkman的tel System.out.println( list.item(1).getTextContent() ); u 增加元素分析:1. 生孩子2. 认孩子public static void addElement(File xml)throws Exception / 5.1 获取DOM树 Document dom = getDOM(xml); / 5.2 创建新孩子节点 Element linkman2 = dom.createElement(linkman); / 5.3 认孩子 Node parent = dom.getLastChild(); parent.appendChild(linkman2); / 5.4 创建name节点 Element name = dom.createElement(name); name.setTextContent(lucy); linkman2.appendChild(name); / 5.5 转换存储 writeDOM2XML(dom,xml);u 修改元素public static void editElement(File xml)throws Exception / 7.1 获取DOM树 Document dom = getDOM(xml); / 7.2找元素Element name2 = (Element) dom.getElementsByTagName(name).item(1); / 7.3改文本值 name2.setTextContent(mary); / 7.4保存 writeDOM2XML(dom,xml);u 删除元素public static void removeElement(File xml)throws Exception / 8.1 获取DOM树 Document dom = getDOM(xml); / 8.2找父亲 Node parent = dom.getFirstChild(); / 8.3找儿子 Node child = dom.getElementsByTagName(linkman).item(1); / 8.4调用父亲的方法断绝关系 parent.removeChild(child); / 8.5保存 writeDOM2XML(dom,xml);u 属性的增删改查(了解)public static void attrOption(File xml)throws Exception / 9.1 获取DOM树 Document dom = getDOM(xml); / 9.2给xml中的所有的linkman添加id属性 NodeList linkmans = dom.getElementsByTagName(linkman); / 9.3循环遍历linkman for (int i = 0; i linkmans.getLength(); i+) Element linkman = (Element)linkmans.item(i); linkman.setAttribute(id, s00+(i+1); / 9.4获取属性System.out.println(Element)linkmans.item(1).getAttribute(id); / 9.5修改属性 (Element)linkmans.item(1).setAttribute(id, 007); / 9.6删除属性 (Element)linkmans.item(1).removeAttribute(id); / 9.7保存 writeDOM2XML(dom,xml);总结:使用DOM解析XML数据,那么解析器会将XML文件直接装载进内存形成DOM树,那么如果该XML文件过大10M,这就会导致内存的溢出或者操作比较慢。SAX解析SAX解析是为了解决DOM解析的缺点,因此SUN在设计的时候借鉴了GUI的事件处理机制。SAX的解析原理就是以事件进行驱动。主要依赖于以下两个包:javax.xml.parsersSAXParserFactory SAX解析器的工厂类SAXParser SAX解析器org.xml.saxDefaultHandler 默认的解析器类,按照开发者指定的方式解析XML该类固然可以直接创建对象,但是查看源码发现该类主要的方法都是空实现,因此我们需要重写该类的相关的方法。-| ContentHandler 主要处理XML中的内容DocumentHandler 文档处理器u 准备工作0、 创建以下users.xml文件1、 获取解析器/ 1. 创建解析对象public static SAXParser getParser()throws Exception / 1.1 创建解析器的工厂类对象 SAXParserFactory fac = SAXParserFactory.newInstance(); / 1.2创建解析器对象 SAXParser parser = fac.newSAXParser(); / 1.3返回解析器 return parser;2、 直接解析/ 2. 使用解析器解析XML数据public static void parseXML(File xml, DefaultHandler handler)throws Exception / 2.1 获取解析器对象 SAXParser parser = getParser(); / 2.2调用解析器的解析方法 parser.parse(xml, handler);u 基本解析public class MyBaseHandler extends DefaultHandler/ 该方法在文档被开始解析的时候自动执行Overridepublic void startDocument() throws SAXException super.startDocument();System.out.println(文档开始解析.);/ 一个元素开始的时候自动执行Overridepublic void startElement(String uri, String localName, String name,Attributes attributes) throws SAXException super.startElement(uri, localName, name, attributes);System.out.println(元素 +name+ 开始执行.);/ 遇到一个元素的文本内容时候自动执行Overridepublic void characters(char ch, int start, int length)throws SAXException super.characters(ch, start, length);System.out.println(文本内容是 : +new String(ch,start,length);/ 一个元素结束的时候自动执行Overridepublic void endElement(String uri, String localName, String name)throws SAXException super.endElement(uri, localName, name);System.out.println(元素 +name+ 结束执行.);/ 该方法在文档被解析结束的时候自动执行Overridepublic void endDocument() throws SAXException super.endDocument();System.out.println(文档结束解析.);练习:使用一个处理器获取以上的XML中的第二个linkman的名称?public class ExampleHandler extends DefaultHandler/ 定义变量private String tag_name = null; private int count = 0;/ 一个元素开始的时候自动执行Overridepublic void startElement(String uri, String localName, String name,Attributes attributes) throws SAXException this.tag_name = name; if(name.equals(name) this.count+;/ 遇到一个元素的文本内容时候自动执行Overridepublic void characters(char ch, int start, int length)throws SAXException if(name.equals(this.tag_name) & this.count = 2) System.out.println( new String(ch,start,length) );/ 一个元素结束的时候自动执行Overridepublic void endElement(String uri, String localName, String name)throws SAXException u 封装解析(重点)其实在实际的开发环境中我们希望将解析好的数据直接封装到一个对象,然后以集合的方式存储这些对象,进而便于其他应用直接操作这些集合数据。举例:public class LinkManHandler extends DefaultHandler / 定义属性private String tag_name;private LinkMan man = null;private List list = null;Overridepublic void startDocument() throws SAXException super.startDocument();/ 初始化容器对象list = new LinkedList();Overridepublic void startElement(String uri, String localName, String name,Attributes attributes) throws SAXException super.startElement(uri, localName, name, attributes);/ 保存标签名this.tag_name = name;/ 如果标签名是linkman则创建linkman对象if(linkman.equals(this.tag_name) man = new LinkMan();Overridepublic void characters(char ch, int start, int length)throws SAXException super.characters(ch, start, length);/ 取出name、tel和email的文本值if(name.equals(this.tag_name) man.setName(new String(ch,start,length);if(tel.equals(this.tag_name) man.setTel(new String(ch,start,length);if(email.equals(this.tag_name) man.setEmail(new String(ch,start,length);Overridepublic void endElement(String uri, String localName, String name)throws SAXException super.endElement(uri, localName, name); / 释放可变的Stringthis.tag_name = null;/ 将一个LinkMan对象添加到集合if(linkman.equals(name)list.add(man);/ 提供一个返回封装好的数据的方法public List getList()return list;Overridepublic void endDocument() throws SAXException super.endDocument();总结:SAX解析器技术明显使用了事件的回调(。?)技术,使得SAX在解析XML文件的时候效率要高于DOM的解析,但是不幸的是SAX解析器只能做元素的获取,至于其他的操作是不能进行的。因此在这里我们急需一个可高效操作XML的解析器。开源组织免费的开发了一个Dom4J框架技术,可以使得开发者快速并高效的解析XML数据。学习方法:SUN公司的标准、自己学习开源的框架技术。举例:加密。DOM4J解析技术DOM4J该解析技术结合了DOM和SAX的优点,因此在实际的项目开发中我们都是用该解析技术进行解析。dom4j is an Open Source XML framework for Java. dom4j allows you to read, write, navigate, create and modify XML documents. dom4j integrates with DOM and SAX and is seamlessly integrated with full XPath support. 下载: /projects/dom4j 使用前必须先进行jar包的引入。u 获取解析器/ 1. 获取DOM4J的解析器对象public static SAXReader getParser()SAXReader parser = new SAXReader();return parser;u 使用解析器进行解析/ 2. 使用解析器进行xml的解析public static Document parseXML(File xml)throws Exception/ 2.1 获取解析器SAXReader parser = getParser();/ 2.2 解析器调用姐解析的方法进行解析Document dom = parser.read(xml);return dom;u 获取根元素/ 3. 解析根元素public static void getRoot(File xml)throws Exception / 3.1 获取解析的Document对象Document dom = parseXML(xml);/ 3.2 获取根元素Element root = dom.getRootElement();/ 3.3 输出根元素的元素名System.out.println(root.getName();u 查询元素public static void getElement(File xml)throws Exception / 4.1 获取解析的Document对象Document dom = parseXML(xml);/ 4.2 获取根元素Element root = dom.getRootElement();/ 4.3 获取第三个linkman对象List list = root.elements(linkman);Element linkman3 = (Element) list.get(2);/ 4.4 获取第三个linkman对象的三个子元素list = linkman3.elements();/ 4.5 使用迭代器进行子元素的迭代Iterator it = list.iterator();while(it.hasNext()System.out.println(Element)it.next().getText();/ 简写方式it = linkman3.elementIterator();while(it.hasNext()System.out.println(Element)it.next().getText();u 添加元素public static void addElement(File xml)throws Exception / 5.1 获取解析的Document对象Document dom = parseXML(xml);/ 5.2 获取根元素Element root = dom.getRootElement();/ 5.3 创建linkman对象Element linkman = DocumentHelper.createElement(linkman);Element name = DocumentHelper.createElement(name);name.setText(焦宁波);/ 5.4 建立关系linkman.add(name);root.add(linkman);/ 5.5 保存writeDocumnet2XML(dom, xml);发现的问题是,写入中文会导致乱码的出现,因此我们需要给XMLWriter类在写的时候指定数据的编码方式。问题是该类的构造函数中只让传递字节流或字符流。在JavaSE中我们只有字节转换流才可以显示的指定编码和解码方式:InputStreamReader(InputStream in, Charset cs)OutputStreamWriter(OutputStream out, Charset cs)使用转换流解决乱码问题:/ 6. 将Document写入XMLpublic static void writeDocumnet2XML(Document dom, File xml)throws Exception/ 6.1 创建转换器对象XMLWriter writer = new XMLWriter(new OutputStreamWriter(new FileOutputStream(xml), UTF-8);/ 6.2 写入writer.write(dom);/ 6.3 刷新writer.close();u 修改元素/ 7. 修改元素public static void editElement(File xml)throws Exception / 7.1 获取解析的Document对象Document dom = parseXML(xml);/ 7.2 获取根元素Element root = dom.getRootElement();/ 7.3 修改第二个linkman的email节点值Element email = (Element)root.elements(linkman).get(1).element(email);email.setText();/ 7.4 保存writeDocumnet2XML(dom, xml);u 删除元素/ 8. 删除元素public static void removeElement(File xml)throws Exception / 8.1 获取解析的Document对象Document dom = parseXML(xml);/ 8.2 获取根元素Element root = dom.getRootElement();/ 8.3 删除最后一个linkmanElement linkman3 = (Element)root.elements(linkman).get(2);/ 8.4 断绝关系root.remove(linkman3);/ 8.5 保存writeDocumnet2XML(dom, xml);u 属性操作public static void attrOption(File xml)throws Exception / 9.1 获取解析的Document对象Document dom = parseXML(xml);/ 9.2 获取根元素Element root = dom.getRootElement();/ 9.3 获取第二个linkmanElement linkman2 = (Element)root.elements(linkman).get(1);/ 9.4 获取id属性String attr_id = linkman2.attributeValue(id);System.out.println(attr_id);/ 9.5 获取所有的属性List attr_list = linkman2.attributes();/ 9.6 迭代获取所有的属性Iterator it = attr_list.iterator();while(it.hasNext()Attribute attr = (Attribute)it.next();System.out.println(attr.getName()+=+attr.getData();/ 简化写法it = linkman2.attributeIterator();while(it.hasNext()Attribute attr = (Attribute)it.next();System.out.println(attr.getName()+=+attr.getData();/ 9.7 添加一个属性linkman2.add(DocumentHelper.createAttribute(linkman2, address, 广州);/ 9.8 保存writeDocumnet2XML(dom, xml);总结:如果在开发中使用DOM4J进行开发,那么每次都需要从根元素开始查找元素的位置。因此我们希望有一个类似操作系统路径的那么一个技术可以直接来描述我们XML中各个节点的关系,这样就方便DOM4J进行查找元素。即XPath。/ 发现问题public static void findQuestion(File xml)throws ExceptionString name = (Element)parseXML(xml).getRootElement().elements(linkman).get(0).element(linkman).element(name).getText();System.out.println(name);XPathXPath该路径语言是一个开源的用于表示元素路径的技术。主要结合不同的解析器进行使用。默认在DOM4J的jar包中已经带有了XPath的支持。u 操作XPath的几种方法selectNodes(String xpath) 主要获取多个元素selectSingleNode(String xpath) 主要获取单个元素valueOf(String xpath) 主要获取属性u 常见的XPath路径/AAA 从根路径下找直接的AAA元素/BBB在整个文档中找BBB/AAA/BBB1 从根路径开始找AAA下面的第一个BBBDOM4J+XPath使用DOM4J结合XPath的时候一定要额外的添加%DOM4J%/lib中jaxen-1.1-bet
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025年潍坊寒亭区(经济区)公开招聘中小学教师(11名)模拟试卷及答案详解(必刷)
- 2025江苏连云港市赣榆区教育局所属学校招聘新教师69人模拟试卷(含答案详解)
- 小学安全培训反思课件
- 2025年文化科技主题公园项目建议书
- 2025年福州市供电服务有限公司招聘65人模拟试卷及答案详解(易错题)
- 2025年氢氧化亚镍合作协议书
- 2025年金属制建筑装饰、散热器及其零件项目建议书
- 2025河南省水利厅厅属事业单位招聘47人模拟试卷完整答案详解
- 2025安徽芜湖市人才发展集团有限公司招聘2人考前自测高频考点模拟试题及参考答案详解1套
- 2025年光电子器件及激光器件项目建议书
- 烘焙类产品的特性及应用
- 第三章转录及转录调控
- 酿造车间绩效考核制度
- GB/T 7193-2008不饱和聚酯树脂试验方法
- GB/T 3810.3-2016陶瓷砖试验方法第3部分:吸水率、显气孔率、表观相对密度和容重的测定
- 部编本语文五年级上册第一单元教材解读
- 医院放疗科护理记录(模板)
- 应急管理行业解决方案及应用
- 7.4.2超几何分布 课件(共14张PPT)
- 高中地理 选必一 地质构造与地貌 PPT 课件
- 含硫化氢油气井井下作业推荐作法
评论
0/150
提交评论