<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
	<channel>
		<title>协议与规范 on 易哥</title>
		<link>https://yeecode.top/tags/%E5%8D%8F%E8%AE%AE%E4%B8%8E%E8%A7%84%E8%8C%83/</link>
		<description>Recent content in 协议与规范 on 易哥</description>
		<generator>Hugo</generator>
		<language>zh-cn</language>
		
		
		
		
			<lastBuildDate>Thu, 01 Jan 2026 00:00:00 +0000</lastBuildDate>
		
			<atom:link href="https://yeecode.top/tags/%E5%8D%8F%E8%AE%AE%E4%B8%8E%E8%A7%84%E8%8C%83/index.xml" rel="self" type="application/rss+xml" />
			<item>
				<title>VoiceXML入门学习指南</title>
				<link>https://yeecode.top/blog/126/</link>
				<pubDate>Thu, 01 Jan 2026 00:00:00 +0000</pubDate>
				<guid>https://yeecode.top/blog/126/</guid>
				<description>&lt;p&gt;VoiceXML（语音可扩 展标记语言）是用来描述语音对话过程的标记语言。其定义了如何使用语音识别、语音合成、互联网访问、数据库访问、语音文件播放、DTMF输入等功能开发一 个完整的语音应用系统。&lt;/p&gt;&#xA;&lt;p&gt;用VoiceXML开发的语音应用系统，不仅可以完全代替传统CTI(计算机电话集成) 系统所能提供的功能，而且还可以使应用系统开发过程极其简单快捷、系统有极高的可扩展性、可维护性、可移植性、可重用性和开放性。&lt;/p&gt;&#xA;&lt;h2 id=&#34;1-概述&#34;&gt;1 概述&lt;/h2&gt;&#xA;&lt;h2 id=&#34;11-voicexml的历史与背景&#34;&gt;1.1 VoiceXML的历史与背景&lt;/h2&gt;&#xA;&lt;p&gt;VoiceXML的出现最早可以追溯到1995在AT&amp;amp;T公司开发的基于XML的电话标记语言（PML）。随后，AT&amp;amp;T、Lucent Technologies以及Motorola公司分别各自着手开发自己的类似于PML的语音标记语言。到了1998年，W3C组织的“语音浏览器”会议上，AT&amp;amp;T和Lucent Technologies分别展现了他们各自的类同PML的标记语言、Motorola和IBM公司分别推出VoxML和SpeechML、HP和PipeBeach公司也分别推出TalkML和VoiceHTML。AT&amp;amp;T、IBM、Lucent Technoglies、以及Motorola随后成立了VoiceXML论坛，其目的是为了建立一个语音对话应用系统的国际标准。到了2000年，AT&amp;amp;T、IBM、Lucent Technologies、以及Motorola通过W3C协会联合推出语音可扩展标记语言VoiceXML1.0。该标准一经推出，便得到相关行业众多公司的响应。经过两年多的论证和实际系统验证，VoiceXML2.0最终草案在2003年推出。&lt;/p&gt;&#xA;&lt;h2 id=&#34;12-为什么要用voicexml&#34;&gt;1.2 为什么要用VoiceXML？&lt;/h2&gt;&#xA;&lt;p&gt;VoiceXML的推出给电话语音系统带来全新的应用和开发概念，使传统的CTI技术从繁琐、封闭的模式中走了出来，使广大的语音系统开发人员可以用极其简单的方法实现复杂系统的开发。&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;完全替代传统CTI&lt;/strong&gt;：传统的电话语音系统典型的工作方式是&lt;strong&gt;接受用户的按键输入和语音文件播放、跟据用户的需求为用户提供相应服务&lt;/strong&gt;。基于VoiceXML开发的电话语音系统完全可以替代传统CTI系统所能提供的功能。&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;语音识别功能&lt;/strong&gt;：基于VoiceXML开发的电话语音系统除了接受用户的按键输入之外，还可以接受用户的语音输入。系统通过语音识别功能实现对用户输入语音到文本的转换。这对于许多仅用按键输入方式而无法解决或解决起来很繁琐的应用领域很有实用意义。&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;语音合成功能&lt;/strong&gt;：基于VoiceXML开发的电话语音系统除了能够播放预先录制的语音文件之外，还可以将系统中的文本转换成语音的方式播放给用户。这对于那些需要播报即时消息和可变信息等的应用领域很有实用价值。&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;与互联网联结&lt;/strong&gt;： 长期以来，公用电话网和互联网是分离的。随着互联网技术的迅速发展，互联网信息与日俱增，以及互联网相关服务的日新月异，将互联网与公用电话网整合为一 体，使广大的电话用户也能享受到互联网提供的信息和服务显得越来越有吸引力。VoiceXML使公用电话网与互联网有机地结合，使两网的信息能够相互流 动。例如，电话语音流言可以通过互联网以电子邮件的方式传送到目的地；互联网上的新闻可以通过电话播放给用户等。&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;灵活的数据库接口&lt;/strong&gt;：许多电话语音应用系统离不开数据库访问。VoiceXM通过脚本方式提供灵活的数据库接口，使得应用系统可以方便地访问各种数据库，如：Microsoft SQL Server 2000、Oracle、Sybase、Microsoft Access、MySQL等。&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;简化开发过程&lt;/strong&gt;： 用VoiceXML将电话语音应用系统开发人员从繁琐的编码细节中解脱了出来。开发人员不需要了解相关软件（如语音识别和语音合成）和硬件（如语音卡）API的编程接口，只需要把精力放在应用领域的业务流程上。开发过程轻松快捷、开发周期大大缩短（7-10倍）。VoiceXML使开发人员得以用简 单的方法实现复杂的工作。&lt;/p&gt;&#xA;&lt;p&gt;除此之外，基于VoiceXML开发的语音应用系统具有很高的&lt;strong&gt;系统可扩展性&lt;/strong&gt;、&lt;strong&gt;可维护性&lt;/strong&gt;、&lt;strong&gt;可移植性&lt;/strong&gt;、&lt;strong&gt;可重用性和开放性&lt;/strong&gt;。&lt;/p&gt;&#xA;&lt;h2 id=&#34;13-voicexml现状&#34;&gt;1.3 VoiceXML现状&lt;/h2&gt;&#xA;&lt;p&gt;自 2000年VoiceXML1.0推出以后经过不断的修改，于2003年1月推出最新的VoiceXML2.0最终推荐版本。根据W3C称，该版本将会比 较稳定，鼓励各VoiceXML浏览器生产厂家可以根据此版本进行开发。预计不久VoiceXML2.0将会正式推出。&lt;/p&gt;&#xA;&lt;p&gt;中国目前也有一些相关行业的公司在着手开发有关VoiceXML的产品。深圳市华琛科技有限公司是国内领先的VoiceXML语音平台生产厂家。在华琛公司 的VoPromote平台上，开发人员可以用VoiceXML2.0脚本语言开发应用于各行业的电话语音系统。&lt;/p&gt;&#xA;&lt;h2 id=&#34;14-小结&#34;&gt;1.4 小结&lt;/h2&gt;&#xA;&lt;p&gt;VoiceXML标准的出现给电话语音应用系统的开发带来了全新的概念，同时还大大扩展了语音应用系统的应用范围。可以预计，VoiceXML标准的推广将会极大地推动电话语音应用系统的开发和应用，将给广大的电话用户带来深远的影响。&lt;/p&gt;&#xA;&lt;h2 id=&#34;2-元素介绍&#34;&gt;2 元素介绍&lt;/h2&gt;&#xA;&lt;p&gt;Voice XML的常用元素如下：&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;code&gt;&amp;lt;assign&amp;gt;&lt;/code&gt;    给变量赋值。&lt;/li&gt;&#xA;&lt;li&gt;&lt;code&gt;&amp;lt;audio&amp;gt;&lt;/code&gt; 播放语音文件。&lt;/li&gt;&#xA;&lt;li&gt;&lt;code&gt;&amp;lt;block&amp;gt;&lt;/code&gt; 无用户交互的可执行代码块。&lt;/li&gt;&#xA;&lt;li&gt;&lt;code&gt;&amp;lt;catch&amp;gt;&lt;/code&gt; 捕获一个事件。&lt;/li&gt;&#xA;&lt;li&gt;&lt;code&gt;&amp;lt;choice&amp;gt;&lt;/code&gt;    定义一个菜单项。&lt;/li&gt;&#xA;&lt;li&gt;&lt;code&gt;&amp;lt;clear&amp;gt;&lt;/code&gt; 清除一个或多个框架项。&lt;/li&gt;&#xA;&lt;li&gt;&lt;code&gt;&amp;lt;disconnect&amp;gt;&lt;/code&gt;    结束一次通话。&lt;/li&gt;&#xA;&lt;li&gt;&lt;code&gt;&amp;lt;else&amp;gt;&lt;/code&gt;  用于&lt;code&gt;&amp;lt;if&amp;gt;&lt;/code&gt;元素中的else。&lt;/li&gt;&#xA;&lt;li&gt;&lt;code&gt;&amp;lt;elseif&amp;gt;&lt;/code&gt;    用于&lt;code&gt;&amp;lt;if&amp;gt;&lt;/code&gt;元素中的elseif。&lt;/li&gt;&#xA;&lt;li&gt;&lt;code&gt;&amp;lt;enumerate&amp;gt;&lt;/code&gt; 列举菜单选项。&lt;/li&gt;&#xA;&lt;li&gt;&lt;code&gt;&amp;lt;error&amp;gt;&lt;/code&gt; 捕获一个&lt;code&gt;&amp;lt;error&amp;gt;&lt;/code&gt;事件。&lt;/li&gt;&#xA;&lt;li&gt;&lt;code&gt;&amp;lt;exit&amp;gt;&lt;/code&gt;  退出一次通话。&lt;/li&gt;&#xA;&lt;li&gt;&lt;code&gt;&amp;lt;field&amp;gt;&lt;/code&gt; 在框架中申明一个输入域。&lt;/li&gt;&#xA;&lt;li&gt;&lt;code&gt;&amp;lt;filled&amp;gt;&lt;/code&gt;    指定当输入域被填充以后需要作的操作。&lt;/li&gt;&#xA;&lt;li&gt;&lt;code&gt;&amp;lt;form&amp;gt;&lt;/code&gt;  提示信息和接受数据的对话框架。&lt;/li&gt;&#xA;&lt;li&gt;&lt;code&gt;&amp;lt;goto&amp;gt;&lt;/code&gt;  把控制转向在同一个或不同文档中的对话。&lt;/li&gt;&#xA;&lt;li&gt;&lt;code&gt;&amp;lt;grammar&amp;gt;&lt;/code&gt;   指定语音识别或DTMF语法。&lt;/li&gt;&#xA;&lt;li&gt;&lt;code&gt;&amp;lt;help&amp;gt;&lt;/code&gt;  捕获一个&lt;code&gt;&amp;lt;help&amp;gt;&lt;/code&gt;事件。&lt;/li&gt;&#xA;&lt;li&gt;&lt;code&gt;&amp;lt;if&amp;gt;&lt;/code&gt;    条件逻辑。&lt;/li&gt;&#xA;&lt;li&gt;&lt;code&gt;&amp;lt;initial&amp;gt;&lt;/code&gt;   在进入一个双向交互式对话框架时申明初始对话逻辑。&lt;/li&gt;&#xA;&lt;li&gt;&lt;code&gt;&amp;lt;link&amp;gt;&lt;/code&gt;  在所有对话公共链接区域指定控制转向。&lt;/li&gt;&#xA;&lt;li&gt;&lt;code&gt;&amp;lt;log&amp;gt;&lt;/code&gt;   生成调试信息。&lt;/li&gt;&#xA;&lt;li&gt;&lt;code&gt;&amp;lt;menu&amp;gt;&lt;/code&gt;  定义菜单对话。&lt;/li&gt;&#xA;&lt;li&gt;&lt;code&gt;&amp;lt;meta&amp;gt;&lt;/code&gt;  定义一个元数据项。&lt;/li&gt;&#xA;&lt;li&gt;&lt;code&gt;&amp;lt;metadata&amp;gt;&lt;/code&gt;  定义元数据信息。&lt;/li&gt;&#xA;&lt;li&gt;&lt;code&gt;&amp;lt;noinput&amp;gt;&lt;/code&gt;   捕获一个&lt;code&gt;&amp;lt;noinput&amp;gt;&lt;/code&gt;事件。&lt;/li&gt;&#xA;&lt;li&gt;&lt;code&gt;&amp;lt;nomatch&amp;gt;&lt;/code&gt;   捕获一个&lt;code&gt;&amp;lt;nomatch&amp;gt;&lt;/code&gt;事件。&lt;/li&gt;&#xA;&lt;li&gt;&lt;code&gt;&amp;lt;object&amp;gt;&lt;/code&gt;    系统扩展的对象。&lt;/li&gt;&#xA;&lt;li&gt;&lt;code&gt;&amp;lt;option&amp;gt;&lt;/code&gt;    在一个输入域中选择一个选项。&lt;/li&gt;&#xA;&lt;li&gt;&lt;code&gt;&amp;lt;param&amp;gt;&lt;/code&gt; &lt;code&gt;&amp;lt;object&amp;gt;&lt;/code&gt;或&lt;code&gt;&amp;lt;subdialog&amp;gt;&lt;/code&gt;的参数。&lt;/li&gt;&#xA;&lt;li&gt;&lt;code&gt;&amp;lt;prompt&amp;gt;&lt;/code&gt;    指定语音合成提示和声音文件输出。&lt;/li&gt;&#xA;&lt;li&gt;&lt;code&gt;&amp;lt;property&amp;gt;&lt;/code&gt;  指定特性值以控制平台设置。&lt;/li&gt;&#xA;&lt;li&gt;&lt;code&gt;&amp;lt;record&amp;gt;&lt;/code&gt;    录音。&lt;/li&gt;&#xA;&lt;li&gt;&lt;code&gt;&amp;lt;reprompt&amp;gt;&lt;/code&gt;  指定重新提示。&lt;/li&gt;&#xA;&lt;li&gt;&lt;code&gt;&amp;lt;return&amp;gt;&lt;/code&gt;    从子对话中返回。&lt;/li&gt;&#xA;&lt;li&gt;&lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt;    定义ECMAScript模块。&lt;/li&gt;&#xA;&lt;li&gt;&lt;code&gt;&amp;lt;subdialog&amp;gt;&lt;/code&gt; 调用一个子对话。&lt;/li&gt;&#xA;&lt;li&gt;&lt;code&gt;&amp;lt;submit&amp;gt;&lt;/code&gt;    向文件服务器上传数据。&lt;/li&gt;&#xA;&lt;li&gt;&lt;code&gt;&amp;lt;throw&amp;gt;&lt;/code&gt; 产生一个事件。&lt;/li&gt;&#xA;&lt;li&gt;&lt;code&gt;&amp;lt;transfer&amp;gt;&lt;/code&gt;  电话转接。&lt;/li&gt;&#xA;&lt;li&gt;&lt;code&gt;&amp;lt;value&amp;gt;&lt;/code&gt; 在提示中插入一个值。&lt;/li&gt;&#xA;&lt;li&gt;&lt;code&gt;&amp;lt;var&amp;gt;&lt;/code&gt;   声明一个变量。&lt;/li&gt;&#xA;&lt;li&gt;&lt;code&gt;&amp;lt;vxml&amp;gt;&lt;/code&gt;  VoiceXML文档标识。&#xA;下面对VoiceXML2.0元素进行一些简单介绍。&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h2 id=&#34;21-assign&#34;&gt;2.1 &lt;code&gt;&amp;lt;assign&amp;gt;&lt;/code&gt;&lt;/h2&gt;&#xA;&lt;p&gt;给一个声明过的变量赋值。在下面的例子中，&lt;code&gt;&amp;lt;assign&amp;gt;&lt;/code&gt;将“学习VoiceXML”赋值给变量verb。由于&lt;code&gt;&amp;lt;assign&amp;gt;&lt;/code&gt; 的属性expr的值是一个Javascript表达式，用单引号将学习VoiceXML括起来以表示其为字符串而不是变量。下面的例子将输出“我学习 VoiceXML”。&lt;/p&gt;</description>
			</item>
			<item>
				<title>OGNL详解及其解析源码分析</title>
				<link>https://yeecode.top/blog/58/</link>
				<pubDate>Mon, 31 Jan 2022 00:00:00 +0000</pubDate>
				<guid>https://yeecode.top/blog/58/</guid>
				<description>&lt;p&gt;OGNL（Object Graph Navigation Language，中文名为：对象图导航语言）是一种功能强大的表达式语言（Expression Language，简称EL）。通过它，能够完成从集合中选取对象、读写对象的属性、调用对象和类的方法、表达式求值与判断等操作。&lt;/p&gt;&#xA;&lt;p&gt;OGNL应用十分广泛，例如同样是获取Map中某个对象的属性，用Java语言表示出来如下：&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;userMap.get(&amp;#34;user2&amp;#34;).getName();&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;而使用OGNL表达式则为：&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;#user2.name&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;除了简单清晰以外，OGNL有着更高的环境适应性。我们可以将OGNL表达式应用在配置文件、XML文件等处，而只要在解析这些文件时使用OGNL进行解析即可。例如，下面所示的一段XML配置中，&lt;code&gt;test&lt;/code&gt;条件的判断就使用了OGNL表达式。&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-java&#34; data-lang=&#34;java&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt;select id&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;selectUsersByNameOrSchoolName&amp;#34;&lt;/span&gt; parameterMap&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;userParam01&amp;#34;&lt;/span&gt; resultType&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;User&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;&amp;gt;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    select &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt; from &lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;`&lt;/span&gt;user&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;`&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt;where&lt;span style=&#34;color:#f92672&#34;&gt;&amp;gt;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; test&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;name != null&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;&amp;gt;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            name &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;#&lt;/span&gt;{name}&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;/&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;&amp;gt;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; test&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;schoolName != null&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;&amp;gt;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            AND schoolName &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;#&lt;/span&gt;{schoolName}&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;/&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;&amp;gt;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;/&lt;/span&gt;where&lt;span style=&#34;color:#f92672&#34;&gt;&amp;gt;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;/&lt;/span&gt;select&lt;span style=&#34;color:#f92672&#34;&gt;&amp;gt;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;那Java程序如何解析OGNL中的表达式呢？&lt;/p&gt;&#xA;&lt;p&gt;OGNL有Java工具包，只要引入它我们便可以在Java中使用OGNL的功能。这样我们就可以使用Java来解析引入了OGNL的各种文档。在介绍OGNL用法之前，我们先介绍OGNL解析时要接触的三个重要概念：&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;表达式（expression）：是一个带有语法含义的字符串，是整个OGNL的核心内容。通过表达式来确定需要进行的OGNL操作。&lt;/li&gt;&#xA;&lt;li&gt;根对象（root）：可以理解为OGNL的被操作对象。表达式中表示的操作就是针对这个对象展开的。&lt;/li&gt;&#xA;&lt;li&gt;上下文（context）：整个OGNL处理时的上下文环境，该环境是一个Map对象。在进行OGNL处理之前，我们可以传入一个初始化过的上下文环境。&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;例如在下面代码中，Java便使用OGNL完成了根对象信息的读写操作、上下文信息的读写操作。并且，整个操作过程中也支持逻辑表达式的判断等。&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-java&#34; data-lang=&#34;java&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;User user01 &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;new&lt;/span&gt; User(1, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;易哥&amp;#34;&lt;/span&gt;, 18);&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;User user02 &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;new&lt;/span&gt; User(2, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;莉莉&amp;#34;&lt;/span&gt;, 15);&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Map&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt;String, User&lt;span style=&#34;color:#f92672&#34;&gt;&amp;gt;&lt;/span&gt; userMap &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;new&lt;/span&gt; HashMap&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&amp;gt;&lt;/span&gt;();&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;userMap.&lt;span style=&#34;color:#a6e22e&#34;&gt;put&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;user1&amp;#34;&lt;/span&gt;, user01);&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;userMap.&lt;span style=&#34;color:#a6e22e&#34;&gt;put&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;user2&amp;#34;&lt;/span&gt;, user02);&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;// 使用表达式读写根对象中信息的示例&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;// 该示例中要用到的OGNL函数：&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;// getValue(String expression, Object root) ：对root内容执行expression中的操作，并返回结果&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;// 读取根对象的属性值&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Integer age &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; (Integer) Ognl.&lt;span style=&#34;color:#a6e22e&#34;&gt;getValue&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;age&amp;#34;&lt;/span&gt;, userMap.&lt;span style=&#34;color:#a6e22e&#34;&gt;get&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;user1&amp;#34;&lt;/span&gt;));&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;System.&lt;span style=&#34;color:#a6e22e&#34;&gt;out&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;println&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;读取根对象属性，得到age：&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt; age);&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;// 设置根对象的属性值&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Ognl.&lt;span style=&#34;color:#a6e22e&#34;&gt;getValue&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;age = 19&amp;#34;&lt;/span&gt;, userMap.&lt;span style=&#34;color:#a6e22e&#34;&gt;get&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;user1&amp;#34;&lt;/span&gt;));&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;age &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; (Integer) Ognl.&lt;span style=&#34;color:#a6e22e&#34;&gt;getValue&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;age&amp;#34;&lt;/span&gt;, userMap.&lt;span style=&#34;color:#a6e22e&#34;&gt;get&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;user1&amp;#34;&lt;/span&gt;));&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;System.&lt;span style=&#34;color:#a6e22e&#34;&gt;out&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;println&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;设置根对象属性后，得到age：&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt; age);&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;// 使用表达式读写环境中信息的示例&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;// 该示例中要用到的OGNL函数：&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;// getValue(String expression, Map context, Object root) ：在context环境中对root内容执行expression中的操作，并返回结果&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;// 读取环境中的信息&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;String userName2 &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; (String) Ognl.&lt;span style=&#34;color:#a6e22e&#34;&gt;getValue&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;#user2.name&amp;#34;&lt;/span&gt;, userMap, &lt;span style=&#34;color:#66d9ef&#34;&gt;new&lt;/span&gt; Object());&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;System.&lt;span style=&#34;color:#a6e22e&#34;&gt;out&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;println&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;读取环境中的信息，得到user2的name：&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt; userName2);&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;// 读取环境中的信息，并进行判断&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Boolean result &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; (Boolean) Ognl.&lt;span style=&#34;color:#a6e22e&#34;&gt;getValue&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;#user2.name != &amp;#39;丽丽&amp;#39;&amp;#34;&lt;/span&gt;, userMap, &lt;span style=&#34;color:#66d9ef&#34;&gt;new&lt;/span&gt; Object());&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;System.&lt;span style=&#34;color:#a6e22e&#34;&gt;out&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;println&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;读取环境中的信息，并进行判断，得到：&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt; result);&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;// 设置环境中的信息&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Ognl.&lt;span style=&#34;color:#a6e22e&#34;&gt;getValue&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;#user2.name = &amp;#39;小华&amp;#39;&amp;#34;&lt;/span&gt;, userMap, &lt;span style=&#34;color:#66d9ef&#34;&gt;new&lt;/span&gt; Object());&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;String newUserName &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; (String) Ognl.&lt;span style=&#34;color:#a6e22e&#34;&gt;getValue&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;#user2.name&amp;#34;&lt;/span&gt;, userMap, &lt;span style=&#34;color:#66d9ef&#34;&gt;new&lt;/span&gt; Object());&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;System.&lt;span style=&#34;color:#a6e22e&#34;&gt;out&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;println&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;设置环境中的信息后，得到user2的name：&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt; newUserName);&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;上述的运行结果如下所示。&lt;/p&gt;</description>
			</item>
			<item>
				<title>如何使用Java解析XML文档</title>
				<link>https://yeecode.top/blog/56/</link>
				<pubDate>Sun, 07 Nov 2021 00:00:00 +0000</pubDate>
				<guid>https://yeecode.top/blog/56/</guid>
				<description>&lt;p&gt;在前面的文章中，我们介绍了XML文件的规范与使用。而且XML应用非常广泛，在很多的软件中，会使用XML作为配置文档。那这些配置文档是如何被解析的呢？本文我们将参考《通用源码阅读指导书——MyBatis源码详解》一书介绍如何使用Java解析XML文件。&lt;/p&gt;&#xA;&lt;p&gt;前面的文章中我们已经说明XML表述了一种树状结构，并通过给出了XML片段的结构树。而XPath（XML Path Language，即，XML路径语言）作为一种小型的查询语言能够根据XML结构树在树中寻找节点。&lt;/p&gt;&#xA;&lt;p&gt;XPath定义了一组语法，能够从结构树中筛选出满足要求的节点。如果读者对CSS选择器或者jQuery选择器比较熟悉的话，那掌握XPath的语法还是非常简单的，因为这些选择器的语法思路是相通的。&lt;/p&gt;&#xA;&lt;p&gt;例如XML片段如下：&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-java&#34; data-lang=&#34;java&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;?&lt;/span&gt;xml version&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;1.0&amp;#34;&lt;/span&gt; encoding&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;UTF-8&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;?&amp;gt;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt;members&lt;span style=&#34;color:#f92672&#34;&gt;&amp;gt;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt;user type&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;student&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;&amp;gt;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt;id&lt;span style=&#34;color:#f92672&#34;&gt;&amp;gt;&lt;/span&gt;1&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;/&lt;/span&gt;id&lt;span style=&#34;color:#f92672&#34;&gt;&amp;gt;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt;name&lt;span style=&#34;color:#f92672&#34;&gt;&amp;gt;&lt;/span&gt;易哥&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;/&lt;/span&gt;name&lt;span style=&#34;color:#f92672&#34;&gt;&amp;gt;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt;shcool&lt;span style=&#34;color:#f92672&#34;&gt;&amp;gt;&lt;/span&gt;Sunny School&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;/&lt;/span&gt;shcool&lt;span style=&#34;color:#f92672&#34;&gt;&amp;gt;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;/&lt;/span&gt;user&lt;span style=&#34;color:#f92672&#34;&gt;&amp;gt;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt;user type&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;student&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;&amp;gt;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt;id&lt;span style=&#34;color:#f92672&#34;&gt;&amp;gt;&lt;/span&gt;2&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;/&lt;/span&gt;id&lt;span style=&#34;color:#f92672&#34;&gt;&amp;gt;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt;name&lt;span style=&#34;color:#f92672&#34;&gt;&amp;gt;&lt;/span&gt;莉莉&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;/&lt;/span&gt;name&lt;span style=&#34;color:#f92672&#34;&gt;&amp;gt;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt;shcool&lt;span style=&#34;color:#f92672&#34;&gt;&amp;gt;&lt;/span&gt;Garden School&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;/&lt;/span&gt;shcool&lt;span style=&#34;color:#f92672&#34;&gt;&amp;gt;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;/&lt;/span&gt;user&lt;span style=&#34;color:#f92672&#34;&gt;&amp;gt;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;/&lt;/span&gt;members&lt;span style=&#34;color:#f92672&#34;&gt;&amp;gt;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;我们可以通过下表所示的例子来简单了解下XPath的语法。&lt;/p&gt;&#xA;&lt;table&gt;&#xA;&#x9;&lt;thead&gt;&#xA;&#x9;&#x9;&#x9;&lt;tr&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;th&gt;路径表达式&lt;/th&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;th&gt;含义&lt;/th&gt;&#xA;&#x9;&#x9;&#x9;&lt;/tr&gt;&#xA;&#x9;&lt;/thead&gt;&#xA;&#x9;&lt;tbody&gt;&#xA;&#x9;&#x9;&#x9;&lt;tr&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;.&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;当前元素&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&lt;/tr&gt;&#xA;&#x9;&#x9;&#x9;&lt;tr&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;..&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;当前元素的父元素&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&lt;/tr&gt;&#xA;&#x9;&#x9;&#x9;&lt;tr&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;user&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;user元素&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&lt;/tr&gt;&#xA;&#x9;&#x9;&#x9;&lt;tr&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;&lt;code&gt;/user&lt;/code&gt;&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;user根元素&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&lt;/tr&gt;&#xA;&#x9;&#x9;&#x9;&lt;tr&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;&lt;code&gt;user/id &lt;/code&gt;&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;user元素的名为id的直接子元素&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&lt;/tr&gt;&#xA;&#x9;&#x9;&#x9;&lt;tr&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;&lt;code&gt;user//id &lt;/code&gt;&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;user元素的名为id的直接或间接子元素&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&lt;/tr&gt;&#xA;&#x9;&#x9;&#x9;&lt;tr&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;&lt;code&gt;user/id[1]&lt;/code&gt;&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;user元素的名为id的直接子元素中的第一个&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&lt;/tr&gt;&#xA;&#x9;&#x9;&#x9;&lt;tr&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;&lt;code&gt;user/*[1]&lt;/code&gt;&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;user元素的第一个子元素&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&lt;/tr&gt;&#xA;&#x9;&#x9;&#x9;&lt;tr&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;&lt;code&gt;user/id[last()-1]&lt;/code&gt;&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;user元素的名为id的直接子元素中的倒数第二个&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&lt;/tr&gt;&#xA;&#x9;&#x9;&#x9;&lt;tr&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;&lt;code&gt;//user[@type=&#39;student&#39;]&lt;/code&gt;&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;所有type属性值为“student”的user元素&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&lt;/tr&gt;&#xA;&#x9;&#x9;&#x9;&lt;tr&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;&lt;code&gt;//user[id&amp;gt;3]&lt;/code&gt;&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&#x9;&#x9;&lt;td&gt;所有id子元素值大于3的的user元素&lt;/td&gt;&#xA;&#x9;&#x9;&#x9;&lt;/tr&gt;&#xA;&#x9;&lt;/tbody&gt;&#xA;&lt;/table&gt;&#xA;&lt;p&gt;&lt;code&gt;javax.xml.xpath&lt;/code&gt;包提供了强大的XPath解析功能，因此我们可以基于它实现XML的解析。&lt;/p&gt;&#xA;&lt;p&gt;我们可以通过下面的代码解析该XML片段。&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-java&#34; data-lang=&#34;java&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;String resource &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;info.xml&amp;#34;&lt;/span&gt;;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;DocumentBuilderFactory dbf &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; DocumentBuilderFactory.&lt;span style=&#34;color:#a6e22e&#34;&gt;newInstance&lt;/span&gt;();&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;DocumentBuilder db &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; dbf.&lt;span style=&#34;color:#a6e22e&#34;&gt;newDocumentBuilder&lt;/span&gt;();&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Document doc &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; db.&lt;span style=&#34;color:#a6e22e&#34;&gt;parse&lt;/span&gt;(Thread.&lt;span style=&#34;color:#a6e22e&#34;&gt;currentThread&lt;/span&gt;().&lt;span style=&#34;color:#a6e22e&#34;&gt;getContextClassLoader&lt;/span&gt;().&lt;span style=&#34;color:#a6e22e&#34;&gt;getResourceAsStream&lt;/span&gt;(resource));&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;XPathFactory factory &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; XPathFactory.&lt;span style=&#34;color:#a6e22e&#34;&gt;newInstance&lt;/span&gt;();&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;XPath xpath &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; factory.&lt;span style=&#34;color:#a6e22e&#34;&gt;newXPath&lt;/span&gt;();&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;XPathExpression compile &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; xpath.&lt;span style=&#34;color:#a6e22e&#34;&gt;compile&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;/members/user[id=1]&amp;#34;&lt;/span&gt;);&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;System.&lt;span style=&#34;color:#a6e22e&#34;&gt;out&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;println&lt;/span&gt;(compile.&lt;span style=&#34;color:#a6e22e&#34;&gt;evaluate&lt;/span&gt;(doc));&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;得到下图所示的输出&lt;/p&gt;</description>
			</item>
			<item>
				<title>详解XML文件的规范与使用</title>
				<link>https://yeecode.top/blog/55/</link>
				<pubDate>Sat, 16 Oct 2021 00:00:00 +0000</pubDate>
				<guid>https://yeecode.top/blog/55/</guid>
				<description>&lt;p&gt;可扩展标记语言（Extensible Markup Language，简称XML）是一种标记语言。所谓的标记是指计算机所能理解的信息符号，通过标记可以实现软件开发者与计算机之间的信息沟通。我们常见的HTML便是一种标记语言，不过HTML语言中的标签（例如“&lt;code&gt;&amp;lt;h1&amp;gt; &amp;lt;/h1&amp;gt;&lt;/code&gt;”、“&lt;code&gt;&amp;lt;img \&amp;gt;&lt;/code&gt;”等）都是固定的，是不可以扩展的。XML则可以由开发人员自由扩展定义。&lt;/p&gt;&#xA;&lt;p&gt;XML可扩展的一个重要表现就是XML文档的结构是可以自由定义的。定义XML文档可以使用DTD（Document Type Definition，即：文档类型定义），也可以使用XML Schema。不过在介绍DTD和XML Schema之前，我们先了解下XML文档的结构。&lt;/p&gt;&#xA;&lt;p&gt;XML文档中包含众多的节点。节点分为以下几类：元素节点、属性节点、文本节点、文档节点等，在实际指代中，我们可以省略“节点”二字，也可以将以上各类统称“节点”。&lt;/p&gt;&#xA;&lt;p&gt;下面代码给出了一个XML文档。&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-java&#34; data-lang=&#34;java&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;?&lt;/span&gt;xml version&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;1.0&amp;#34;&lt;/span&gt; encoding&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;UTF-8&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;?&amp;gt;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt;members&lt;span style=&#34;color:#f92672&#34;&gt;&amp;gt;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt;user type&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;student&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;&amp;gt;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt;id&lt;span style=&#34;color:#f92672&#34;&gt;&amp;gt;&lt;/span&gt;1&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;/&lt;/span&gt;id&lt;span style=&#34;color:#f92672&#34;&gt;&amp;gt;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt;name&lt;span style=&#34;color:#f92672&#34;&gt;&amp;gt;&lt;/span&gt;易哥&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;/&lt;/span&gt;name&lt;span style=&#34;color:#f92672&#34;&gt;&amp;gt;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt;shcool&lt;span style=&#34;color:#f92672&#34;&gt;&amp;gt;&lt;/span&gt;Sunny School&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;/&lt;/span&gt;shcool&lt;span style=&#34;color:#f92672&#34;&gt;&amp;gt;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;/&lt;/span&gt;user&lt;span style=&#34;color:#f92672&#34;&gt;&amp;gt;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt;user type&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;student&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;&amp;gt;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt;id&lt;span style=&#34;color:#f92672&#34;&gt;&amp;gt;&lt;/span&gt;2&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;/&lt;/span&gt;id&lt;span style=&#34;color:#f92672&#34;&gt;&amp;gt;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt;name&lt;span style=&#34;color:#f92672&#34;&gt;&amp;gt;&lt;/span&gt;莉莉&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;/&lt;/span&gt;name&lt;span style=&#34;color:#f92672&#34;&gt;&amp;gt;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt;shcool&lt;span style=&#34;color:#f92672&#34;&gt;&amp;gt;&lt;/span&gt;Garden School&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;/&lt;/span&gt;shcool&lt;span style=&#34;color:#f92672&#34;&gt;&amp;gt;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;/&lt;/span&gt;user&lt;span style=&#34;color:#f92672&#34;&gt;&amp;gt;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;/&lt;/span&gt;members&lt;span style=&#34;color:#f92672&#34;&gt;&amp;gt;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;文档第一行为XML声明，它声明了XML的版本是1.0，使用的编码是&lt;code&gt;UTF-8&lt;/code&gt;。XML中从一个标签开始（含）到一个标签结束（含）的部分叫作元素节点，例如从第一个“&lt;code&gt;&amp;lt;user&amp;gt;&lt;/code&gt;”到第一个“&lt;code&gt;&amp;lt;/user&amp;gt;&lt;/code&gt;”之间的部分就是一个&lt;code&gt;user&lt;/code&gt;元素节点。元素节点可以有属性节点，例如“&lt;code&gt;type=&amp;quot;student&amp;quot;&lt;/code&gt;”。元素节点可以包含其他元素节点，例如&lt;code&gt;user&lt;/code&gt;元素包含了&lt;code&gt;id&lt;/code&gt;、&lt;code&gt;name&lt;/code&gt;、&lt;code&gt;school&lt;/code&gt;这三个元素节点。元素节点中也可以有文本节点，例如第一个&lt;code&gt;name&lt;/code&gt;元素节点中就包含了文本节点，值为“易哥”。&lt;/p&gt;&#xA;&lt;p&gt;上述XML中，&lt;code&gt;members&lt;/code&gt;元素位于最顶层，因此是根元素。每一个XML文档都必须要有一个根元素。&lt;/p&gt;&#xA;&lt;p&gt;XML文档实际上表述了一棵树。下图展示了上述XML对应的结构树。&lt;/p&gt;&#xA;&lt;p&gt;&lt;img src=&#34;https://yeecode.top/blog/55/pic/xmlTree_hu_e2ef641b5617e9a2.webp&#34; alt=&#34;结构树&#34; width=&#34;900&#34; height=&#34;335&#34; loading=&#34;eager&#34; decoding=&#34;async&#34;&gt;&lt;/p&gt;&#xA;&lt;p&gt;在一个XML文档中，可以存在什么元素以及每个元素是怎样的，这些是由XML文档的定义文件来进行描述的，例如DTD（此类文件的后缀名为dtd）或者XML Schema（此类文件的后缀名为xsd）。&lt;/p&gt;&#xA;&lt;p&gt;以XML Schema文档为例，我们可以使用下面的代码来定义上述XML片段。&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-java&#34; data-lang=&#34;java&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt;xs:schema attributeFormDefault&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;unqualified&amp;#34;&lt;/span&gt; elementFormDefault&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;qualified&amp;#34;&lt;/span&gt; xmlns:xs&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;http://www.w3.org/2001/XMLSchema&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;&amp;gt;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt;xs:element name&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;members&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;&amp;gt;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt;xs:complexType&lt;span style=&#34;color:#f92672&#34;&gt;&amp;gt;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt;xs:sequence&lt;span style=&#34;color:#f92672&#34;&gt;&amp;gt;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt;xs:element maxOccurs&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;unbounded&amp;#34;&lt;/span&gt; name&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;user&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;&amp;gt;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt;xs:complexType&lt;span style=&#34;color:#f92672&#34;&gt;&amp;gt;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt;xs:sequence&lt;span style=&#34;color:#f92672&#34;&gt;&amp;gt;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;              &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt;xs:element name&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;id&amp;#34;&lt;/span&gt; type&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;xs:unsignedByte&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;/&amp;gt;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;              &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt;xs:element name&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;name&amp;#34;&lt;/span&gt; type&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;xs:string&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;/&amp;gt;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;              &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt;xs:element name&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;school&amp;#34;&lt;/span&gt; type&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;xs:string&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;/&amp;gt;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;/&lt;/span&gt;xs:sequence&lt;span style=&#34;color:#f92672&#34;&gt;&amp;gt;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt;xs:attribute name&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;type&amp;#34;&lt;/span&gt; type&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;xs:string&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;/&amp;gt;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;/&lt;/span&gt;xs:complexType&lt;span style=&#34;color:#f92672&#34;&gt;&amp;gt;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;/&lt;/span&gt;xs:element&lt;span style=&#34;color:#f92672&#34;&gt;&amp;gt;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;/&lt;/span&gt;xs:sequence&lt;span style=&#34;color:#f92672&#34;&gt;&amp;gt;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;/&lt;/span&gt;xs:complexType&lt;span style=&#34;color:#f92672&#34;&gt;&amp;gt;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;/&lt;/span&gt;xs:element&lt;span style=&#34;color:#f92672&#34;&gt;&amp;gt;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;/&lt;/span&gt;xs:schema&lt;span style=&#34;color:#f92672&#34;&gt;&amp;gt;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;而使用DTD，则可以用下面的代码来定义。&lt;/p&gt;</description>
			</item>
			<item>
				<title>HTTP协议详解</title>
				<link>https://yeecode.top/blog/25/</link>
				<pubDate>Sun, 26 Jan 2020 00:00:00 +0000</pubDate>
				<guid>https://yeecode.top/blog/25/</guid>
				<description>&lt;h2 id=&#34;1-简介&#34;&gt;1 简介&lt;/h2&gt;&#xA;&lt;p&gt;HTTP是Hyper Text Transfer Protocol（超文本传输协议）的缩写。HTTP协议用于从WWW服务器传输超文本到本地浏览器的传送协议。它可以使浏览器更加高效，使网络传输减少。它不仅保证计算机正确快速地传输超文本文档，还确定传输文档中的哪一部分，以及哪部分内容首先显示(如文本先于图形)等。HTTP是一个应用层协议，由请求和响应构成，是一个标准的客户端服务器模型。HTTP是一个无状态的协议。&lt;/p&gt;&#xA;&lt;p&gt;&lt;img src=&#34;https://yeecode.top/blog/25/pic/007_hu_fbb5d5f485ab9fe.webp&#34; alt=&#34;图片&#34; width=&#34;663&#34; height=&#34;425&#34; loading=&#34;lazy&#34; decoding=&#34;async&#34;&gt;&lt;/p&gt;&#xA;&lt;h2 id=&#34;11-工作流程&#34;&gt;1.1 工作流程&lt;/h2&gt;&#xA;&lt;p&gt;一次HTTP操作称为一个事务，其工作过程可分为四步：&lt;/p&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;首先客户机与服务器需要建立连接。只要单击某个超级链接，HTTP的工作开始。&lt;/li&gt;&#xA;&lt;li&gt;建立连接后，客户机发送一个请求给服务器，请求方式的格式为：统一资源标识符（URL）、协议版本号，后边是MIME信息包括请求修饰符、客户机信息和可能的内容。&lt;/li&gt;&#xA;&lt;li&gt;服务器接到请求后，给予相应的响应信息，其格式为一个状态行，包括信息的协议版本号、一个成功或错误的代码，后边是MIME信息包括服务器信息、实体信息和可能的内容。&lt;/li&gt;&#xA;&lt;li&gt;客户端接收服务器所返回的信息通过浏览器显示在用户的显示屏上，然后客户机与服务器断开连接。 如果在以上过程中的某一步出现错误，那么产生错误的信息将返回到客户端，有显示屏输出。对于用户来说，这些过程是由HTTP自己完成的，用户只要用鼠标点击，等待信息显示就可以了。&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;h2 id=&#34;12-http协议特点&#34;&gt;1.2 HTTP协议特点&lt;/h2&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;支持客户/服务器模式。支持基本认证和安全认证。&lt;/li&gt;&#xA;&lt;li&gt;简单快速：客户向服务器请求服务时，只需传送请求方法和路径。请求方法常用的有GET、HEAD、POST。每种方法规定了客户与服务器联系的类型不同。由于HTTP协议简单，使得HTTP服务器的程序规模小，因而通信速度很快。&lt;/li&gt;&#xA;&lt;li&gt;灵活：HTTP允许传输任意类型的数据对象。正在传输的类型由Content-Type加以标记。&#xA;HTTP 0.9和1.0使用非持续连接：限制每次连接只处理一个请求，服务器处理完客户的请求，并收到客户的应答后，即断开连接。采用这种方式可以节省传输时间。HTTP 1.1使用持续连接：不必为每个web对象创建一个新的连接，一个连接可以传送多个对象。&lt;/li&gt;&#xA;&lt;li&gt;无状态：HTTP协议是无状态协议。无状态是指协议对于事务处理没有记忆能力。缺少状态意味着如果后续处理需要前面的信息，则它必须重传，这样可能导致每次连接传送的数据量增大。&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h2 id=&#34;2-http11的新机制&#34;&gt;2 HTTP1.1的新机制&lt;/h2&gt;&#xA;&lt;p&gt;HTTP/1.1 版本发布，只比 1.0 版本晚了半年。它进一步完善了 HTTP 协议，一直用到了20年后的今天，直到现在还是最流行的版本。&lt;/p&gt;&#xA;&lt;h2 id=&#34;21-持久连接&#34;&gt;2.1 持久连接&lt;/h2&gt;&#xA;&lt;p&gt;1.1 版的最大变化，就是引入了持久连接（persistent connection），即TCP连接默认不关闭，可以被多个请求复用，不用声明Connection: keep-alive。客户端和服务器发现对方一段时间没有活动，就可以主动关闭连接。不过，规范的做法是，客户端在最后一个请求时，发送&lt;code&gt;Connection: close&lt;/code&gt;，明确要求服务器关闭TCP连接。&lt;/p&gt;&#xA;&lt;h2 id=&#34;22-管道机制&#34;&gt;2.2 管道机制&lt;/h2&gt;&#xA;&lt;p&gt;1.1 版还引入了管道机制（pipelining），即在同一个TCP连接里面，客户端可以同时发送多个请求。这样就进一步改进了HTTP协议的效率。&lt;/p&gt;&#xA;&lt;p&gt;举例来说，客户端需要请求两个资源。以前的做法是，在同一个TCP连接里面，先发送A请求，然后等待服务器做出回应，收到后再发出B请求。管道机制则是允许浏览器同时发出A请求和B请求，但是服务器还是按照顺序，先回应A请求，完成后再回应B请求。&lt;/p&gt;&#xA;&lt;p&gt;但是同一个TCP连接里面，所有的数据通信是按次序进行的。服务器只有处理完一个回应，才会进行下一个回应。要是前面的回应特别慢，后面就会有许多请求排队等着。这称为&amp;quot;队头堵塞&amp;quot;（Head-of-line blocking）。&lt;/p&gt;&#xA;&lt;p&gt;为了避免这个问题，只有两种方法：一是减少请求数，二是同时多开持久连接。这导致了很多的网页优化技巧，比如合并脚本和样式表、将图片嵌入CSS代码、域名分片（domain sharding）等等。如果HTTP协议设计得更好一些，这些额外的工作是可以避免的。&lt;/p&gt;&#xA;&lt;h2 id=&#34;23-content-length字段&#34;&gt;2.3 Content-Length字段&lt;/h2&gt;&#xA;&lt;p&gt;一个TCP连接现在可以传送多个回应，势必就要有一种机制，区分数据包是属于哪一个回应的。这就是Content-length字段的作用，声明本次回应的数据长度。&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;Content-Length: 3295&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;上面代码告诉浏览器，本次回应的长度是3295个字节，后面的字节就属于下一个回应了。&lt;/p&gt;&#xA;&lt;p&gt;在1.0版中，Content-Length字段不是必需的，因为浏览器发现服务器关闭了TCP连接，就表明收到的数据包已经全了。&lt;/p&gt;&#xA;&lt;p&gt;使用Content-Length字段的前提条件是，服务器发送回应之前，必须知道回应的数据长度。对于一些很耗时的动态操作来说，这意味着，服务器要等到所有操作完成，才能发送数据，显然这样的效率不高。更好的处理方法是，产生一块数据，就发送一块，采用&amp;quot;流模式&amp;quot;（stream）取代&amp;quot;缓存模式&amp;quot;（buffer）。&lt;/p&gt;&#xA;&lt;p&gt;因此，1.1版规定可以不使用Content-Length字段，而使用&amp;quot;分块传输编码&amp;quot;（chunked transfer encoding）。只要请求或回应的头信息有Transfer-Encoding字段，就表明回应将由数量未定的数据块组成。&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;Transfer-Encoding: chunked&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;每个非空的数据块之前，会有一个16进制的数值，表示这个块的长度。最后是一个大小为0的块，就表示本次回应的数据发送完了。&lt;/p&gt;&#xA;&lt;h2 id=&#34;24-其他改进&#34;&gt;2.4 其他改进&lt;/h2&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;1.1版还新增了许多动词方法：PUT、PATCH、HEAD、 OPTIONS、DELETE。&lt;/li&gt;&#xA;&lt;li&gt;另外，客户端请求的头信息新增了Host字段，用来指定服务器的域名。有了Host字段，就可以将请求发往同一台服务器上的不同网站，为虚拟主机的兴起打下了基础。&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;接下来，我们详细介绍1.1版本的相关规范。&lt;/p&gt;&#xA;&lt;h2 id=&#34;3-客户端请求&#34;&gt;3 客户端请求&lt;/h2&gt;&#xA;&lt;p&gt;发出的请求具体格式如下：&lt;/p&gt;&#xA;&lt;p&gt;&lt;img src=&#34;https://yeecode.top/blog/25/pic/001_hu_7cff4a9386d84dca.webp&#34; alt=&#34;图片&#34; width=&#34;625&#34; height=&#34;239&#34; loading=&#34;lazy&#34; decoding=&#34;async&#34;&gt;&lt;/p&gt;</description>
			</item>
	</channel>
</rss>
