java工程师必会技术:XML(详细易理解)

备注:该技术博客的内容是我根据技术视频整理与总结的(并非复制粘贴)。取自黑马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.存储的数据的用途

  • 作为配置文件存储数据(XML配置文件存储复杂的数据,而不像properties配置文件存储简单的数据)。
  • 把数据存起来在网络中传输。

4.XML和HTML的区别

  • XML标签都是自定义的,HTML标签是预定义。
  • XML语法严格,HTML语法松散。
  • XML是存储数据的,HTML是展示数据的

快速入门

我们先在桌面上创建一个记事本,后缀名改成.xml,写一段XML代码:

<?xml version='1.0' ?>  文档声名

<users>
	<user id='1'>
		<name>zhangsan</name>
		<age>23</age>
		<gender>male</gender>
	</user>

	<user id='2'>
		<name>lisi</name>
		<age>24</age>
		<gender>female</gender>
	</user>
</users>

保存之后我们将该桌面上的代码文件拖入浏览器中,效果如下:
在这里插入图片描述
运行成功了,我们来总结一下XML代码的基本语法

  • XML文档的后缀名是 .xml
  • XML第一行必须定义位 文档声明。 文档声明上方不能有空格(特别严格),否则报错!
    在这里插入图片描述
  • XML文档必须有且仅有一个根标签,比如上面代码中的user标签。
  • 属性值必须使用引号(单双都可)引起来,否则报错。
  • 标签必须正确关闭,要么自闭合标签,要么围堵标签。
  • HTML标签不区分大小写(建议用小写),而XML的标签区分大小写。

XML组成部分及注意事项

1.文档声明:

格式:<?xml 属性列表 ?>
属性列表:

  • version:版本号,必须要写,目前常用1.0版本。
  • encoding:编码方式。告知解析引擎当前使用的字符集,默认值:ISO-8859-1
  • standalone(一般不设置这个值,了解即可):是否独立。取值有两个(yes,no),yes表示不依赖其他文件,no反之。

2.指令(了解):
结合CSS展示数据,但是XML作用已经改成存储数据,所以了解即可。结合方式代码如下:

<?xml-stylesheet type="text/css" href="a.css" ?>

3.标签:
标签名称是自定义的。

4.属性:
id属性值唯一。

5.文本:
CDATA区:在该区域中的数据会被原样展示。
格式: <![CDATA[ 展示的数据 ]]>

约束

在讲解约束问题之前,先问两个问题:谁编写XML? 谁解析XML?
那必然是软件的使用者(用户)编写的XML文档,必然是软件自身解析(获取文档中的数据)。我们用一张图来理解:

在这里插入图片描述
根据上图得知,我们程序员(用户)编写XML文档,软件去解析XML文档,获取用户编写的数据,就可以去改变背景色之类的功能。我们程序员想要去用框架就需要XML作为一个媒介。框架提前写好了就可以解析XML文档。程序员可以告诉框架做什么事情。

但是软件怎么知道程序员要写什么标签呢?毕竟XML文档是可拓展标记语言,标签可以随便定义,所以不能随便写,需要约定。所以在框架提供的时候,就为XML写了一个说明书(说明文档)。程序员需要按照规定文档去写XML文档,我们就称说明的文档为约束(约束文档)。而这个约束文档是由软件提供的。谁写的框架,谁去编写约束文档。

约束的概念:规定XML文档的书写规则。

我们程序员作为框架使用者,要求只有两个:

  • 能够在XML中引入约束文档。
  • 能够简单的读懂约束文档。

约束(约束文档)的分类:

  1. DTD:一种简单的约束技术。
  2. Schema:一种复杂的约束技术。

上面我们说了,只要能够简单的读懂约束文档就可以了。

我们先学第一个约束技术,使用DTD约束文档,第一件事是引入DTD文档到XML文档中。由于DTD文档的格式不一样,所以引入的方式也不一样。DTD文档分为两种方式:

  1. 内部DTD:将约束规则定义在XML文档中。(不常用,了解即可)
  2. 外部DTD:将约束的规则定义在外部的DTD文件中。

外部DTD也分为两种型式:

  1. 本地:
  2. 网络:

我们再来学习一下第二个约束技术,使用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解析的思想) 是什么:

  1. DOM:将标记语言文档一次性加载进内存,在内存中会形成一颗DOM树。
    优点: 操作比较方便,可以对文档进行CRUD的所有操作。
    缺点: 比较占内存。
  2. SAX:逐行读取,基于事件驱动来完成事件的获取。
    优点: 基本不占内存,可以适用于内存较小的设备(手机)。
    缺点: 只能读取,不能增删改。
    首先读第一行,然后指针向下移动一行,并且将第一行资源释放。也就说:读一行释放一行,在内存中永远只存在一行。

我们在服务器端一般使用DOM思想,在移动端(安卓设备)使用SAX思想。今天只讲解DOM思想。

XML常见的解析器:
解析器其实就是针对于上面两种解析的思想(DOM SAX),写出来一些供我们使用的工具包。当然我们可以根据自己的思想来写,但是太麻烦了。我们直接使用第三方开源的解析器(工具包)即可。

介绍几种常见的解析器了解一下,我们采用一种解析一下就可以:
1.JAXP(SUN公司提供):支持DOM和SAX两种思想。
由于功能不好,性能低,代码写起来很麻烦,基本上没人使用它,(了解)

2.DOM4J:一款非常优秀的解析器,是基于DOM思想实现的解析器。

3.Jsoup:本来是用于解析HTML的,但是由于特别好用,同样可以用来解析XML。(学习重点)

4.PULL:是安卓操作系统内置的解析器,SAX方式的。(了解)

我们接下来重点(主要)学习Jsoup解析器的解析方式。

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解析器是一个第三方开源免费且功能强大的解析器,我们使用它步骤如下

  1. 导入相关jar包
  2. 获取Document对象(代表整个DOM的树形结构)
  3. 获取对应的标签(Element对象)
  4. 获取数据

快速入门代码如下:

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解析器中的常见对象:

  1. Jsoup(工具类):解析HTML或XML文档,返回Document对象。
  2. Document:文档对象。代表内存中的dom树。
  3. Elements:元素Element对象的集合。可以把它当作ArrayList< Element >来使用。
  4. Element::元素对象。可以获取元素的名称、属性、文本等…
  5. Node:节点对象。(上面这些对象的父亲)

接下来我们来学习这些对象。

一、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 = "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n" +
                "\n" +
                "<students>\n" +
                "\t<student number=\"heima_0001\">\n" +
                "\t\t<name>tom</name>\n" +
                "\t\t<age>18</age>\n" +
                "\t\t<sex>male</sex>\n" +
                "\t</student>\n" +
                "\n" +
                "\t<student number=\"heima_0002\">\n" +
                "\t\t<name>jack</name>\n" +
                "\t\t<age>18</age>\n" +
                "\t\t<sex>female</sex>\n" +
                "\t</student>\n" +
                "</students>";
        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. 获取子元素对象(只演示其中一个):
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. 获取属性值:
1.String attr(String key):根据属性名称获取属性值

代码展示://获取student对象的属性值
        String number = element_student.attr("number");
        System.out.println(number); //heima_0001
  1. 获取文本内容:
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中都可以使用。(了解,有印象即可)

快捷查询方式

  1. selector:选择器(可以结合CSS的选择器一起使用)

使用的方法是: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);
  1. XPath:是XML路径语言,它是一种确定XML文档中某部分位置的语言

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是这个世界上最好的语言。

猜你喜欢

转载自blog.csdn.net/weixin_46594796/article/details/108048767