JAXP实现Schema和DTD验证

       在JAXP1.3以前的实现中,进行XML的约束验证都是调用SAXParserFactory或DocumentBuilderFactory对象的setValidating(true)方法来处理的。

       这种方式有许多不足的地方,它要求正在被验证的XML实例文档中必须要显示的引入相关的约束(Schema或DTD文件),这无形之中就产生了XML实例文档与约束之间的耦合。尤其在分布式或中间件技术应用中,往往在客户端提供的信息交换实体的描述中,并不一定会引入相关的约束,而在服务端进行实体处理之前又需要验证客户端发送来的实体描述是否合法。因此在这种情况下,采用这种老的验证方式就无法实现这一点。

 

一、 JAXP验证框架

       JAXP1.3以后推出了一个全新的验证框架,其核心的接口和实现类都主要在javax.xml.validation包中,最常用的有如下几个:

       1)SchemaFactory:创建某种模式(Schema)类型的工厂类。其模式类型需要在其静态的工厂方法newInstance(String schemaLanguage)方法的参数中指出,可用于验证的模式类型在XMLContants中有所提供,分别是XMLConstants.W3C_XML_SCHEMA_NS_URI和XMLConstants.RELAXNG_NS_URI。也就是说,SchemaFactory能用于Shchema和RELAX NG验证;

       2)Schema:表示某种验证模式的对象;

       3)Validator:验证器。

       结合如上所述的三个核心类,其验证的一般步骤如下:

       1)创建某种模式类型的工厂类;

       2)指定模式的资源并调用工厂对象的newSchema()后获取Schema对象;

       3)从Schema对象中生成验证器;

       4)指定需要被验证的实例资源并调用验证器的validate()方法。

 

       方式一:利用Validator对象进行显示验证

package com.daniele.appdemo.xml.jaxp.validation;

import java.io.File;
import java.io.IOException;

import javax.xml.XMLConstants;
import javax.xml.transform.Source;
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.SAXException;


/**
 * <p>XML Schema约束验证测试类</p> 
 * @author  <a href="mailto:code727@gmail.com">Daniele</a>
 * @version 1.0.0, 2013-7-14
 * @see     
 * @since   AppDemo1.0.0
 */
public class SchemaValidationTest {

	public static void main(String[] args) throws Exception {
		SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
		File schemaSource = new File("resource/xml/schema/schema_test_nns.xsd");
		try {
			Schema schema = factory.newSchema(schemaSource);
			// 从模式中生成验证器
			Validator validator = schema.newValidator();
			// 如果用于验证的Schema文件中定义了命名空间,则被验证的XML实例文件中必须要引用相同的空间
			Source source = new StreamSource(new File("resource/xml/schema/schema_test_copy.xml"));
			validator.validate(source);
			System.out.println("XML有效!");
		} catch (SAXException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} 
	}

}      

 

      除了上述方式外,还可以将Schema对象与某一类型的JAXP解析器工厂(DocumentBuilderFactory或SAXParserFactory)建立联系后, 再让工厂后续创建的解析器在解析XML实例的过程中,隐式的进行验证。

 

       方式二:解析器隐式验证

package com.daniele.appdemo.xml.jaxp.validation;

import java.io.File;
import java.io.IOException;

import javax.xml.XMLConstants;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;

import org.xml.sax.SAXException;


/**
 * <p>XML Schema约束验证测试类</p> 
 * @author  <a href="mailto:code727@gmail.com">Daniele</a>
 * @version 1.0.0, 2013-7-14
 * @see     
 * @since   AppDemo1.0.0
 */
public class SchemaValidationTest {

	public static void main(String[] args) throws Exception {
		SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
		File schemaSource = new File("resource/xml/schema/schema_test_nns.xsd");
		try {
			Schema schema = factory.newSchema(schemaSource);
			DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
			builderFactory.setSchema(schema);
			DocumentBuilder builder = builderFactory.newDocumentBuilder();
			builder.parse(new File("resource/xml/schema/schema_test_copy.xml"));
			System.out.println("XML有效!");
		} catch (SAXException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} catch (ParserConfigurationException e) {
			e.printStackTrace();
		} 
	}

}

