如何使用RELAX NG模式和JAXP验证XML文档?

时间:2009-10-09 00:22:56

标签: java xml validation relaxng jaxp

我想使用RELAX NG schemata验证XML文档,我想使用the JAXP validation API

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

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

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

我需要使用它来使用Java 5和Java 6.

谢谢!

5 个答案:

答案 0 :(得分:12)

我使用以下行解决了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模式验证XML文档。完整的例子如下。我没有使用这座桥或其他任何东西。运行时类路径只有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)

答案 1 :(得分:9)

参见Stefan Bodewig于2008年3月7日撰写的名为RELAX NG Validation in XMLUnit的博客:

  

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

...

  

据我所知,没有支持RELAX NG的JAXP实现。 Sun自己的JAXP 1.4(Java6 +)肯定没有。一些搜索带我到Kohsuke Kawaguchi's Blog谁应该知道,因为他在JAXP,Sun的多模式验证器,isorelax和其他东西上的工作。

     

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

     

所以你可能不得不跳过一些环节来获得RELAX NG支持到你的JAXP设置 - 在我的例子中,Java5,MSV和Kawaguchi的桥梁工作,但是评论表明它应该也适用于Java6 - 但是一旦你管理了为了正确配置所有内容,XMLUnit现在可以让你在单元测试中断言文档的有效性。但它似乎不适用于紧凑语法。

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

  

Java 5解释服务提供者   file作为键/值对的列表,   这违反了Java 5&amp; 6   JAR文件规范但恰好   符合你的榜样。

     

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

     

兼容Java 5和   Java 6无需更改   JAXP-JARV适配器JAR文件,可以   只需添加另一个包含的JAR文件   一个正确的   javax.xml.validation.SchemaFactory中   服务提供商文件。

答案 2 :(得分:1)

我无法帮助您使用JAXP验证API,但Nux提供了一个类,可以验证人类已知的几乎所有类型的模式。关于RELAX NG模式,使用this factory method创建相关的验证器对象。

答案 3 :(得分:1)

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

答案 4 :(得分:0)

... IllegalArgumentException尝试实例化工厂

表示无法识别架构语言,可能有几个原因。

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