如何使用RELAX NG模式和JAXPvalidationXML文档?

我想使用RELAX NG schematavalidationXML文档,我想使用JAXPvalidationAPI 。

从谷歌搜索,似乎我可以使用Jing和ISO RELAX JARV到JAXP Bridge 。 不幸的是,在将两者都添加到我的类路径后,我无法让它工作。 SchemaFactory只是在尝试实例化工厂时抛出IllegalArgumentException – 我在SchemaFactory查看,显然SchemaFactoryFinder返回null结果。

所以我很欣赏这两个问题的答案:

  • 我怎么能和Jing和这座桥一起工作呢?
  • 我应该尝试一套更好/不同的库吗?

我需要这个来使用Java 5和Java 6。

谢谢!

请参阅2008年3月7日撰写的Stefan Bodewig的Weblog,标题为XMLUnit中的RELAX NGvalidation :

从昨晚开始,XMLUnit的trunk包含一个新的Validator类,它基于javax.xml.validation,它是JAXP 1.3的一部分(即Java5 +)。

据我所知,没有JAXP实现支持RELAX NG开箱即用。 Sun自己的JAXP 1.4(Java6 +)肯定没有。 一些搜索带我到Kohsuke Kawaguchi的博客谁应该知道,因为他的工作在JAXP,Sun的多架构validation器,isorelax和其他东西。

使用他的isorelax-bridge和Jing并没有让我在Java6上的任何地方。 我回到了Kohsuke Kawaguchi的文章并阅读了评论:由于他们更改了SchemaFactory查找算法,因此桥不能与Java6一起使用。 好了,尝试了Java5 – 进步,我现在在Jing内部的某个地方得到一个NullPointerException,所以至少它正在加载工厂。 接下来我用MSV取代了Jing(现在就在这里 ,不管有多少链接引导你到Sun的WebServices堆栈页面,以及“好的URL永远不会改变”),而且我的简单测试通过了。

所以你可能不得不跳过一些箍来获得RELAX NG支持到你的JAXP设置 – 在我的例子中,Java5,MSV和Kawaguchi的桥工作,但是评论表明它应该也适用于Java6 – 但是一旦你设法配置一切正确地说,XMLUnit现在可以让你在unit testing中断言文档的有效性。 但它似乎不适用于紧凑语法。

要阅读Kohsuke Kawaguchi博客上的评论,你必须使用archive.org,因为他们现在都不见了:

Java 5将服务提供者文件解释为键/值对的列表,这违反了Java 5和6 JAR文件规范,但恰好与您的示例相匹配。

Java 6按指定解析服务提供者文件,即。 作为完全限定类名的列表,但因此无法实例化适配器的SchemaFactory,因为服务提供者文件的内容无效。

要与Java 5和Java 6兼容而不必更改JAXP-JARV适配器JAR文件,可以简单地添加另一个包含正确的javax.xml.validation.SchemaFactory服务提供程序文件的JAR文件。

我使用以下行解决了Java 1.6上的这个错误:

 // Specify you want a factory for RELAX NG "compact" System.setProperty(SchemaFactory.class.getName() + ":" + XMLConstants.RELAXNG_NS_URI, "com.thaiopensource.relaxng.jaxp.CompactSyntaxSchemaFactory"); SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.RELAXNG_NS_URI); 

这允许我使用Jing来针对Compact RELAX NG模式validationXML文档。 完整的例子如下。 我没有使用这座桥或其他任何东西。 运行时类路径只有jing.jar(20091111)和我自己的Validator类。

 import java.io.File; import java.io.IOException; import javax.xml.XMLConstants; 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; public class Validate { public static void main(String[] args) throws SAXException, IOException { // Specify you want a factory for RELAX NG System.setProperty(SchemaFactory.class.getName() + ":" + XMLConstants.RELAXNG_NS_URI, "com.thaiopensource.relaxng.jaxp.CompactSyntaxSchemaFactory"); SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.RELAXNG_NS_URI); // Load the specific schema you want. // Here I load it from a java.io.File, but we could also use a // java.net.URL or a javax.xml.transform.Source File schemaLocation = new File(args[0]); // Compile the schema. Schema schema = factory.newSchema(schemaLocation); // Get a validator from the schema. Validator validator = schema.newValidator(); for (int i = 1; i < args.length; i++) { String file = args[i]; // Check the document try { validator.validate(new StreamSource(new File(file))); System.out.println(file + " is valid."); } catch (SAXException ex) { System.out.print(file + " is not valid because: " + ex.getMessage()); } } } } 

再一次,我只测试了这个离子Java 1.6。

 $ java -version java version "1.6.0_01" Java(TM) SE Runtime Environment (build 1.6.0_01-b06) Java HotSpot(TM) Client VM (build 1.6.0_01-b06, mixed mode, sharing) 

我无法帮助您使用JAXPvalidationAPI,但Nux提供了一个类,可以validation人类已知的几乎所有类型的模式。 关于RELAX NG模式,使用此工厂方法创建相关的validation器对象。

另一个选项是Trang ,它是一个RelaxNG-to-XMLSchema翻译器。 我相信它被设计为用作构建工具而不是运行时库,但您最好的选择可能是在构建时使用Trang将模式转换为XMLSchema,然后对其进行validation。 这样,您可以准确地看到翻译的样子,同时充分利用JAXP的XML Schema支持。

一旦尝试实例化工厂,就会出现IllegalArgumentException

意味着架构语言无法识别,可能有几个原因。

  • 由于Sun JDK默认情况下不包含RELAX NGvalidation器,因此可能无法找到它。
  • 可能是您在架构语言标识符中出错了。