通过 XML Catalog 实现 XML 文件的自动化实时校验


 引言

  XML Catalog 实现了根据 XSD 实时校验 XML 文件的功能。用户不用编写程序,通过少量的配置就可以在编辑 XML 文件的时候得到及时的反馈(需要在 XML 编辑器进行文件的编写),实现了实时的校验。

  然而在实际应用中,由于环境的不同以及 XML 文件本身的不同,手动方式的配置并不能满足需求。比如,作者在实践中发现,在开发环境里手动配置的 XML Catalog 是不能保存在运行环境的。而且,许多实际的 XML 的编写方式并没有采用标准的格式,这也给 XML Catalog 的使用带来了很多的不便。

  本文针对以上问题,通过例子来说明如何通过扩展 XML Catalog 来实现基于 xsd 对 XML 文件的自动化实时校验。

  XML Catalog 介绍

  XML Catalog 是基于 OASIS XML Catalog specification 标准的实现,它提出了一些关于 XML 文件如何引用外部资源的控制。Eclipse 的 WTP 提供了 XML Catalog 的功能,实现利用 schema 对 xml 文件的实时校验功能。XML Catalog 是由来自一个或者多个 catalog 条目文件的条目组成的 xml 文件,其保存了要校验的 xml 文件以及该文件对应的 xsd 文件的映射,在运行时可以自动将它们关联起来,从而实现对 xml 文件的校验。

  下面通过一个例子来说明 XML catalog 的相关概念。

  XML Catalog 相关概念介绍

 <?xml version="1.0"?> 
 <!DOCTYPE catalog 
 PUBLIC "-//OASIS/DTD Entity Resolution XML Catalog V1.0//EN" 
 "http://www.oasis-open.org/committees/entity/release/1.0/catalog.dtd"> 1 
 <catalog xmlns="urn:oasis:names:tc:entity:xmlns:xml:catalog"> 2 
 <group prefer="public" xml:base="file:///usr/share/xml/" > 3 
 <public 
 publicId="-//OASIS//DTD DocBook XML V4.5//EN" 4 
 uri="docbook45/docbookx.dtd"/> 
 <system 
 systemId="http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" 5 
 uri="docbook45/docbookx.dtd"/> 
 <system 
 systemId="docbook4.5.dtd" 6 
 uri="docbook45/docbookx.dtd"/> 
 </group> 
 </catalog> 

  DOCTYPE 表示这个文件是 OASIS XML catalog 文件。如果没有 Internet 连接,那么,整个 DOCTYPE 的声明需要删除或者注释掉。因为 catalog 处理器会尝试从网络去下载 catalog.dtd 文件,显然在没有网络的环境下,处理器因为找不到文件会报错。

  catalog 元素包含了 catalog 的内容和 catalog 的命名空间标识。

  group 元素是一个包装元素,可以设置在这个组里面包含的所有 catalog 条目的属性。属性 prefer="public" 指出 catalog resolver(解析器) 在使用 SYSTEM 标识符之前优先使用 PUBLIC 标识符。属性 xml:base 表明,所有 URI 都是相对这个路径。本例中,uri="docbook45/docbookx.dtd"/ 是个相对路径,绝对路径应该是 file:///usr/share/xml/ docbook45/docbookx.dtd "。

  public 元素将 publicId 映射到 uri 的路径。publicId 是资源的一个唯一标识,通常是该文件的命名空间 .

  system 元素将 systemId 映射到 uri 的路径。systemId 与 publicId 一样,也是资源的唯一标识,通常是资源文件在文件系统的全路径。

  XML Catalog 原理

  XML Catalog 提供了一种重新定位资源的机制,可以将 xml 引用的 artifacts,包括 URI 地址以及 namespace 名重新定位到另一个地址。通常这种机制被用来将远程的引用资源重定位到本地或者 web。XML catalog 就是一个描述外部实体引用和本地缓存的相同实体的映射的文件。

  在实际的开发生产中,xml 文件经常会引用外部的文件,这些文件通常通过 URI 表示,其中以 URL 应用最广。但是如果是绝对的 URL, 那么只有当你的网络能够访问它时才能起作用,如果网络出现问题,那么将不能访问。当是相对 URL 时,例如"../../xml/dtd/docbookx.xml",只有当你的文件系统和定义者一致的时候才能起作用。

  一种解决办法就是通过实体解析器(Entity Resolver)或者是 URI 解析器 (URI Resolver ),解析器可以通过检查资源的 URI 来定位资源。 用户通过配置 xml catalog, 手动的指定 xml 文件引用的 xsd 文件的本地地址,URI 解析器通过 xml catalog 里面的映射,找到对应的 xsd, 最后 xml catalog 处理器通过解析器找到的 xsd 对 xml 进行校验。

  通俗点说,XML catalog 通过命名空间将 xml 文件及其对应的 xsd 文件联系起来,并通过解析器定位 xsd 文件的位置,最后通过处理器进行校验。

  与 javax.xml.validation 通过 xsd 对 xml 进行校验的方法不同,xml catalog 可以通过 Namespace 来校验所有引用这个 xsd 的 xml 文件,从而达到批量校验的效果。例如,a.xml,b.xml,c.xml 都是由 d.xsd 校验,那么只要将 d.xsd 的命名空间配置好,通过该命名空间就可以校验以上三个文件了。

  手动方式配置 XML Catalog

  手动配置 XML Catalog 比较简单也比较容易理解,可以在 Eclipse 的开发环境中直接进行。选择 File -> New -> Other -> Examples -> Editing and Validating XML files,便可以进行配置了。如下图所示:

图 1. 打开 XML Catalog 的配置界面

  从图 1 中可以看到有两种 xml catalog entity , 用户定义的实体及插件的实体。用手动方式生成的配置属于用户配置的实体。

图 2. 新建一个 XML Catalog Entry

  新建一个 XML Catalog Entry 中的 Location 指明了 xsd 文件的位置,在这里我们选择来源于工作空间。

图 3. 从工作空间选择 student.xsd 文件

  选择 OK 以后,XML Catalog Entry 就创建完成了。XML Catalog 会自动填写其他两个属性,如下图所示。

图 4. 完整的 XML Catalog Entry

  如图所示,Location 标签指定了 xsd 的位置,在这里是工作空间的相对路径;Key Type 标签表明了在这里我们使用的是命名空间的名字作为 xml 和 xsd 的关联;Key 标签的值是 xml 命名空间的值。

图 5. 完整的 XML Catalog Entry

  从图 5 中可以看出,新建的 XML Catalog Entry 已经在 User Specified Entries 目录下。图 1 到 4 显示了 XML Catalog 的手动配置步骤。下面,我们在 XML 编辑器里打开一个 xml 文件,看一下 XML Catalog 的功能。

图 6. 正确的 XML 文件

  首先,用 XML 编辑器打开 sample.xml 文件。

图 7. XML Catalog 的实时校验结果

  将 name 为 BB 的学生的 age 标签去调,从图中可以看到在编辑器的右边有一个红色的点,同时在 student 元素下面有个红色的波浪线,提示 student 元素有错