前言
标记语言是一类非常重要的语言,其中又属HTML和XML使用最为频繁,这两种语言形式上的相似性会造成一定的误解,故此文对两种语言进行对比学习,主要聚焦于XML语法层面。
一、什么是XML和HTML
XML指可扩展性标记语言,扩展性体现在其标签完全由使用者自己定义。它是由W3C推荐的一种数据传输格式。xml文件只是文件的后缀名为.xml的文件。
HTML指超文本标记语言,超文本是指超越文字文本,也就是包括视频、音频、图片在内的文本。html文件只是文件的后缀名为.html的文件。
二、XML和HTML的三个最大不同点
- XML用于数据传输和存储,HTML用于数据展示
- XML的标签只能自定义,HTML的标签是规定好的,不可以自定义
- XML语法要求及其严格,必须是成对标签,HTML语法要求不严格
三、XML语法注意点
-
xml必须有一个根节点包住所有的标签
<root> <lable1> context </lable1> <lable2> context </lable2> </root>
-
xml的标签必须是成对出现,不能有任何的缺失,并且每一对标签的前后两个标签名必须相同
<!--以下是错误写法--> <root> <lable1> context <lable2> context </lable1> </root>
-
xml的标签不可交叉
<!--以下是错误写法--> <root> <a> ddd <b> fff </a> </b> </root>
-
xml的标签名是大小写敏感的
<!--以下是错误写法--> <root> <User> context </user> </root>
-
xml第一行可以加入头文件,可以不加,但是建议加
<?xml version="1.0" encoding="utf-8"?> <!--头文件的开头必须是 ?xml--> <!--头文件的声明必须放在整个xml文件的第一行,否则无法识别--> <!--version属性指定版本,encoding属性指定编码方式,方便后面解码--> <root> <lable1> context </lable1> <lable2> context </lable2> </root>
-
xml的标签中可以加入“属性”,但是基本没人用,要说明的是,属性值必须放在双引号里,并且属性的命名规则为:数字字母下划线,数字不能开头。
<?xml version="1.0" encoding="utf-8"?> <root> <man> <name>成龙</name> <age>68</age> </man> <man> <name age="59">李连杰</name> </man> </root>
-
xml标签之间的内容中有一些字符需要转义,需要转义的字符有五种,转义的方法有两种
第一种转义方法就如以上表格中所示,第二列即为需要转义的字符,第一列为转义时的写法。第二种转义方法是通过CDATA
<?xml version="1.0" encoding="utf-8"?> <root> <!--要输入的文本:如果2>3,那么我们也可以说3<2--> <msg>如果2 > 3,那么我们也可以说3 < 2 </msg> <!--CDATA的使用语法如下--> <!--<![CDATA[……不解析的内容……]]>--> <msg1><![CDATA[如果2>3,那么我们也可以说3<2]]></msg1> </root>
Safari展示结果:
Chrome展示结果:
对于以上两种方法,当特殊字符较少时,使用实体替换;当特殊字符较多时,使用CDATA,其中CDATA必须大写。
四、XML命名空间
由于标签全部由用户自己定义,那么就存在这样的问题:两个不同的xml文档用了相同的标签名,这个时候该如何区分二者呢?对于这种情况,XML处理器无法自动区分,需要编写者在语法上提供区别。
<!--xml_1-->
<table>
<tr>
<td>apple</td>
<td>orange</td>
</table>
<!--xml_2-->
<table>
<width>40cm</width>
<longth>80cm</longth>
<height>76cm</height>
</table>
在以上两个不同的xml文件中,都含有table标签,但是xml_1中是一个水果的表格,xml_2中是一个桌子,那么当同时使用以上两个xml文件的时候就会出现命名冲突。解决方法就是为标签加一个前缀来区分,如下:
<!--xml_1-->
<a:table>
<a:tr>
<a:td>apple</a:td>
<a:td>orange</a:td>
</a:table>
<!--xml_2-->
<b:table>
<b:width>40cm</b:width>
<b:longth>80cm</b:longth>
<b:height>76cm</b:height>
</b:table>
这样做在一定程度上能够解决问题,但还是会有冲突的可能,因为只不过是变了标签名而已,万一有一个xml_3文件中,同样使用了a:table标签,不是又和xml_1冲突了吗。为了解决这个问题,XML标准提供了xmlns(xml namespaces)属性,具体做法如下:
<!--xml_1-->
<a:table xmlns:a="http://www.w3.org/TR/html4/">
<a:tr>
<a:td>apple</a:td>
<a:td>orange</a:td>
</a:table>
<!--xml_2-->
<b:table xmlns:b="http://www.w3school.com.cn/furniture">
<b:width>40cm</b:width>
<b:longth>80cm</b:longth>
<b:height>76cm</b:height>
</b:table>
可以看到,其语法如下:
xmlns:namespace-prefix="namespaceURI"
可以对照这个语法和例子来看,当我们为前缀使用了xmlns属性之后,这个前缀就会和后面的namespaceURI绑定,相当于这个namespaceURI别名。而这个的URI是指同一资源标识符,可以保证前缀之间不相互冲突。
新的问题又出现了,这么写的话好像特别麻烦?也有办法解决。在XML标准中规定,每一个xml文件可以定义一个默认的命名空间,当定义了这个默认命名空间之后,文件中的所有标签在处理器处理的时候会自动加上前缀,无需手动加入。具体如下:
<!--xml_1-->
<table xmlns="http://www.w3.org/TR/html4/">
<tr>
<td>apple</td>
<td>orange</td>
</table>
<!--xml_2-->
<table xmlns="http://www.w3school.com.cn/furniture">
<width>40cm</width>
<longth>80cm</longth>
<height>76cm</height>
</table>
结合例子课件其语法如下:
xmlns="namespaceURI"
但是要注意两点:1. 一个xml文档中只可有一个默认命名空间,也就是此语法只能使用一次;2.定义了默认命名空间之后仍然可以定义其他的命名空间,但是需要手动加前缀。具体如下:
<table xmlns="namespaceURI_1"
xmlns:a="namespaceURI_2"
xsi:b="namespaceURI_3">
</table>
在以上例子中,默认命名空间为namespaceURI_1,另外还定义了前缀a和b。
五、如何检验自己的语法是否正确?
由于xml是用于传输数据的,并非展示数据,想要知道xml写的是否正确该怎么办呢?直接在浏览器打开本地xml文件即可直接运行xml文件,在浏览器打开本地文件可以通过快速开启http本地服务共享文件的方法:这个链接里详细讲了如何建立http服务,我建议通过Python的方法,简洁有效,具体如下。
使用Python工具开启http服务:在终端直接输入如下命令
Python3:
python -m http.server 8000
非Python3:
python -m SimpleHTTPServer 8000
注意,运行之后要保持终端开启。然后直接在浏览器中输入localhost:8000或者127.0.0.1:8000即可访问本地文件。
这里要说明的是,尽管xml是通用的数据传输和存储格式,但是不同的浏览器对相同数据的展示方式是不同的。因此,在不同的浏览器打开相同的xml文件可能会有不同的显示方式。在CDATA语法的例子中,我们将相同的代码放在Safari和Chrome中运行得到了不同形式的输出。