二、验证错误后的处理

       在上述方式一中,当执行validate()后,如果发现被验证的实例不符合约束规范,则会抛出SAXException异常,从而被后续对应的catch块所捕获并在控制台中简单的显示出异常信息。如果需要集中处理显示出更多精确详细的异常信息,则直接在这里的catch块中进行显然是不合适的。

       在方式二中更为严重的问题是:当不符合约束规范时,parse()方法只是简单的显示一个错误信息,将不会抛出异常,因此不会被SAXException对应的catch块所捕获,从而仍然会提示“XML有效!”。

       为了解决方式一中集中处理错误和方式二中严重缺陷的问题,这时就需要用到org.xml.sax.ErrorHandler,它是一个接口,其作用在于当进行SAX解析的过程中,如果发生warning、error或

fatalError级别的错误时,则会回调此接口中相关的同名方法,用户需要提供一个实现类,实现对这三种错误类型的处理细节。

package com.daniele.appdemo.xml.sax.handler;

import org.xml.sax.ErrorHandler;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;

/**
 * <p>SAX错误处理器示例类</p> 
 * @author  <a href="mailto:code727@gmail.com">Daniele</a>
 * @version 1.0.0, 2013-6-18
 * @see     
 * @since   AppDemo1.0.0
 */
public class SAXExampleErrorHandler implements ErrorHandler {

	/**
	 * <p>解析过程中遇到警告性错误时被触发</p> 
	 * @author <a href="mailto:code727@gmail.com">Daniele</a> 
	 * @param exception:SAXParseException对象,封装了异常产生时的所在行号和信息
	 * @throws SAXException:当遇到警告性错误要求停止解析时,可直接向上抛出此异常
	 * @since AppDemo1.0.0 
	 */
	public void warning(SAXParseException exception) throws SAXException {
		StringBuffer message = new StringBuffer();
		message.append("解析到第").append(exception.getLineNumber())
				.append("行时发生如下警告:\n").append("messge:")
				.append(exception.getMessage());
		System.out.println(message);
	}

	/**
	 * <p>解析过程中遇到可恢复性错误(如不符合约束规则)时被触发</p> 
	 * @author <a href="mailto:code727@gmail.com">Daniele</a> 
	 * @param exception:SAXParseException对象,封装了异常产生时的所在行号和信息
	 * @throws SAXException: 当遇到可恢复性错误要求停止解析时,可直接向上抛出此异常
	 * @since AppDemo1.0.0 
	 */
	public void error(SAXParseException exception) throws SAXException {
		StringBuffer message = new StringBuffer();
		message.append("解析到第").append(exception.getLineNumber())
				.append("行时发生如下错误:\n").append("messge:")
				.append(exception.getMessage());
		throw new SAXException(message.toString());
	}

	/**
	 * <p>解析过程中遇到不可恢复的致命错误(如不符合XML文档的基本规则)时被触发</p> 
	 * @author <a href="mailto:code727@gmail.com">Daniele</a> 
	 * @param exception:SAXParseException对象,封装了异常产生时的所在行号和信息
	 * @throws SAXException:当遇到不可恢复的严重错误要求停止解析时,可直接向上抛出此异常
	 * @since AppDemo1.0.0 
	 */
	public void fatalError(SAXParseException exception) throws SAXException {
		StringBuffer message = new StringBuffer();
		message.append("解析到第").append(exception.getLineNumber())
				.append("行时发生如下致命错误:\n").append("messge:")
				.append(exception.getMessage());
		throw new SAXException(message.toString());
	}

}

       这里需要重点关注的是error方法,因为验证错误一般都属于这类级别的。在此方法的最后一步抛出SAXException,其目的在于一旦发生错误就让解析器停止解析过程,从而可以解决方式二所述的缺陷并且可以在SAXException的catch块中捕获自定义的异常信息。

      上述实现类定义好后,就需要在验证或解析之前,设置这个错误处理器,可以设置错误处理器的对象有如下几种:

       1)SchemaFactory;

       2)Validator;

       3)DocumentBuilder;

       4)SAXParser;

       其中,SchemaFactory是全局的,即后续创建的schema所生成的Validator对象都采用这个全局的处理器来处理验证错误时的逻辑。另外,如果是用SAXParser对象来进行,则上述自定义的错误处理器就应该修改为通过继承org.xml.sax.helpers.DefaultHandler的方式来实现,因为它是在调用parse()方法时传递一个DefaultHandler对象来进行的,而DefaultHandler实现了org.xml.sax.ErrorHandler接口。例如:

       schemaFactory.setErrorHandler(new SAXExampleErrorHandler());   或

       saxParser.parse(source,new SAXExampleErrorHandler());

 

