我为什么要学习XML?
在编程开发中我们使用XML作为程序之间数据传输的载体,无论这些程序用任何语言编写,运行在任何和平台上,XML都能很好的做到信息的传输。各种框架也使用XML作为配置文件(如spring、mybatis、maven),对XML有个基本的了解和感性的认识是很有必要的。
什么是XML?
- XML指可扩展标记语言(EXtensible Markup Language)。
- XML是很像于HTML的标记性语言。
- XML的宗旨是用来传输和存储数据,而HTML是用来显示数据。
- XML没有预定义的标签,标签由XML文档的作者自定义。
- XML具有自我描述性。
- XML是一种树形接口,从"根"到”叶子“。
- XML是W3C推荐的标准。
XML和HTML的不同之处?
- 首先,目的不同,XML是用于传输和存储数据,HTML是用于显示数据。
- 其次,XML的标签由XML文档作者自定义,HTML标签由W3C预定义的。
- 再次,XML的标签必须是成对的(一个开始标签和结束标签),HTML可以单独单独出现(可以没有结束标签)。
通过下边的事例来直观的认识XML
<note>
<to>Tove</to>
<from>Jani</from>
<heading>Reminder</heading>
<body>Don't forget me this weekend!</body>
</note>
上边的XML具有自我描述性,Tove发给了Jani一条信息,标题是 “Reminder”,内容是 “Dont‘t forget me this weekend!”。但是这个XML没有做任何事情,仅仅是将纯粹的信息包装在了XML中。我们需要编写程序才能解析和传递XML。总之一句话 XML是独立于平台和软件的信息传输工具,XML简化了数据的共享和存储。
XML语法
- 所有的XML元素必须有一个开始标签和一个结束标签,必须是成对出现。
- XML对大小写敏感。<a></a>和<A></A>是两个元素。
- XML必须有个根元素,这个元素是所有元素的父元素。
- XML的元素属性值必须用加引号,如:<name type="string"><name>。
- XML使用<!-- 我是注释 -->作为注释,和HTML注释是一样的。
- XML中不会将多个连续的空格合并成一个空格,而HTML会这样做。
- XML中以LF来存储换行。ps:这个知识点没有弄明白
- 使用实体引用来代替特殊字符。
如果元素的文字内容包括“<”,会发生错误,因为解析器会将"<"作为新元素的开始来识别。“&”会被解析成实体引用的开始。这样的XML会产生错误:
<message>if salary < 1000 then</messag>
为了避免这个错误,请使用实体字符来代替“<”字符:
注释:在 XML 中,只有字符 "<" 和 "&" 确实是非法的。大于号是合法的,但是用实体引用来代替它是一个好习惯。
<message>if salary < 1000 then</message>
在XML中有5个预定义的实体引用:
< | < | less than |
> | > | greater than |
& | & | ampersand |
' | ' | apostrophe |
" | " | quotation mark |
注释:在 XML 中,只有字符 "<" 和 "&" 确实是非法的。大于号是合法的,但是用实体引用来代替它是一个好习惯。
什么是XML元素?
XML元素是指从开始标签直到结束标签的部分。XML元素可以包含属性、文本内容和其它元素,或者以上混合。在给出的XML事例中<note>和</note>被称为开始和结束标签,<note></note>和之间的内容被成为元素。
XML的命名规则
- 可以包含字母、数字和其它字符。
- 不能已符号和数组开头。
- 名称不能包含空格。
- 不能已XML或xml开头。
因为xml用于声明xml文档,“
<?xml version="1.0" encoding="ISO-8859-1"?>”表示xml文档的版本是1.0,字符编码是ISO-8859-1。
验证XML的两种方式
有些时候我们需要验证XML是否符合一定的结构规则,这个时候我们可以使用XML DTD和XML Schema来验证。比如我们想验证上面的XML中note只能包含to、form、heading、body元素,不能包含其它元素。
DTD验证XML
Note.xml文件内容:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE note SYSTEM "Note.dtd">
<note>
<to>Tove</to>
<from>Jani</from>
<heading>Reminder</heading>
<body>Don't forget me this weekend!</body>
</note>
Note.dtd文件内容:
<!ELEMENT note (to,from,heading,body)>
<!ELEMENT to (#PCDATA)>
<!ELEMENT from (#PCDATA)>
<!ELEMENT heading (#PCDATA)>
<!ELEMENT body (#PCDATA)>
<!DOCTYPE root-element SYSTEM "filename">代表引入note.dtd文件来校验note.xml。如果我们在note添加一个元素或删除其中一起元素都会提示错误。注意:在IDE中中才能看见这种错误。
XML Schema校验XML
note.xml
<?xml version="1.0" encoding="UTF-8"?>
<note
xmlns="note_ns"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="note_ns note.xsd">
<to>Tove</to>
<from>Jani</from>
<heading>Reminder</heading>
<body>Don't forget me this weekend!</body>
</note>
note.xsd
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="note_ns"
xmlns="note_ns"
elementFormDefault="qualified">
<xs:element name="note">
<xs:complexType>
<xs:sequence>
<xs:element name="to" type="xs:string"/>
<xs:element name="from" type="xs:string"/>
<xs:element name="heading" type="xs:string"/>
<xs:element name="body" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
像spring、mybatis的配置文件都是使用这种方式校验XML。
XML命名空间
有时候我们需要在一个XML文档中定义相同名称的元素,例如table.xml文件:
table.xml
spring-context.xml
<root>
<table>
<tr>
<td>Apples</td>
<td>Bananas</td>
</tr>
</table>
<table>
<name>African Coffee Table</name>
<width>80</width>
<length>120</length>
</table>
</root>
第一个table代表HTML表格数据,第二个table代表桌子信息,两个table元素完全是两种类型。可以通过XML的命名空间来区分这两种类型。如下:
table.xml
<root xmlns="http://ttt.com" xmlns:h="http://www.table1.com" xmlns:f="http://www.table2.com">
<h:table>
<h:tr>
<h:td>Apples</h:td>
<h:td>Bananas</h:td>
</h:tr>
</h:table>
<f:table>
<f:name>African Coffee Table</f:name>
<f:width>80</f:width>
<f:length>120</f:length>
</f:table>
<a></a>
</root>
xmlns是XML 命名空间属性,语法:
xmlns:namespace-prefix="namespaceURI"命名空间属性被定义在根开始标签或应用这一命名空间的开始标签(也可将xmlns属性定义在table开始标签上),所有带有前缀的子元素都属于这一命名空间。上段的第一个table元素属于h命名空间,第二个table属于f命名空间,xmlns定义了默认的命名空间,就是没有前缀。namespaceURI用于标示命名空间的地址不会被解析器用于查找信息。其惟一的作用是赋予命名空间一个惟一的名称。不过,很多公司常常会作为指针来使用命名空间指向实际存在的网页,这个网页包含关于命名空间的信息。在看一个我们比较熟悉的XML片段。
spring-context.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:task="http://www.springframework.org/schema/task"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:websocket="http://www.springframework.org/schema/websocket"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task.xsd
http://www.springframework.org/schema/websocket http://www.springframework.org/schema/websocket/spring-websocket.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
spring-context.xml文件的beans元素声明了xsi、task、mvc等命名空间。
XML的CDATA区段(CDATA section)
CDATA是指不应该被XML解析器进行解析的文本数据(
Unparsed Character Data)。CDATA的作用是不让解析器去解析区段内的文本数据。XML解析器会默认解析XML文档中的所有文本(PCDATA 指的是被解析的字符数据(Parsed Character Data)),假如我们元素的文本内容是一断 HTML、JavaScript、java、代码,这些代码中通常带有“<”、“&”等XML非法字符,“<”会被解析成开始标签,“&”会被解析成实体引用的开始,用实体引用替换这些字符又非常繁琐。这种情况我们可以把我们的代码放在CDATA区段中,让解析器不去解析段中的文本数据。例如:
<script_tag>
<![CDATA[function add(){docuemnt.wirit("<div></div>");}]]>
</script_tag>
CDATA区段以"<![CDATA["开始,以"]]>"结束。下段XML片段是CDATA区段在mybatis mapping xml文件的应用。
<select id="getWz_Ldzlbhqs" resultType="map" >
select date_format(bug_find_time,'%Y-%m-%d')sj,count(*) count from base_bugs where 1=1
<if test="st != null and st != ''">
<![CDATA[ and bug_find_time >= #{st}]]>
</if>
<if test="et != null and et != ''">
<![CDATA[ and bug_find_time <= #{et} ]]>
</if>
GROUP BY sj order by sj asc
</select>
关于CDATA注意两点:
- CDATA 部分不能包含字符串 "]]>"。也不允许嵌套的 CDATA 部分。
- 标记 CDATA 部分结尾的 "]]>" 不能包含空格或折行。
XML编码
XML编码这里需要注意一点,encoding编码属性值应该与XML文档保存的编码一直,否则会出现乱码或错误。