XML使用总结(二):
·命名空间?
·编码解析?
·数据存储?
·服务器端?
·涉及技术?
一、命名空间
命名空间(namespace)是用来解决或区分不同文档使用同样元素冲突的问题,因为XML编译器无法区分该编译哪个文档。
1、名字冲突
文档1:
<product>
<id>1001</id>
<no>NOC0001</no>
<name>PHP高级设计教程</name>
<price>88.99</price>
<time>2015.12.30</time>
</product>
文档2:
<product>
<id>10001</id>
<no>MSC0001</no>
<name>韩国料理 </name>
<price>128.99</price>
<time>2015.04.30</time>
</product>
正如上面的两个文档,它们使用同样的元素分别描述了书籍和美食,如果它们同时使用的话,编译器无法确认如何处理这类名字冲突,就会发生问题。
2、前缀命名
针对上面的问题,我们可以使用前缀命名来区分两个文档的元素,使编译器能够编译解析,区分对应的XML文档,可如下设置:
文档1:
<book:product>
<book:id>1001</id>
<book:no>NOC0001</no>
<book:name>PHP高级设计教程</name>
<book:price>88.99</price>
<book:time>2015.12.30</time>
</book:product>
文档2:
<food:product>
<food:id>10001</id>
<food:no>MSC0001</no>
<food:name>韩国料理 </name>
<food:price>128.99</price>
<food:time>2015.04.30</time>
</product>
NOTE:
实际上,前缀命名构造了新的文档描述元素,也就是通过一种前缀办法,区分了两个文档中的相同元素标记。
3、命名空间
命名空间的语法:
xmlns:namespace-prefix= "namespaceURI"
注:当命名空间定义在元素的开始标签,那么所有的相同前缀子元素标签都与该命名空间相关联。另外,默认命名空间只需要把namespace-prefix 去掉即可,即xmlns="namespaceURI"。那么上面的两个文档就可以设置为如下:
文档1:
<product xmlns:book="http://www.nsbooks.com/books">
<id>1001</id>
<no>NOC0001</no>
<name>PHP高级设计教程</name>
<price>88.99</price>
<time>2015.12.30</time>
</product>
文档2:
<product xmlns:food="http://www.nsfoods.com/foods">
<id>10001</id>
<no>MSC0001</no>
<name>韩国料理 </name>
<price>128.99</price>
<time>2015.04.30</time>
</product>
注:
我们推荐使用这种方式来定义区分同时使用的不同文档元素,它的优势在于元素的访问以及后期的维护等工作,变得更加简单。另外,namespaceURI为统一资源定位符,是一串可以唯一标志互联网上资源的标记,某些企业会将这个定义为一个可显示的页面,里面显示与该类命名空间相关的信息。
在很多语言中也使用了命名空间的,如Android布局文件XML:
xmlns:android="http://schemas.android.com/apk/res/android"
二、编码解析
1、XML编码
在文档方面,编码问题一直都有关注,在XML中的编码问题主要出现在:
A、文档未指定编码,在平台移植XML或是编辑器编辑保存导致乱码;
B、文档编辑器编码,如果文档的编码与编辑器的编码不同,很容易发生编码不一致的问题,导致乱码或是解析出现问题。
NOTE:
一点建议:
·文档添加编码格式
·确认编辑器的编码
·使用有编码编辑器
·保证文档和编辑器编码相同
2、避免解析
我们知道,默认XML文档中内容都会被解析器解析,但有时候某些内容我们不希望被解析,那么我们可以使用CDATA标记告诉解析器,在我的庇护区段内容不需要您解析。它的语法结构如下:
<![CDATA[
text_statement
]]>
注:
CDATA 部分不能包含字符串"]]>"。也不允许嵌套的 CDATA 部分。
标记 CDATA 部分结尾的 "]]>" 不能包含空格或折行。
也就是,text_statement部分被CDATA保护,不被XML解析器解析。在实际使用时,很多语言代码,例如Java、PHP及JavaScript等,都包含大量的"<"和"&"符号,而我们也知道,在XML中使用这些字符是不允许的,虽然可以使用实体引用来替换,但是这种方式不是很方便,也不利于维护。
XML文档如下:
<producttype>
<product category="PHP">
<id>1001</id>
<no>NOC0001</no>
<name>PHP高级设计教程</name>
<price>88.99</price>
<time>2015.12.30</time>
<discount><![CDATA["7折"]]></discount>
</product>
<product category="JAVA">
<id>1002</id>
<no>NOC0002</no>
<name>JAVA高级开发教程</name>
<price>102.99</price>
<time>2004.03.30</time>
<discount>if 1 <2 then "7折";</discount>
</product>
<product category="WEB">
<id>1003</id>
<no>NOC0003</no>
<name>WEB高级开发教程</name>
<price>78.99</price>
<time>2012.07.30</time>
<discount><script><![CDATA[matchdis = function(p){
if(p >= 0 && p< 2) return "9折";}]]></script>
</discount>
</product>
</producttype>
我们对上面的XML文档解析,结果:
从上图分析,我么可以看到使用了CDATA之后,XML解析器并未对里面的内容进行解析。
NOTE:
一般情况下,CDATA常用在XHTML兼容处理,以及处理在XML中嵌入代码段,限制解析器解析保护的内容,留给其它程序处理该内容。
三、数据存储
XML描述文件可作为文本数据存储的方式,因为它的跨平台一致性较高,并且数据不需要格式转换。在实际使用中,我们经常看到很多配置信息,或是量少的数据通过XML存储,但是在大数据保存时,我们还是要使用数据库的,我们需要针对具体的需求而选择何时的存储方式。
下面我们举个例子,来说明XML怎样构建,数据如何存储到XML中,以及如何解析查看。我们之前在JavaScript中通过DOM解析XML,接下来我们在另一种语言PHP中去生成和解析XML,在PHP默认支持XML的DOM解析器,具体如下(这里使用了PHP开源框架ThinkPHP):
<?PHP
$dom = new \DOMDocument('1.0','utf-8');
// root element
$root =$dom->createElement('producttype');
$element =$dom->appendChild($root);
// child element
$product =$dom->createElement('product');
$product->setAttribute('category','PHP');
$element->appendChild($product);
$eleId =$dom->createElement('id','1001');
$product->appendChild($eleId);
$eleNo =$dom->createElement('no','NOC0001');
$product->appendChild($eleNo);
$eleName =$dom->createElement('name','PHP高级设计教程');
$product->appendChild($eleName);
$elePrice =$dom->createElement('price','88.99');
$product->appendChild($elePrice);
$eleTime =$dom->createElement('time','2015.12.30');
$product->appendChild($eleTime);
$product =$dom->createElement('product');
$product->setAttribute('category','JAVA');
$element->appendChild($product);
$eleId =$dom->createElement('id','1002');
$product->appendChild($eleId);
$eleNo =$dom->createElement('no','NOC0002');
$product->appendChild($eleNo);
$eleName =$dom->createElement('name','JAVA高级开发教程');
$product->appendChild($eleName);
$elePrice =$dom->createElement('price','102.99');
$product->appendChild($elePrice);
$eleTime =$dom->createElement('time','2004.03.30');
$product->appendChild($eleTime);
$product =$dom->createElement('product');
$product->setAttribute('category','WEB');
$element->appendChild($product);
$eleId =$dom->createElement('id','1003');
$product->appendChild($eleId);
$eleNo =$dom->createElement('no','NOC0003');
$product->appendChild($eleNo);
$eleName =$dom->createElement('name','WEB高级开发教程');
$product->appendChild($eleName);
$elePrice =$dom->createElement('price','78.99');
$product->appendChild($elePrice);
$eleTime =$dom->createElement('time','2012.07.30');
$product->appendChild($eleTime);
// save document
$dom->formatOutput = true;
$msg = $dom->save('product_save.xml');
?>
<?xml version="1.0" encoding="utf-8"?>
<producttype>
<product category="PHP">
<id>1001</id>
<no>NOC0001</no>
<name>PHP高级设计教程</name>
<price>88.99</price>
<time>2015.12.30</time>
</product>
<product category="JAVA">
<id>1002</id>
<no>NOC0002</no>
<name>JAVA高级开发教程</name>
<price>102.99</price>
<time>2004.03.30</time>
</product>
<product category="WEB">
<id>1003</id>
<no>NOC0003</no>
<name>WEB高级开发教程</name>
<price>78.99</price>
<time>2012.07.30</time>
</product>
</producttype>
<?PHP
$dom = new \DOMDocument('1.0','utf-8');
// 加载
$dom->load('product_save.xml');
// 遍历
$items =$dom->getElementsByTagName('product');
echo $items;
foreach($items as$item) {
echo $item->nodeValue.'</br>';
}
?>
打印的结果:
从上图可看出,结果与上一篇文章结果相同。好了,XML数据存储就到这,接下来看下服务端XML的处理。
四、服务器端
XML是一种描述文件,可以独立的存放在本机或是服务器端,在本篇文章的第三部分已经使用PHP生成了XML文档,并对其进行解析,同时生成的文档也以文件的形式存放在服务端;而有的时候,我们也会将数据库中读取的数据,写入XML描述问价并返回前端显示,其实过程就是数据库读取数据,然后将数据转换为XML格式,返回给前端,前端获得之后再对XML进行解析并显示,这就是现阶段最为常用的XML使用情景。
五、涉及技术
这里罗列的是与XML相关的技术列表:
1、XML DOM
访问和操作XML的标准文档模型。
2、DTD
用来定义XML文档中合法元素格式的标准。
3、XSLT
XSLT主要用来将XML转换为其它格式的工具,它包含三个部分:
XSLT:把XML转为其它格式的数据;
XSL-FO:格式化XML文档语言;
XPath:在XML文档中导航的语言;
好了,到这里我们已经总计介绍了XML的命名空间、CDATA、编码、服务端使用等内容,如有问题请及时讨论学习,谢谢。