XML允许创作者定义自己的标签,因其灵活的特性让其难以编写和解析。因此必须使用某种模式来约束其结构。目前最流行的这种模式有两种:DTD和SCHEMA,而后者以其独特的优势即将取代DTD模式,目前只是过渡时期。XML教程请参考这里

为什么要用Schema

DTD 的局限性

  • DTD不遵守XML语法(写XML文档实例时候用一种语法,写DTD的时候用另外一种语法)
  • DTD数据类型有限(与数据库数据类型不一致)
  • DTD不可扩展
  • DTD不支持命名空间(命名冲突)

.Schema的新特性

  • Schema基于XML语法
  • Schema可以用能处理XML文档的工具处理
  • Schema大大扩充了数据类型,可以自定义数据类型
  • Schema支持元素的继承—Object-Oriented’
  • Schema支持属性组

每设计一个模式(DTD或Schema),都对应一种新的标记语言,比如使用xhtml1-strict.dtd诞生了html。基于DTD即将被Schema取代,本篇只讨论Schema模式。Schema教程请参考这里

Schema验证XML

note.xml(d:\MyTemp\xml\note.xml)

<?xml version="1.0"?>
<note xmlns="http://www.oseye.net" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.oseye.net note.xsd"> <to>George</to>
<from>John</from>
<heading>Reminder</heading>
<body>Don't forget the meeting!</body>
</note>

note.xsd(d:\MyTemp\xml\note.xsd)

<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.oseye.net" xmlns="http://www.oseye.net"
elementFormDefault="qualified"> <xs:element name="note">
<xs:complexType>
<xs:sequence>
<xs:element name="to" type="xs:string" />
<xs:element name="from" type="xs:string" />
<xs:element name="heading" type="xs:string" />
<xs:element name="body" type="xs:string" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>

代码解释:

xmlns:xs="http://www.w3.org/2001/XMLSchema"

显示 schema 中用到的元素和数据类型来自命名空间 "http://www.w3.org/2001/XMLSchema"。同时它还规定了来自命名空间 "http://www.w3.org/2001/XMLSchema" 的元素和数据类型应该使用前缀 xs。

targetNamespace="http://www.oseye.net" 

显示被此 schema 定义的元素 (note, to, from, heading, body) 来自命名空间: "http://www.oseye.net"。

xmlns="http://www.oseye.net" 

指出默认的命名空间是 "http://www.oseye.net"。

elementFormDefault="qualified" 

指出任何 XML 实例文档所使用的且在此 schema 中声明过的元素必须被命名空间限定。

App.java

package net.oseye.SchemaXML;

import java.io.File;

import javax.xml.transform.stream.StreamSource;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;
import javax.xml.validation.Validator; import org.xml.sax.ErrorHandler;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
/**
* xml的schema验证器
* @author oseye.net
*/
public class App {
public static void main(String[] args) throws Exception {
if (args.length < 2) {
System.out.print("usage:cmd xsdfile xmlfile");
System.exit(0);
}
SchemaFactory schemaFactory = SchemaFactory
.newInstance("http://www.w3.org/2001/XMLSchema"); Schema schema = schemaFactory.newSchema(new File(args[0]));
Validator validator = schema.newValidator();
validator.setErrorHandler(new ErrorHandler() { public void warning(SAXParseException exception)
throws SAXException {
System.out.println("警告:" + exception);
} public void fatalError(SAXParseException exception)
throws SAXException {
System.out.println("致命:" + exception);
} public void error(SAXParseException exception) throws SAXException {
System.out.println("错误:" + exception); }
});
validator.validate(new StreamSource(new File(args[1])));
}
}

PS:你或许对“SchemaFactory.newInstance(String schemaLanguage) ”的参数模式语言有疑问,这里摘录JDK文档中的描述:

模式语言
此规范使用名称空间 URI 来指定模式语言。下表显示了此规范定义的值。
要遵守此规范,实现只需支持 W3C XML 模式 1.0 即可。但是,如果实现选择支持其他模式语言,那么它必须遵守此规范中所描述的相关行为。
此处未列出的模式语言应引用它们自己的 URI 来表示它们本身。SchemaFactory 类能够在运行时定位其他模式语言的其他实现。
注意,因为 XML DTD 与解析过程有紧密联系,并对解析过程产生很大影响,因此不能将 DTD 验证定义为与解析无关的过程。出于此原因,此规范不定义 XML DTD 的语义。这并不限制实现者以他们了解的合适方式来实现它,但这里提醒用户,此接口上实现的任何 DTD 验证必然偏离 XML 1.0 中所定义的 XML DTD 语义。
值:XMLConstants.W3C_XML_SCHEMA_NS_URI ("http://www.w3.org/2001/XMLSchema"),表示的语言是:W3C XML Schema 1.0;
值:XMLConstants.RELAXNG_NS_URI ("http://relaxng.org/ns/structure/1.0"),表示的语言是:RELAX NG 1.0;

