zoukankan      html  css  js  c++  java
  • 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的合法性。

  • 相关阅读:
    分享ASP.NET+jQuery MiniUI后台购物管理
    ASP.NET发送电子邮件
    LINQ学习(三):Where子句
    ASP.NET配置KindEditor文本编辑器
    一步步写自己SqlHelper类库(五):Command对象
    ASP.NET生成静态页面的简单实现
    兼职开发悟出的点点滴滴
    设计模式学习笔记
    if else替代者
    ASP.NET 一生命周期中的额事件
  • 原文地址:https://www.cnblogs.com/beijiguangyong/p/2625697.html
Copyright © 2011-2022 走看看