三、DTD验证       

SchemaFactory目前并不支持DTD的验证,当我们执行SchemaFactory.newInstance(XMLConstants.XML_DTD_NS_URI)时将会抛出java.lang.IllegalArgumentException。

       对于DTD验证,采用原有的验证方式,启用JAXP相关解析器工厂类的验证功能即可。

package com.daniele.appdemo.xml.jaxp.validation;

import java.io.File;
import java.io.IOException;

import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.xml.sax.SAXException;

import com.daniele.appdemo.xml.sax.handler.SAXExampleHandler;


/**
 * <p>XML DTD约束验证测试类</p> 
 * @author  <a href="mailto:code727@gmail.com">Daniele</a>
 * @version 1.0.0, 2013-7-16
 * @see     
 * @since   AppDemo1.0.0
 */
public class DTDValidationTester {

   public static void main(String[] args) throws ParserConfigurationException, IOException, SAXException {
		
	SAXParserFactory factory = SAXParserFactory.newInstance();
	//  这里只需开启相关解析工厂的验证功能,并在后续的解析过程中隐式的执行验证
	factory.setValidating(true);
	SAXParser parser = factory.newSAXParser();
	parser.parse(new File("resource/xml/dtd/dtd_test.xml"), new SAXExampleHandler());
   }

}

       在XML1.0的规范中,没有考虑过要使用DTD之外的方式进行验证。即XML1.0规范硬性规定使用DTD进行验证,文档中必须使用DOCTYPE引入要用于验证的DTD文件。

 

3、XML Schema验证:JAXP 1.3 API详解 本文详细解析了JAXP 1.3中用于XML Schema模式验证的三种主要API:DOM解析器、SAX解析器和验证API。文章介绍了它们的使用方法、适用场景以及对比分析,并提供了完整的代码示例。此外,还讨论了实际应用中的注意事项、扩展应用以及未来发展趋势,帮助开发者更好地理解和应用XML Schema验证技术。 阅读详情

相关推荐

南京银行信息技术岗提前批笔试与面试

1、笔试 笔试大致可以分为三部分:性格测试、行测题目、专业知识 性格测试 性格测试一般会有较多的体量,可能一共大概有一百多道接近两百道的样子,这个是不限时的。 前面有100道是这样的题目,就是有四个选项都是各种形容词,然后分别选出最符合自己的与最不符合自己的选项。这种题你就顺着自己的潜意识填就行了,但是前后要一致,我怀疑他出这么多题,可能就是考一考你记不记得前面填了啥。比如你做到第90题的时候,可能会出现和前面第2题类似的四个形容词,更有甚者就是一模一样的,你要对自己之前选的什么有个比较清楚的记忆。

qq_40971025的博客 6922

schema学习系列五: schema校验

检查文档是否遵循了模式中规定的规则。不同的解析器和工具支持不同的模式语言如  DTD 、 W3C XML Schema  语言、 RELAX NG  和  Schematron 。 Java 5™  增加了统一的验证应用程序编程接口( API ),可以 把文档和用这种或那种语言编写的模式作比较。了解这种  XML  验证  API 。 验证是一种强大的工具。它可以快速检查...

ReeBoo 2390

uniapp实战:5分钟搞定PDA激光扫码功能(附完整代码)

本文详细介绍了在Uniapp应用中快速集成工业PDA激光扫码功能的实战方案。通过解析PDA硬件扫码与手机摄像头扫码的核心机制差异,提供了完整的广播监听封装类代码,并演示了在Vue页面中的集成使用方法,帮助开发者高效解决仓储、零售等行业的条码扫描需求。

weixin_29239661的博客 456

通过jdk实现xsd校验xml

利用jdk自身的javax.xml.validation.Schema特性实现对象xsd对xml的校验,参考代码如下: package xxx.common.util; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.nio.file.Path; imp...

839

【rt-thread实战解析】从零到一:基于STM32与LAN8720A的以太网驱动配置全流程

本文详细解析了在RT-Thread操作系统上为STM32F407配置LAN8720A以太网驱动的全流程。从硬件连接自查、CubeMX工程创建、PHY复位函数编写,到RT-Thread工程配置、LwIP协议栈集成,最后进行实际上电测试与网络调试,手把手指导开发者避开常见陷阱,实现稳定的以太网连接。

m2n3b4v5c6的博客 525

合成生物学中试:花钱只是开始,烧钱才是常态