执行

java net.oseye.SchemaXML.App d:\MyTemp\xml\note.xsd d:\MyTemp\xml\note.xml

没有任何的输出,说明是验证通过的,如果我们把note.xml修改成这样:

<?xml version="1.0"?>
<note xmlns="http://www.oseye.net" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.oseye.net note.xsd"> <name>George</name>
<from>John</from>
<heading>Reminder</heading>
<body>Don't forget the meeting!</body>
</note>

执行验证将输出:

错误:org.xml.sax.SAXParseException; systemId: file:/d:/MyTemp/xml/note.xml; lin
eNumber: 5; columnNumber: 8; cvc-complex-type.2.4.a: 发现了以元素 'name' 开头的
无效内容。应以 '{"http://www.oseye.net":to}' 之一开头。

你也能从中看到了to是使用了默认命名空间的作用。

命名空间

上面提到了命名,其实命名空间这个东东最难理解,难以理解的原因是因为它是URL,其实这个URL完全可以不用URL来表示,及时使用URL也完全可以是不可用的,因为它只是一个标示。标准建议使用URL,只是为了方便其唯一性。

上文说到,每设计一个模式(DTD或Schema),都对应一种新的标记语言。在各种各样的XML实例标记语言如雨后春笋般不断涌现的过程中,将会产生这样的一种应用需求,即在一个XML文档中,包含由多个DTD描述的元素。这个想法显然是达到“物尽其用”的一个好办法,它帮助我们最大程度低利用了现有的资源。

但是,这就造成了XML元素的冲突,如在一个XML文档中有两个table元素,而他们表达的含义却不同,前者表示表格,后者表示家具:

<?xml version="1.0"?>
<root>
<table>
<tr>
<td>Apples</td>
<td>Bananas</td>
</tr>
</table>
<table>
<name>African Coffee Table</name>
<width>80</width>
<length>120</length>
</table>
</root>

我们可以使用前缀来区分

<?xml version="1.0"?>
<root>
<h:table>
<h:tr>
<h:td>Apples</h:td>
<h:td>Bananas</h:td>
</h:tr>
</h:table>
<f:table>
<f:name>African Coffee Table</f:name>
<f:width>80</f:width>
<f:length>120</f:length>
</f:table>
</root>

前缀太简短,不易阅读,于是标准规定了命名空间来和前缀一同使用,既易阅读也不会太繁冗,名空间格式:

xmlns:namespace-prefix="namespaceURI"

当命名空间被定义在元素的开始标签中时,所有带有相同前缀的子元素都会与同一个命名空间相关联。

PS:用于标示命名空间的地址不会被解析器用于查找信息。其惟一的作用是赋予命名空间一个惟一的名称。不过,很多公司常常会作为指针来使用命名空间指向实际存在的网页,这个网页包含关于命名空间的信息。

<?xml version="1.0"?>
<root>
<h:table xmlns:h="http://www.w3.org/TR/html4/">
<h:tr>
<h:td>Apples</h:td>
<h:td>Bananas</h:td>
</h:tr>
</h:table>
<f:table xmlns:f="http://www.w3school.com.cn/furniture">
<f:name>African Coffee Table</f:name>
<f:width>80</f:width>
<f:length>120</f:length>
</f:table>
</root>

如果不使用前缀则是默认命名空间,命名空间有其作用域的,具体细节请参考XML文档。然后你可以定义一个XSD或多个XSD来验证此XML格式是否正确,如何编写XSD,请参考这里

schemaLocation 属性 XML 架构实例命名空间 http://www.w3.org/2001/XMLSchema-instance(通常与前缀 xsi 关联)定义仅适用于 XML 实例文档而适用于 XML 架构文档区别于 XML 架构命名空间 http://www.w3.org/2001/XMLSchema 定义 schemaLocation 属性。
xsi:schemaLocation 属性提供种方法来查找 XML 实例文档定义命名空间 XML 架构定义值用空白分隔统资源标识符 (URI) 对列表其每对 URI 都依次包含命名空间及该命名空间 XML 架构定义(通常 .xsd 文件)位置
当 XML 文档反序列化对象时XmlSerializer 类忽略 xsi:schemaLocation 属性验证 XML 文档时XmlValidatingReader 类使用该属性值来获取 XML 架构定义

本文主要是针对《使用Spring构建RMI服务器和客户端》遇到问题后的延伸,如果你遇到了什么问题,欢迎留言交流。

