XML简明教程(4)

目录


发展历史

XMLHTML对比之可扩展

XMLHTML对比之语法细节

XML验证之DTD

XML语法结构

XML命名空间

DOM4J读写配置文件

关于SLT

XML验证之DTD


如前面教程中所说的那样,XML的最大作用在于存储、传输以及交换数据。在这期间XML的正确性至关重要,为了保证XML的正确性人们采取了相应的措施。

XML的正确性分为两方面:一方面是XML的语法,一方面是XML的内容。人们把拥有正确语法的 XML 被称为“形式良好”的 XML,对于一个形式良好的XML文档,我们只能保证这个文档的格式符合XML规范,换句话说就是保证XML在语法上没有错误,但是元素与元素的关系,属性的取值是否正确,这些都无法得知。对于一个形式良好的文档,如果仅仅是在有限的应用中使用,例如自己开发的系统中当作配置文件,或者作为数据的存储传输,也许能够很好的满足我们的应用。但如果要让其他用户理解或者系统也能运用你的XML文档,或者进行数据交换,那么必须保证XML为“合法”的。这样就有必要提供一种验证XML机制,目的就是用来保证我们所写的XML文档和别人所写的XML文档其结构是相同的,元素与元素之间的关系是正确的,属性的取值是符合要求的。

这种机制在XML标准中已经为我们提供了,也就是我们前面提到的DTDDocument Type Definition,文档类型定义)。换句话说通过 DTD 可以验证的自己的XML 是否为“合法”的 XML

我们可以直接在XML文档中定义DTD,也可以通过URI引入外部的DTD文件。内部的DTD虽然方便,但是会导致文档本身长度增加传输负担,而且如果多个XML文档要共用一个DTD我们就需要在每一个文档中加入DTD,这是相当繁琐的。所以推荐的做法是将DTD放到一个单独的文件中去定义,在XML文档中通过URI去引用外部的DTD文件。

下面就演示如何用DTD文件来验证XML文件的合法性

test.xml文件代码

 

<?xml version="1.0" encoding="gb2312" standalone="no"?>
<!DOCTYPE student SYSTEM "test.dtd">
<!--这是XML文档-->
<student>
	<name>张三</name>
	<age>24</age>
</student>

 

代码解析:在第二行中将外部的DTD文档引入,用于判断XML是否合法。其中用的路径为相对路径,网上很多XML中引入的DTD是一个URI,无论是相对还是绝对的路径,总之只要XML能找到其对应的DTD就是可行的。

test.dtd文件代码

 

<!ELEMENT student (name,age)>
<!ELEMENT name (#PCDATA)>
<!ELEMENT age (#PCDATA)>
<!ATTLIST student sex (man | woman) 'man'>

 

代码解析:第一行至第三行定义了XML文件中的元素,以及元素之间的关系。在第四行定义了student属性中对sex的限制内容,其默认为man而且只能选取两个值man或者woman

下面开始验证XML的合法性:

 

package ValidateXml;

import java.io.FileNotFoundException;
import java.io.IOException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

public class ValidateXMLDTD {
    
    public static void main(String[] args) {
//       test1XML();
       test2XML();
    }
    
    public static void test1XML() {
        try {
        	InputSource ips=new InputSource();
        	ips.setSystemId("d:\\test.xml");
            DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
            dbf.setValidating(true);
            DocumentBuilder db = dbf.newDocumentBuilder();
            db.parse(ips);
        System.out.println("xml 正确!");
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (ParserConfigurationException e) {
            e.printStackTrace();
        } catch (SAXException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    
    public static void test2XML() {
        try {
            DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
            dbf.setValidating(true);
            DocumentBuilder db = dbf.newDocumentBuilder();
            db.parse(new java.io.FileInputStream("d:\\test.xml"));
        System.out.println("xml 正确!");
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (ParserConfigurationException e) {
            e.printStackTrace();
        } catch (SAXException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

 

代码解析:上面的代码验证XML是否为合法,需要注意的是不要直接将XML读入到输入流中,那样的话会找不到相对路径下的DTD,调用test2XML会报错如下,如果调用test1XML则会正确验证XML。

直接用输入流读入的话XML寻找相对路径会在eclipse的环境下进行寻找DTD,如果用setSystemId进行设置的话会根据XML自己存在的目录中寻找DTD(参看具体解释),很显然后一种方式才是我们想要的。

通过DTD我们可以很容易的判断要验证的XML是否符合我们所定义的规范(元素之间的关系,属性的取值是否正确)但是如果要验证元素的内容DTD就无能为力了,于是人们研究了新的验证方法——Schema。就像人们远行一样,当对时间要求不苛刻的时候,火车便宜而且安全;当对时间有严格要求的时候,飞机也是不错的选择。根据实际需要改进技术,根据实际需要选择技术。量体裁衣,明智之举。

下一篇博客将简单介绍Schema,以及如何用Schema验证XML的合法性。

posted @ 2012-08-06 08:06  郗晓勇  阅读(286)  评论(0编辑  收藏  举报