xml 处理的java api (jaxp) 1.3在java 2 平台里已经首先引入了, 标准版(j2se) 5.0 并且同样也在目前已可使用的java web services developer pack (java wsdp)中 。 jaxp 1.3 新增了一个模式验证结构(svf), 也叫验证api, 它提供了依靠模式高效验证xml的高级能力。svf同样也提供了比jaxp 1.2中更高的执行效率。
在考察svf之前, 我们看看早期的模式验证方法。以下的代码片断示范了sax解析的方法:
saxparserfactory sf = saxparserfactory.newinstance();
sf.setnamespaceaware(true);
sf.setvalidating(true);
saxparser sp = sf.newsaxparser();
sp.setproperty(
schema_language, xmlconstants.w3c_xml_schema_ns_uri);
sp.setproperty(schema_source, schema); sp.parse(new file(xml), dh);
基本的步骤是:
1.创建一个saxparserfactory 对象。
2.配置saxparserfactory对象来生成支持xml命名空间的分析程序, 以及需要解析的验证文档。
3.创建一个sax 分析程序。
4.设置sax 分析程序属性的模式语言和模式来源。在本例中为w3c xml模式。
5.解析文件。
注意,这个过程的耦合验证和xml处理。
作为比较, svf方法中, xml文件模式验证从xml 处理中分离出来。svp方法的第一步是编译模式:
final string sl = xmlconstants.w3c_xml_schema_ns_uri; schemafactory factory = schemafactory.newinstance(sl); streamsource ss = new streamsource("myschema.xsd"); schema schema = factory.newschema(ss);
schemafactory是一个模式编译器。它读指定的模式, 根据指定的模式语言的约束来检查模式语法和语义, 并且返回一个在内存中不变的schema对象。不可变意味着一旦创建了schema对象约束设置就不可改变。一个应用程序使用同一个schema对象验证同样的文件两次也总会得到同样的结果。
然后,您使用模式验证一个xml文件。根据你的需要将有三个方法可供选择:
?在documentbuilderfactory 或saxparserfactory上设置了schema实例
?创建一个validator
?创建一个validatorhandler (验证sax流)
所有这三个方法都保证, xml文件只在从schema实例中获得的模式中有效。
查看第一种方法, 在一个factory上设置schema实例:
saxparserfactory spf = saxparserfactory.newinstance(); spf.setschema(schema); saxparser parser = spf.newsaxparser(); parser.parse(<xml document>);
在这里, 同一个schema实例传输到所有的由saxparserfactory创建的saxparser实例中。saxparser对象解析xml 文件并且同时验证它所依靠的schema实例。 由于saxparser并不为需要解析的每个xml文件都反复装载模式,这个方法可为整个模式处理提高相当的效率。与前面的方法比较,前面需要为每个需要验证的xml文件重复的装载指定的模式。
在您装载一个schema对象到内存以后, 您能采用第二个方法,通过schema对象使用validator 验证xml 文件。首先您从schema对象中创建一个validator 对象。 然后调用在validator 对象中的validate() 方法来验证:
validator v = schema.newvalidator(); v.validate(new streamsource(xml));
validator对象接受java.xml.transform.source作为输入。 这意味着, 它可接受基于事件, sax 源(saxsource) 和基于对象, 文档对象模型(dom) 源(domsource) 。 接受domsource作为输入, validator能由指定的schema对象验证一个在内存中的dom文件或节点。
validator v = schema.newvalidator(); v.validate(new domsource(<dom node>));
如果要验证一个dom 节点或指定的saxsource,您也可考虑validator方法。既使sax 驱动器的执行是来自另外的一个供营商这个方法仍然可以运作。
第三个方法是创建一个特殊设计的javax.xml.validation.validatorhandler来验证sax 事件:
saxparserfactory spf = saxparserfactory.newinstance(); spf.setnamespaceaware(true); xmlreader reader = spf.newsaxparser().getxmlreader(); validatorhandler vh = schema.newvalidatorhandler(); //key is to set "validatorhandler" as contenthandler //so that sax event can be validated reader.setcontenthandler(vh); reader.parse(xml);
注意验证sax事件, 您需要设置validatorhandler 为contenthandler 。
使用validatorhandler, 您也能利用模式验证一个jdom 文件。 实际上, 任一个可在一个sax流顶部建立或可产生sax事件的对象模型(譬如xom 和dom4j)能由svf利用一个模式来验证xml 文件。 这是可能的,因为validationhandler 能验证一个sax流。 以下代码片断说明了一个jdom文件是如何利用一个模式来验证的,假设你已经获取了前面例子中显示的validatorhandler:
saxoutputter so = new saxoutputter(vh); so.output(jdomdocument);
saxoutputter 对象为jdom 文件释放sax事件。 sax 事件然后由validatorhandler验证。
您能使用svf做的其它事是, 譬如在转换以后验证xml或获得模式类型信息。使用svf的更多信息请参考:easy and efficient xml processing: upgrade to jaxp 1.3
运行例代码
范例程序包伴有本提示。 范例程序包中的代码包括编码实例和展示技术报道信息。在这个程序包里还有额外范例。 例如, 其中一个例子比较使用新的svf模式验证性能和设置二个模式属性的前面的方法。 其它范例显示利用模式怎么验证transformer的输出。 安装和运行范例:
1.下载sample file并解压缩其内容。你能在形如<install_dir>/validationframework的目录中看到解压缩出来的目录。例如,如果你解压缩内容到一台windows机器上的c:/中,你最近创造的目录就应该是c:/validationframework 。解压缩出来的内容包括一个readme文件,此文件中包括了运行例子的介绍。你能使用在j2se 5.0或者java wsdp 1.6平台上的jaxp 1.3来运行例程序。你也能下载在java.net 上的jaxp 项目页面中的standalone jaxp 1.3 implementation 。
2.运行validationframework 目录中的ant图标。要编译使用如下的命令:
ant compile
反馈信息中,你会看到如下的内容:
buildfile: build.xml
init:
[mkdir] created dir: c:/validationframework/build
[mkdir] created dir:
c:/validationframework/build/classes
compile:
[echo] c:/program files/java/jdk1.5.0/jre
...
build successful
要运行例子,利用适当的目标来运行ant命令,例如:
ant validatesaxstream
在反馈的信息中,你会看到如下的信息输出:
[java] startelement: personnel
[java] startelement: person
[java] startelement: name
[java] startelement: family
[java] characters: boss
[java] endelement: family
...
[java] startelement: email
[java] characters: five@foo.com
[java] endelement: email
[java] startelement: link
[java] endelement: link
[java] endelement: person
[java] endelement: personnel
build successful
如果你在j2se 5.0中运行例子,不考虑jaxp jar的位置的'endorsed' 属性。例如:
ant -dendorsed=/space/jaxp/jaxp-1_3/dist/ validate
闽公网安备 35060202000074号