备注:该技术博客的内容是我根据技术视频整理与总结的(并非复制粘贴)。取自黑马JavaWeb课程。
1.XML(Extensible Markup Language):可扩展标记语言。
这个概念看起来有点抽象,我们来理解理解。可拓展通俗理解就是标签都是自定义的。我们之前学习HTML的时候,发现HTML的标签都是系统规定好的,直接使用即可。然而XML没有任何一个标签是规定好的,都是自定义的标签。 比如:
<user>user>
<student>student>
2.那么XML和HTML有什么关系呢?
XML和HTML是亲兄弟。他们共同的父亲是W3C(万维网联盟)。 也就是说HTML和XML都是W3C发布的。早期只有HTML,由于它语法简单,大部分浏览器兼容,所以它非常的火爆。但是因为浏览器之间的恶性竞争(无论多么错误的语法基本都可以解析)导致HTML语法非常的松散,基本上写HTML很难报错。因此W3C推出了XML想从而取代HTML。XML要求语法非常的严格, 稍微出错就会展示失败。正因为XML的语法严格从而导致程序员不是特别喜欢使用XML,所以XML没有办法取代他的哥哥HTML。因此XML转换方向不再去和HTML竞争,竞争枪口指向了properties配置文件。 XML认为properties配置文件存储数据特别差劲。最后XML找到自己的发展方向,不再去像HTML那样展示数据,而是去存储数据。所以XML的功能是:存储数据!!
3.存储的数据的用途
4.XML和HTML的区别
我们先在桌面上创建一个记事本,后缀名改成.xml,写一段XML代码:
文档声名
<users>
<user id='1'>
<name>zhangsanname>
<age>23age>
<gender>malegender>
user>
<user id='2'>
<name>lisiname>
<age>24age>
<gender>femalegender>
user>
users>
保存之后我们将该桌面上的代码文件拖入浏览器中,效果如下:
运行成功了,我们来总结一下XML代码的基本语法:
1.文档声明:
格式:
属性列表:
2.指令(了解):
结合CSS展示数据,但是XML作用已经改成存储数据,所以了解即可。结合方式代码如下:
3.标签:
标签名称是自定义的。
4.属性:
id属性值唯一。
5.文本:
CDATA区:在该区域中的数据会被原样展示。
格式:
在讲解约束问题之前,先问两个问题:谁编写XML? 谁解析XML?
那必然是软件的使用者(用户)编写的XML文档,必然是软件自身解析(获取文档中的数据)。我们用一张图来理解:
根据上图得知,我们程序员(用户)编写XML文档,软件去解析XML文档,获取用户编写的数据,就可以去改变背景色之类的功能。我们程序员想要去用框架就需要XML作为一个媒介。框架提前写好了就可以解析XML文档。程序员可以告诉框架做什么事情。
但是软件怎么知道程序员要写什么标签呢?毕竟XML文档是可拓展标记语言,标签可以随便定义,所以不能随便写,需要约定。所以在框架提供的时候,就为XML写了一个说明书(说明文档)。程序员需要按照规定文档去写XML文档,我们就称说明的文档为约束(约束文档)。而这个约束文档是由软件提供的。谁写的框架,谁去编写约束文档。
约束的概念:规定XML文档的书写规则。
我们程序员作为框架使用者,要求只有两个:
约束(约束文档)的分类:
上面我们说了,只要能够简单的读懂约束文档就可以了。
我们先学第一个约束技术,使用DTD约束文档,第一件事是引入DTD文档到XML文档中。由于DTD文档的格式不一样,所以引入的方式也不一样。DTD文档分为两种方式:
外部DTD也分为两种型式:
我们再来学习一下第二个约束技术,使用Schema约束文档,Schema作为一个复杂的约束技术肯定弥补了DTD的缺陷(内容不限定,可以把age标签写成非数字的内容)。使用步骤如下:
1.填写xml文档的根元素
2.引入xsi前缀. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3.引入xsd文件命名空间. xsi:schemaLocation="http://www.itcast.cn/xml student.xsd"
4.为每一个xsd约束声明一个前缀,作为标识 xmlns="http://www.itcast.cn/xml"
接下来我们来说一下XML解析,其实解析就是操作XML文档,将文档中的数据读取到内存中。
然而操作XML文档却有一下两种方式:
1.解析(读取):将文档中的数据读取到内存中。
2.写入:将内存中的数据保存到XML文档中。持久化的存储。(了解即可)
我们可以发现解析和写入操作与我们之前学的IO流理解方式非常相似。
我主要讲解析,引入写入操作对于我们JAVA程序员来说不会有太多。所以我们了解意思即可。
既然我们要解析XML文档,我就得需要了解析XML的方式(XML解析的思想) 是什么:
我们在服务器端一般使用DOM思想,在移动端(安卓设备)使用SAX思想。今天只讲解DOM思想。
XML常见的解析器:
解析器其实就是针对于上面两种解析的思想(DOM SAX),写出来一些供我们使用的工具包。当然我们可以根据自己的思想来写,但是太麻烦了。我们直接使用第三方开源的解析器(工具包)即可。
介绍几种常见的解析器了解一下,我们采用一种解析一下就可以:
1.JAXP(SUN公司提供):支持DOM和SAX两种思想。
由于功能不好,性能低,代码写起来很麻烦,基本上没人使用它,(了解)
2.DOM4J:一款非常优秀的解析器,是基于DOM思想实现的解析器。
3.Jsoup:本来是用于解析HTML的,但是由于特别好用,同样可以用来解析XML。(学习重点)
4.PULL:是安卓操作系统内置的解析器,SAX方式的。(了解)
我们接下来重点(主要)学习Jsoup解析器的解析方式。
使用解析器之前,我们要先创建一个XML文档,名字为student.xml 文档中的代码如下:
<?xml version="1.0" encoding="UTF-8" ?>
<students>
<student number="heima_0001">
<name id="xuzhibin">tom</name>
<age>18</age>
<sex>male</sex>
</student>
<student number="heima_0002">
<name>jack</name>
<age>18</age>
<sex>female</sex>
</student>
</students>
XML文档准备完毕后我们就可以使用解析器去解析XML文档,Jsoup解析器是一个第三方开源免费且功能强大的解析器,我们使用它步骤如下:
快速入门代码如下:
public class JsoupDemo1 {
public static void main(String[] args) throws IOException {
//2.获取Document对象,根据XML文档获取文档对象
//2.1获取student.xml的path,通过使用类加载器
String path = JsoupDemo1.class.getClassLoader().getResource("student.xml").getPath();
//2.2解析XML文档,加载文档的进内存,获取DOM树--->Document对象
Document document = Jsoup.parse(new File(path), "utf-8");
//3.获取元素对象(Element对象),可看作集合。用索引访问数据
Elements elements = document.getElementsByTag("name");
System.out.println(elements.size());
//3.1获取第一个name的Element对象
Element element = elements.get(0);
//3.2获取数据
String name = element.text();
System.out.println(name);
}
}
接下来我们来学习这些对象。
一、Jsoup对象:
parse方法:解析HTML或XML文档,返回Document对象。
该方法有许多重载型式:
1. parse(File in,String charsetName): 解析XML或HTML文件(常用,重点)
代码展示:String path = JsoupDemo2.class.getClassLoader().getResource("student.xml").getPath();
Document document = Jsoup.parse(new File(path), "utf-8");
System.out.println(document);
===============================================================================================
2. parse(String html): 解析XML或HTML字符串(了解)
代码展示:String str = "\n" +
"\n" +
"\n" +
"\t\n" +
"\t\ttom \n" +
"\t\t18 \n" +
"\t\tmale \n" +
"\t\n" +
"\n" +
"\t\n" +
"\t\tjack \n" +
"\t\t18 \n" +
"\t\tfemale \n" +
"\t\n" +
"";
Document document = Jsoup.parse(str);
System.out.println(document);
=============================================================================================
3.parse(URL rul,int timeoutMillis): 通过网络路径获取指定的HTML和XML的文档对象
(多用于解析HTML,可以用于做一些爬虫的小程序,我可以获取各个网站的数据对它进行操作)
代码展示:URL url = new URL("网络中的资源路径");
Document document = Jsoup.parse(url, 10000);
System.out.println(document);
二、Document对象(继承Element对象):
该对象是文档对象,代表一个DOM树。主要是用来获取Element对象,里面有许多的get方法,我们来了解常用的几个:
1.getElementById(String id):根据id属性值来获取唯一的Element对象
代码展示://我们将XML文档中的第一个name标签中插入一个id属性,属性值为xuzhibin
//获取id属性值的元素对象
Element xuzhibin = document.getElementById("xuzhibin");
System.out.println(xuzhibin);
=========================================================================================
2.getElementByTag(String tagName):根据标签名称获取元素对象集合
代码展示://获取XML文档中所有student对象
Elements elements = document.getElementsByTag("student");
System.out.println(elements);
=========================================================================================
3.getElementsByAttribute(String key):根据属性名称获取元素对象集合
代码展示://获取属性名为id的元素对象们
Elements elements1 = document.getElementsByAttribute("id");
System.out.println(elements1);
=========================================================================================
4.getElementsByAtrributeValue(String key,String value):根据对应的属性名和属性值获取元素对象集合。
(并不是真正的集合,它返回的是Elements,相当于ArrayList集合)
代码展示://获取number属性值为heima_0001的元素对象
Elements elements2 = document.getElementsByAttributeValue("number", "heima_0001");
System.out.println(elements2);
三、Element对象:
Element对象有许多功能,比如获取子元素对象。Element对象与之前我们用Document对象有区别:Document对象来获取Element对象是可以获取任意的对象,然而现在我们使用Element元素对象调用方法获取对象仅仅是子元素对象!Document对象中的几个方法Element对象都是可以使用的。我们来看看他的获取方法展示:
1.getElementById(String id):根据id属性值来获取唯一的Element对象
=======================================================================================
2.getElementByTag(String tagName):根据标签名称获取元素对象集合
代码展示://通过Element对象获取子标签对象
Element element_student = document.getElementsByTag("student").get(0);
Elements ele_name = element_student.getElementsByTag("name");
System.out.println(ele_name.size()); // 1
=======================================================================================
3.getElementsByAttribute(String key):根据属性名称获取元素对象集合
=======================================================================================
4.getElementsByAtrributeValue(String key,String value):根据对应的属性名和属性值获取元素对象集合。
1.String attr(String key):根据属性名称获取属性值
代码展示://获取student对象的属性值
String number = element_student.attr("number");
System.out.println(number); //heima_0001
1.String text():获取所有字标签的纯文本内容
代码展示:String text = ele_name.text();
System.out.println(text);
=======================================================================================
2.String html():获取标签体的所有内容(包括子标签的标签和文本内容)
代码展示:String html = ele_name.html();
System.out.println(html);
四、Node对象:
是Document和Element的父类。Node对象中定义了许多方法在Document和Element中都可以使用。(了解,有印象即可)
使用的方法是:Elements select(String cssQuery),接下来我们来介绍一下他的语法(参考Selector类中定义的语法完成选择器的查询动作)。我们用选择器做几个快捷的例子:
// 查询name标签 根据元素选择器
Elements elements = document.select("name");//这样就拿到所有的name标签
System.out.println(elements);
======================================================================================
//查询id值为xuzhibin的元素
Elements elements1 = document.select("#xuzhibin");
System.out.println(elements1);
======================================================================================
//想获取student标签并且number属性值为heima_0001的age子标签
Elements elements3 = document.select("student[number=heima_0001] > age");
System.out.println(elements3);
XPath仅仅是对XML的DOM树形结构进行操作的,也就是说我们只要有树形结构就可以操作了。
那么使用Jsoup解析器的Xpath需要额外导入一个jar包。因为Xpath是一个独立的东西,跟Jsoup并没有什么联系。
导入jar包后,就可以使用Jsoup的XPath了。相当于使用Jsoup获取Document对象,然后使用jar包中的API结合Xpath的语法来选取DOM树中的某些元素内容,接下来我们代码展示一下:
// 我们获取了Document对象是Jsoup中的,而Jsoup并不支持Xpath语法,
// 我们需要根据Document对象来创建JXDocument对象,来自jar包中,支持XPath语法。
JXDocument jxDocument = new JXDocument(document);
//集合XPath的语法来查询
List<JXNode> jxNodes = jxDocument.selN("//student");// 查询所有的student标签
for (JXNode jxNode : jxNodes) {
System.out.println(jxNode);
}
//查询所有student标签下的name标签
List<JXNode> jxNodes2 = jxDocument.selN("//student/name");
for (JXNode jxNode : jxNodes2) {
System.out.println(jxNode);
}
//查询student标签下带id属性的name标签
List<JXNode> jxNodes3 = jxDocument.selN("//student/name[@id]");
for (JXNode jxNode : jxNodes3) {
System.out.println(jxNode);
}
//查询student标签下带id属性的name标签,并且id的属性值为xuzhibin
List<JXNode> jxNodes4 = jxDocument.selN("//student/name[@id='xuzhibin']");
for (JXNode jxNode : jxNodes4) {
System.out.println(jxNode);
}
我们可以发现XPath语法,有需求根据文档找对应的事例,基本上都能找到。我们只需要查询W3Cschool参考手册,会用XPath的基本语法完成查询就可以了。
以上就是快捷查询的两种方式,不论使用哪一个都可以。
说实在的,有关XML的知识真的很琐碎很多,让人看起来真的很头大。但是学习的过程就是这样,很艰辛难熬。我们只需要稳下心来慢慢学,一点点消化没有什么技术是我们攻不破的。学习就是一个循循渐进的过程。这篇将近万字博客也是花费了很多时间,XML这个技术说实在的,顶多就是繁琐,确实不算难,只不过麻烦而已。我们作为JAVA后端程序员只需要会查询参考书使用即可,不要过于深追原理。这篇博客是我边学习边整理的,用了接近8个小时时间,但是确实不是那么难,让我们一起进步。最后说一句:JAVA是这个世界上最好的语言。