Java使用Schema模式对XML验证的更多相关文章

  1. Java工具类——通过配置XML验证Map

    Java工具类--通过配置XML验证Map 背景 在JavaWeb项目中,接收前端过来的参数时通常是使用我们的实体类进行接收的.但是呢,我们不能去决定已经搭建好的框架是怎么样的,在我接触的框架中有一种 ...

  2. java+反射+多线程+生产者消费者模式+读取xml(SAX)入数据库mysql-【费元星Q9715234】

    java+反射+多线程+生产者消费者模式+读取xml(SAX)入数据库mysql-[费元星Q9715234] 说明如下,不懂的问题直接我[费元星Q9715234] 1.反射的意义在于不将xml tag ...

  3. Java面试题 OOAD & UML+XML+SQL+JDBC & Hibernate

    二.OOA/D 与UML 部分:(共6 题:基础2 道,中等难度4 道) 96.UML 是什么?常用的几种图?[基础] 答:UML 是标准建模语言:常用图包括:用例图,静态图(包括类图.对象图和包图) ...

  4. JAVA中使用DOM解析XML文件

    XML是一种方便快捷高效的数据保存传输的格式,在JSON广泛使用之前,XML是服务器和客户端之间数据传输的主要方式.因此,需要使用各种方式,解析服务器传送过来的信息,以供使用者查看. JAVA作为一种 ...

  5. 一张图搞定Java设计模式——工厂模式! 就问你要不要学!

    小编今天分享的内容是Java设计模式之工厂模式. 收藏之前,务必点个赞,这对小编能否在头条继续给大家分享Java的知识很重要,谢谢!文末有投票,你想了解Java的哪一部分内容,请反馈给我. 获取学习资 ...

  6. Java Web开发模式

    一 Java Web开发模式的变迁 1 最初的Java web服务器端编程技术是Servlet,利用Servlet就可以开发出一个Web应用程序. 2 为了解决Servlet缺陷,SUN推出了JSP技 ...

  7. java责任链模式及项目实际运用

    1.前言 上次我们认识了java责任链模式的设计,那么接下来将给大家展示责任链模式项目中的实际运用.如何快速搭建责任链模式的项目中运用. 2.简单技术准备 我们要在项目中使用借助这样的几个知识的组合运 ...

  8. Java的MVC模式简介

    Java的MVC模式简介 MVC(Model View Control)模型-视图-控制器 首先我们需要知道MVC模式并不是javaweb项目中独有的,MVC是一种软件工程中的一种软件架构模式,把软件 ...

  9. 雷林鹏分享:XML 验证

    XML 验证 拥有正确语法的 XML 被称为"形式良好"的 XML. 通过 DTD 验证的XML是"合法"的 XML. 形式良好的 XML 文档 "形 ...

随机推荐

  1. 使用(Drawable)资源———ClipDrawable资源

    ClipDrawable代表从其他位图上截取的一个"图片片段".在XML文件中定义ClipDrawable对象使用<clip.../>元素,该元素的语法为: <? ...

  2. MyBatis中的大于、小于、like等符号写法

    其实就是xml的特殊符号,因为它的配置就是xml,所以可以用下面这种写法转义 < < > > <> <> & & &apos; ...

  3. 关于aop:pointcut的expression配制说明及JoinPoint

    http://blog.csdn.net/wubai250/article/details/8102194 网上其它示例1:<aop:pointcut id="serviceMetho ...

  4. jQuery如何实现点击页面获得当前点击元素

    获得jquery对象: function foo(e){ var obj = $(e.target); }

  5. Docker环境中部署DzzOffice 1.2.5.2

    整体思路: 1.官方获取mysql.php+apache镜像: 2.基于php+apache,创建DzzOffice镜像: 3.启动mysql镜像: 4.启动DzzOffice镜像,链接mysql镜像 ...

  6. [随笔]利用云虚拟机和学校VPN实现校外访问校内站点(反向代理)

    探究背景简介: 大学校内站点一般不对外开放,个人认为原因有二: 一是站点内容受众就是大学师生: 二是站点基本无防御措施,在公网环境下容易发生意外情况. 至于为何不对外开放,不是这篇随笔探讨的重点,利用 ...

  7. MAC的VIMRC

    set nocompatible            " 关闭 vi 兼容模式 syntax on                   " 自动语法高亮 " color ...

  8. venom结合Metasploit绕过360安全卫士

    原理:msfvenom是msfpayload和msfencode的结合体,利用msfvenom生成shellcode,venom生成工具使用了 一些 Veil-Evasion.py, unicorn. ...

  9. C++ 头文件系列(unordered_map、unordered_set)

    简介 很明显,这两个头文件分别是map.set头文件对应的unordered版本. 所以它们有一个重要的性质就是: 乱序 如何乱序 这个unorder暗示着,这两个头文件中类的底层实现----Hash ...

  10. ubuntu 下配置Web服务器

    ubuntu 下配置Web服务器 1.切换管理员身份 终端/文本界面输入命令: su 根据提示输入密码 注: 如果不能使用su 点击查看如何启用su2.安装MySQL5 apt-get install ...