2026年合成生物学行业面临严峻产业化挑战:多家企业终止发酵项目或延期投产,显示从实验室到工厂的转化困境。核心问题并非基因合成成本,而是工艺放大难题——67%项目在中试阶段因工艺问题失败。AI辅助无法替代工程经验,菌株-配方-工艺的三元适配需要长期数据积累。中试成本惊人,涉及设备折旧、原料消耗和稀缺工艺人才,而行业普遍回避讨论这些工程现实,导致认知偏差。建议创业者提前布局中试,将其视为核心竞争力而非简单成本项。合成生物学的真正瓶颈在于工程化能力,这需要时间沉淀而非技术叙事。

AIexander的博客 942

Java中使用Schema验证

by Neeraj Bajaj The Java API for XML Processing (JAXP) 1.3 was initially introduced in Java 2 Platform, Standard Edition (J2SE) 5.0 and is also now available in the Java Web Services Developer Pack (J...

刘刚的空间 698

R语言中如何获取前向选择(forward selection)选出的变量

前向选择是一种常用的特征选择方法,可以在给定一个预测模型的情况下,逐步添加变量来确定最佳的预测模型。在R语言中,可以使用适当的函数和库来执行前向选择,并获取选出的变量。以下是一个详细的步骤,展示了如何使用R语言执行前向选择并获得选出的变量。通过按照上述步骤,你可以使用R语言执行前向选择,并获取选出的变量。记住,前向选择是一种特征选择方法,可以根据不同的评估指标选择最佳的预测模型。接下来,准备用于前向选择的数据。使用"summary"函数查看前向选择的摘要,并使用"which"函数获取被选中的变量。

WangWEel的博客 924

sax解析dtd_好程序员Java教程分享详细了解Javasax解析器

好程序员Java教程分享详细了解Javasax解析器,SAX(针对XML的简单API)是基于事件为XML文档的解析器。不像DOM解析器,SAX解析器创建没有解析树。SAX是一个流接口用于XML的,这意味着使用SAX应用接收事件通知有关XML文档被处理的元素,属性,在按顺序每次开始在文档的顶部,并与所述闭合结束根元素。读取XML文件从上到下,构成一个结构完整的XML文档的标记令牌以相同的顺序进行处理...

weixin_29737443的博客 197

SAP UI5 用数据绑定导出:从 ExportTypeCSV 到 Spreadsheet 的完整实践与取舍

SAP UI5 数据绑定导出机制通过复用 Model、Binding Path 等配置,将控件视图转换为文件格式。早期方案使用 sap/ui/core/util/Export 生成 CSV,需自定义 ExportType 扩展格式;现代方案推荐 sap/ui/export/Spreadsheet 直接导出 XLSX,支持类型精度和智能表格集成。注意 CSV 方案已弃用但仍有业务价值,需根据项目需求选择合适方案。两种方式都基于数据绑定,避免重复定义列结构和格式化逻辑。

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 268

【项目实战】DevOps制品管理之JFrog Artifactory介绍

JFrog Artifactory是一款领先的二进制软件制品仓库管理工具,由JFrog公司开发。

奶爸的编程之路,也就一周冷个三天 1354

JAVA解析XML文件--SAX方式

1.XML基础知识见:http://www.w3school.com.cn/xml/index.asp 2.DTD基础知识见:http://www.w3school.com.cn/dtd/index.asp 和 http://blog.youkuaiyun.com/xiazdong/article/details/7270593 3. DOM (Document Object Model,与平台和语言

蓁蓁尔的博客 882

【深度学习基础】多任务学习(Multi-Task Learning)

多任务学习(Multi-task learning)是和单任务学习(single-task learning)相对的一种机器学习方法。在机器学习领域,标准的算法理论是一次学习一个任务,也就是系统的输出为实数的情况。复杂的学习问题先被分解成理论上独立的子问题,然后分别对每个子问题进行学习,最后通过对子问题学习结果的组合建立复杂问题的数学模型。多任务学习是一种联合学习,多个任务并行学习,结果相互影响。一次只学习一个任务(task),大部分的机器学习任务都属于单任务学习。

十二月的猫 1万+

为什么使用 XML Schema?——从约束到校验的完整指南

通过这样,ISBNType就强制 ISBN 必须符合特定的格式模式,PriceType则限定了价格的范围和小数位数。对比维度DTDXML Schema语法格式非 XML 语法标准 XML 语法数据类型仅字符串丰富内置类型 + 自定义类型命名空间支持薄弱原生支持类型继承不支持支持扩展与限制枚举与模式仅枚举(有限)枚举 + 正则模式唯一性约束仅 ID/IDREF可扩展性差强,支持模块化工具生态较少广泛支持。

2611_96449474的博客 502

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

xml的解析和schema约束

XML的解析和schema约束 1、XML的解析

LH is programming hard 1092

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

JAXP 验证-使用 JAXP 1.3 的新功能验证 XML

 http://www-128.ibm.com/developerworks/cn/xml/x-jaxpval.html JAXP 验证 使用 JAXP 1.3 的新功能验证 XML

燕窝 1579

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

JAXP 验证

JAXP 验证 使用 JAXP 1.3 的新功能验证 XML Java™ 编程语言的最新版本 Java 5.0 包括经过改进和扩展的 Java API for XML Processing(JAXP)版本。JAXP 主要增加了新的验证 API,它提供了更好的交互性,支持 XML Schema 和 RELAX NG,能够在验证的同时即时修改。经过这些改进,为 Java 开

legend_x的专栏 620

jaxp_关于JAXP的全部,第1部分

Java技术和XML可以说是过去五年中最重要的编程开发。 结果,用于使用Java语言的XML的API激增了。 两种最受欢迎​​的文档对象模型(DOM)和XML的简单API(SAX)引起了极大的兴趣,紧随其后的是JDOM和数据绑定API(请参阅参考资料 )。 彻底了解这些API中的一两个是一项艰巨的任务。 正确使用所有这些使您成为专家。 但是,越来越多的Java开发人员发现他们不再需要广泛的SA...

cuyi7076的博客 200

JSR 206: Java API for XML Processing (JAXP) 1.3

        JAXP (全称Java API for XML Parsing)1.3 增加了XML的可插拔性(pluggability),开发人员可以编写自己的xml处理器,只要它符合JAXP的APIs,这样底层不同的xml处理器可以任意切换而不用改应用程序的代码。        那JAXP到底是什么呢?首先这个P有点迷惑,它代表Parsing还是Processing呢?    因为J

王洪伟的专栏 3178

Xml文件读取与配置文件解析方法比较

Xml文件读取与配置文件解析方法比较

prince2270的专栏 2945

xml语法、xml解析(dom4j)、DTD约束和语法、schema约束和语法

xml语法、xml解析(dom4j)、DTD约束和语法、schema约束和语法

qq_39159340的博客 325

验证 XML 是否符合 Schema

为了验证 XML 文档的合法性,通常需要对文档进行验证,要么符合 DTD,要么符合 Schema。在以前的 JAXP 版本中,验证(Validation)是作为解析器(Parser)的一个功能特征来提供的。 JAXP 的 Validation API 把 XML Parser 和 Validator 解耦合了。这样获得了两个好处: 1...

weixin_33712881的博客 423

JAXP的演进(转)

  原文作者: Rahul Srivastava 原文地址:http://www.xml.com/pub/a/2005/07/06/jaxp.html 中文地址:http://www.matrix.org.cn/resource/article/43/43893_JAXP.html 简介 在1998年W3CXML1.0推荐标准发布之后,XML就开始变得很流行。Sun公司就是在...

大音希声 大象无形 194

`javax.xml.validation` 是 Java 标准 API 中用于 XML 文档验证的核心包,自 Java 5(JDK 1.5)引入

- 默认不启用命名空间感知(namespace-aware),若 XSD 使用命名空间,`SchemaFactory` 必须通过 `setNamespaceAware(true)`(通常在创建 `DocumentBuilder` 或 `SAXParser` 时也需同步配置); - `Validator` **不是线程安全的**,每次验证应使用新实例或同步访问; - 不支持内联 XSD(如 `<xs:schema>` 嵌入 XML 中),仅支持外部引用或 `StreamSource` 加载的独立 XSD 文件

[Blog][Domain] programb.blog.youkuaiyun.com 491

【XML】schema验证-MSV,

  通过Schema对xml文档进行验证:   http://msv.java.net/   The Oracle Multi-Schema XML Validator (MSV) is a Java technology tool to validate XML documents against several kinds of XML schemata. It supports R...

cfy_zybing的专栏 383
上一篇: JAXP和Dom4j通过XPath获取带命名空间的节点
下一篇: JAXB2.0编组和解组实现
心如止水dy
博客等级 码龄19年 5粉丝 16原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值