文章目录

  • P1 XML文件
    • 1 XML文件概述
      • (1) 可扩展标记语言:XML
      • (2) XML文件的书写规则和语法要求
    • 2 创建一个XML文件
  • P2 解析给定的XML文件
    • 1 XML解析器和W3C
    • 2 从XML文件中解析数据
  • P3 设计一个XML文件解析工具
    • 1 静态块和本地块
    • 2 将XML解析过程工具化
    • 3 分析“静”与“动”
    • 4 将XML解析类做成抽象类,并解析XML文件
  • P4 将XMLParser和XMLNotFoundException做成工具
    • 1 生成jar工具包
    • 2 使用jar工具包
  • P5 jd-gui

P1 XML文件

之前设计的简单学生信息管理系统,除了交互性需要完善外,最重要的问题就是输入的数据无法保存,为了解决这个问题,这里引入XML文件来保存录入的数据

由于从程序中生成XML文件的过程较为复杂,此处只进行XML文件的创建和解析

1 XML文件概述

(1) 可扩展标记语言:XML

XML,即Extensible Markup Language,即可扩展标记语言,是一种允许用户对自己的标记语言进行定义的源语言,它非常适合万维网传输,提供统一的方法来描述和交换独立于应用程序或供应商的结构化语言

1998年,W3C发布了XML1.0规范,使用它来简化Internet的文档信息传输

XML是一种能描述层次结构的数据描述规范,使用它可以方便地描述和存储复杂数据

(2) XML文件的书写规则和语法要求

对于先前的学生信息,可以大概描述为:

学生1:学号:20181001姓名:张三性别:男出生日期:1999/10/1爱好:篮球足球羽毛球简介:热爱运动

有这个模板生成XML文件前,需要先了解XML文件的语法和规则:

1,标签:标签是为了能够表达有一定意义的数据的起,止标记,分为开始标签和结束标签,在起止标签之间的文本称为内容,基本格式如下:

<student><id>20181001</id>
</student>

标签大小写敏感,起止标签必须成对出现,且保持严格的顺序

2,标签属性:在开始标签中,可以通过 键 = "值"的形式定义一或多个属性,标签属性中的值必须为字符串,即需要双引号

<student id = "20181001" name = "张三" sex = "男"></student>

3,XML文件头:XML文件应当以一个文件头开始,如

<?xml version="1.0"?>

4,根标签:XML文件里的众多标签,都应该在一个根标签中书写,如

<students><student id = "20181001">张三</student>
</students>

5,注释:XML文件中的注释在解析XML时,将被忽略

XML中的注释:
<!-- 注释文字 -->

2 创建一个XML文件

通过eclipse自动生成XML文件框架来编写XML文件内容:
file->new->other->XML->XML File->next->选择目录并命名

通过上述的步骤,由eclipse生成了一个XML文件的框架:

点击source进行编辑,下面给出一个学生信息XML文件示例:

P2 解析给定的XML文件

通过编程,可以生成,修改,添加,删除XML文件及其内容,也可以从XML文件中取得数据

这里着重于后者,即XML文件的解析,就是通过程序从XML文件中取出特定的标签内容,或者属性值,并将这些值转换成对应的类对象

1 XML解析器和W3C

java提供了专门的XML解析器,且不止一个,这里使用W3C标准化了的DOM解析器

DOM(Document Object Model),即文件对象模型,是一种树型解析器,对于上述的XML文件,明显存在着一对多的关系,即树型结构

2 从XML文件中解析数据

先来试着从XML文件中取出学生的学号:

解析程序:

package GetFromXML;import java.io.IOException;
import java.io.InputStream;import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;//注意导包时使用w3c的包
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;public class Test {public static void main(String[] args) {try {/*** 用于找到xml文件并转换成document类的对象*/InputStream is = Class.class.getResourceAsStream("/student.xml");DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();DocumentBuilder db = dbf.newDocumentBuilder();Document document = db.parse(is);//从document中取出名为student的标签并存储到数组中NodeList studentList = document.getElementsByTagName("student");//此处长度为2,进行两次遍历取出两个学生的student标签for(int index = 0; index < studentList.getLength(); index++) {//使用数组的.item(下标)方法将取出的一行转换成Element类的对象Element student = (Element)studentList.item(index);//通过Element的getAttribute取出属性名为id的值存为String类型String id = student.getAttribute("id");System.out.println("id:" + id);}} catch (ParserConfigurationException e) {e.printStackTrace();} catch (SAXException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}}}

接下来解析学生标签中的所有属性:


上述的操作从student标签中取得了所有的属性,观察XML文件,发现在student标签下面还有两种标签hobby和introduce,这两种标签是包含在student标签内部的,作为student标签的一部分内容存在,为了解析它们,需要两个并列的循环嵌套在第一个循环中

解析程序

package GetFromXML;import java.io.IOException;
import java.io.InputStream;import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;public class Test2 {public static void main(String[] args) {try {InputStream is = Class.class.getResourceAsStream("/student.xml");DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();DocumentBuilder db = dbf.newDocumentBuilder();Document document = db.parse(is);NodeList studentList = document.getElementsByTagName("student");    for(int index = 0; index < studentList.getLength(); index++) {StringBuffer str = new StringBuffer(); /*** 解析student标签内的标签属性*/Element student = (Element)studentList.item(index);String id = student.getAttribute("id");str.append("id=").append(id);String name = student.getAttribute("name");str.append(" name=").append(name);String sex = student.getAttribute("sex");str.append(" sex=").append(sex);String birth = student.getAttribute("birth");str.append(" birthday :").append(birth);/*** 解析student标签中作为内容的hobby标签*/NodeList hobbies = student.getElementsByTagName("hobby");for(int i = 0; i < hobbies.getLength(); i++) {Element hobby = (Element)hobbies.item(i);String hobbyId = hobby.getAttribute("id");String hobbyName = hobby.getTextContent();str.append("\n").append(hobbyId).append(":").append(hobbyName);}/*** 解析student标签中作为内容的introduce标签*/NodeList introduceList = student.getElementsByTagName("introduce");for(int j = 0; j < introduceList.getLength(); j++) {Element introduce = (Element)introduceList.item(j);String introduceText = introduce.getTextContent().trim();str.append("\n简介: ").append(introduceText);}System.out.println(str);}} catch (ParserConfigurationException e) {e.printStackTrace();} catch (SAXException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}}}

上述接卸学生信息XML文件中最需要注意的是XML文件的结构,通过初始化NodeList数组存储标签名中所含的所有信息,之后在循环中,通过下标将取得它们并转换成Element类型的对象,再通过getAttribute()方法和getTextContent()方法来获得数据

P3 设计一个XML文件解析工具

上述对学生信息XML文件解析的程序是没有任何泛用性的,它不能解析其他的XML文件,哪怕同样是学生信息但其中稍有变化,就无法完成任务,java的一项编程思想是面向工具编程,且做到代码复用,为此需要创建一个泛用的工具类来解析各式的XML文件,即把它做成jar包

1 静态块和本地块

在完成设计工具前,先了解静态块和本地块的概念:

通过上述简单的示例可以得知,本地块就是一段java代码,而本地块加上static就成了静态块,静态块发生在类加载过程后,类实例化过程前,即只会被执行一次

2 将XML解析过程工具化

首先分析上述解析学生信息XML文件的程序中的:

1        InputStream is = Class.class.getResourceAsStream("/student.xml");
2       DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
3       DocumentBuilder db = dbf.newDocumentBuilder();
4       Document document = db.parse(is);

上述的这段程序可以看作一个固定的套路,而且从最后一行可以看出,2,3行的程序就是为了得到一个DocumentBuilder类的对象,且对于不同的XML文件解析,这个对象只需要一个就足够了,可以利用静态块只执行一次的特点,只产生一个DocumentBuilder对象,即单例模式

在完成XML解析类前,可以将这段程序设置为static成员作为一个静态块,且在类加载过程后,没有产生XML解析类对象前,就可以直接生成一个DocumentBuilder类对象以供使用

在得到了DocumentBuilder对象后,还需要通过parse(InputStream)方法才能打开要处理的XML文件,并得到所需要的Document类对象,且这一步需要用户提供的XML文件的路径参数,因此需要做成一个方法


至此XML解析工具就可以得到所要解析的XML文件的Document对象了

3 分析“静”与“动”


回顾上述的代码,其中的第26行和第50(64)行都是取得指定标签的节点列表,但是document对象和student对象的类型不同(document是要处理的文件主体,需要从里面拿出学生标签,student是文件中每个学生,需要从中得到这个学生的详细信息),分别是Document类和Element类,这需要两个参数类型不同的方法分别处理,而且由于标签名称也不相同,需要存在字符串类型的参数:

package GetFromXML;import java.io.IOException;
import java.io.InputStream;import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;public class Demo {private static DocumentBuilder db;/*** 静态块只产生一个DocumentBuilder类的对象*/static { try {db = DocumentBuilderFactory.newInstance().newDocumentBuilder();} catch (ParserConfigurationException e) {e.printStackTrace();}}/*** 根据给定的XML文件路径,产生一个Document类的对象*/public Document openXML(String xmlPath) throws SAXException, IOException {Document document = null;InputStream is = Class.class.getResourceAsStream(xmlPath);document = db.parse(is);return document;}/*** 处理传入的document,获得标签列表 */public void parseTag(Document document, String tagName) {NodeList nodeList = document.getElementsByTagName(tagName);for(int index = 0; index < nodeList.getLength(); index++) {Element node = (Element)nodeList.item(index);//TODO}}/*** 处理传入的element,获取内层信息 */public void parseTag(Element element, String tagName) {NodeList nodeList = element.getElementsByTagName(tagName);for(int index = 0; index < nodeList.getLength(); index++) {Element node  =(Element)nodeList.item(index);//TODO}}}

这样就粗略完成了一个解析工具,但是TODO部分的内容却不得而知,因为无法确定用户需要处理哪个XML文件,这个XML文件内的结构和标签里是什么东西,这时就可以使用抽象方法只提供结构框架,让用户完成具体的抽象方法

4 将XML解析类做成抽象类,并解析XML文件

现在为解析类添加一个抽象方法,用来执行具体的处理:

package CoisiniUtil;import java.io.IOException;
import java.io.InputStream;import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;public abstract class XMLParser {private static DocumentBuilder db;public XMLParser() {}/*** 静态块只产生一个DocumentBuilder类的对象*/static {  try {db = DocumentBuilderFactory.newInstance().newDocumentBuilder();} catch (ParserConfigurationException e) {e.printStackTrace();}}/*** 根据给定的XML文件路径,产生一个Document类的对象*/public static Document openXML(String xmlPath) throws XMLNotFoundException,SAXException, IOException {Document document = null;InputStream is = Class.class.getResourceAsStream(xmlPath);if(null == is) {throw new XMLNotFoundException("xml文件未找到");  }document = db.parse(is);return document;}/*** 需要用户完善的抽象方法*/public abstract void dealElement(Element element, int index);/*** 处理传入的document,获得标签列表 */public void dealElementList(Document document, String tagName) {NodeList nodeList = document.getElementsByTagName(tagName);for(int index = 0; index < nodeList.getLength(); index++) {Element node = (Element)nodeList.item(index);//用户需要实现具体操作的parserElement方法dealElement(node, index);}}/*** 处理传入的element,获取内层信息 */public void dealelementList(Element element, String tagName) {NodeList nodeList = element.getElementsByTagName(tagName);for(int index = 0; index < nodeList.getLength(); index++) {Element node  =(Element)nodeList.item(index);//用户需要实现具体操作的parserElement方法dealElement(node, index);}}}

再使用XMLParser抽象类解析XML文件:

package GetFromXML;import java.io.IOException;import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.xml.sax.SAXException;import CoisiniUtil.XMLNotFoundException;
import CoisiniUtil.XMLParser;public class Demo {public static void main(String[] args) {//创建一个XMLParser类的对象//并使用匿名内部类完成它的抽象方法XMLParser xmlParser = new XMLParser() {@Overridepublic void dealElement(Element element, int index) {/*** 解析外层标签的属性*/StringBuffer str = new StringBuffer(); String id = element.getAttribute("id");str.append("id=").append(id);String name = element.getAttribute("name");str.append(" name=").append(name);String sex = element.getAttribute("sex");str.append(" sex=").append(sex);String birth = element.getAttribute("birth");str.append(" birthday :").append(birth);/*** 创建两个匿名对象,并完成抽象方法* 调用该类的dealElementList* 使用方法重载获取详细信息*/new XMLParser() {@Overridepublic void dealElement(Element element, int index) {String hobbyId = element.getAttribute("id");String hobbyName = element.getTextContent();str.append("\n").append(hobbyId).append(":").append(hobbyName);}}.dealelementList(element, "hobby");new XMLParser() {@Overridepublic void dealElement(Element element, int index) {String introduceText = element.getTextContent().trim();str.append("\n简介: ").append(introduceText);}}.dealelementList(element, "introduce");System.out.println(str);}};try {//由文件路径获得Document类的对象Document document = XMLParser.openXML("/student.xml");//方法重载处理标签列表xmlParser.dealElementList(document, "student");       } catch (SAXException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();} catch (XMLNotFoundException e) {e.printStackTrace();}}}

利用工具成功完成了XML文件的解析

P4 将XMLParser和XMLNotFoundException做成工具

1 生成jar工具包

现在将上面完成的XMLParser和XMLNotFoundException放在一个javaproject下的同一个包内,做成jar工具包

1,将整个工程导出成jar文件


2,配置条件,选择生成的目录

3,在给定的目录下生成了jar工具包

2 使用jar工具包

如果想要使用该jar包:

1,复制jar包,在需要的工程下src下创建一个lib目录,将jar包粘贴:

2,将jar包加入到工程中:

3,加入后再导包即可:

jar包是不可被更改的

P5 jd-gui

为了查看某些jar包内的源码内容,可以使用带有GUI的jar,jd-gui

jd-gui 1.5.2

也可下载更高版本,jd-gui可以反编译class文件,带有图形界面

使用时找到jd-gui所在的目录,打开cmd,输入:

java -jar jd-gui-版本号.jar

即可使用

JAVA SE 进阶篇 C3 解析XML文件,做一个jar工具包相关推荐

  1. MEC@JavaSE@进阶篇@笔记09@XML文件以及Properties文件解析初步

    一.XML文件 1.介绍 简介: XML,即,Extensible Markup Language,中文翻译:可扩展标记语言是一种用于标记电子文件使其具有结构性的标记语言. 标签 标签是为了能表达有一 ...

  2. JAVA SE学习day14:解析XML

    XML解析有两种方式:SAX,DOM SAX:simple api for xml,解析XML的简单API,特点是内存占用少,速度快,但由于是逐行扫描式解析,对整体结构没有把控,不能修改XML内容 * ...

  3. Java案例:利用dom4j解析XML文件

    文章目录 一.XML概述 二.dom4j概述 (一)什么是dom4j (二)解析XML性能优异 (三)dom4j针对XML标准定义的实现 三.dom4j使用示例 (一)创建Maven项目 (二)解析X ...

  4. 【java】jdom解析xml文件

    java中有四种分别解析xml文件.分别是,DOM,SAX,DOM4J,JDOM四种.我第一篇就介绍用Jdom解析XML.本人觉得这四种学习其中一种即可.其余三中解析思想差不了多少.况且这四种介绍优缺 ...

  5. Java解析xml文件dom4j篇(基于xml配置文件完成Excel数据的导入、导出功能完整实现)

    DOM4J解析XML文件 dom4j是一个Java的XML API,是jdom的升级产品,用来读写XML文件.另外对比其他API读写XML文件,dom4j是一个十分优秀的JavaXML API,具有性 ...

  6. java xml中的冒号_Java jdom解析xml文件带冒号的属性

    Java jdom解析xml文件带冒号的属性 如果xml文件解析带了冒号的属性,一般都是要特别处理,这里是命名空间,N年前遇到过一次忘记记录,后来也忘了,这次再记录下. 解决了,记录下,分享给大家,百 ...

  7. java解析xml文档_Java解析xml文件

    读xml文件: xml文件内容: Java Eclipse Swift Xcode C# Visual Studio 代码: package XMLParse; import java.io.File ...

  8. 使用java解析XML文件的步骤

    以前的时候,也解析过,今天又拿出来解析就让忘记怎么解析了,后来在网上查还有自己想,终于解析出来了,下面就是原XML文件: accp.xml <?xml version="1.0&quo ...

  9. java xpath 解析xml_使用XPATH解析XML文件

    使用XPATH解析XML文件 import java.util.Iterator; import java.util.List; import org.dom4j.Document; import o ...

最新文章

  1. Python爬虫,通过特定的函数来筛选标签
  2. 解惑解释性语言与编译性语言
  3. Python学习之datetime时间戳
  4. Tensorflow get_variable和Varialbe的区别
  5. JavaScript基础笔记
  6. WIFI无线路由器的五种工作模式
  7. 微电台│Get产品信息管理指南,和客户谈一场全渠道恋爱!
  8. 冰心的作品有哪些?聊一聊冰心都有哪些作品?
  9. 为什么我只写微头条,粉丝一天就增加700多人?
  10. hdu 1186(搜索+HASH)
  11. selenium python怎么断言_如何为python / selenium中的特定元素断言文本?
  12. .NET客户端实现Redis中的管道(PipeLine)与事物(Transactions)
  13. 阿里架构师必学的2019最新资料!首次公布
  14. GML C++ Camera Calibration Toolbox 相机标定畸变矫正
  15. 每日学习笔记(20)
  16. 计算机制图大赛,制图大赛简介
  17. JavaScript中栈内存与堆内存分别是什么?
  18. Android:如何优雅的开发马甲包?
  19. 不用找,你想要的酒店餐饮su模型素材都在这里
  20. 葫芦娃手游服务器未响应,葫芦娃充值没反应 充值元宝未到账解决办法

热门文章

  1. 硬盘、移动硬盘或U盘的文件系统变成了RAW格式的解决办法
  2. SPAMnet(AAAI2020) 立体图像SR+一致性保持 Stereoscopic Image Super-Resolution with Stereo Consistent Feature
  3. 【项目管理】软件项目外包常见的3个坑
  4. ubuntu安装fcitx五笔拼音输入法
  5. 【死磕JVM】五年 整整五年了 该知道JVM加载机制了!
  6. 网络编程五种IO模型的形象比喻(老陈收信)
  7. mysql基础地总结一下
  8. GBK解码报错-UnicodeDecodeError: ‘gbk‘ codec can‘t decode byte 0xa1 in position 98: illegal multibyte seq
  9. K8s系列之:命名空间Namespace
  10. 一个简单的留言微信小程序