简体   繁体   English

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

[英]How to validate an XML document using a RELAX NG schema and JAXP?

I would like to validate XML documents using RELAX NG schemata, and I would like to use the JAXP validation API . 我想使用RELAX NG schemata验证XML文档,我想使用JAXP验证API

From Googling around, it appeared that I could use Jing and the ISO RELAX JARV to JAXP Bridge . 从谷歌搜索,似乎我可以使用JingISO RELAX JARV到JAXP Bridge Unfortunately, after adding both to my classpath, I can't get it to work. 不幸的是,在将两者都添加到我的类路径后,我无法让它工作。 SchemaFactory is just throwing an IllegalArgumentException as soon as it tries to instantiate a factory — I looked inside SchemaFactory , apparently SchemaFactoryFinder is returning a null result. SchemaFactory只是在尝试实例化一个工厂时抛出一个IllegalArgumentException - 我在SchemaFactory查看,显然SchemaFactoryFinder返回一个null结果。

So I'd appreciate answers to either question: 所以我很欣赏这两个问题的答案:

  • How can I make this work with Jing and this bridge? 我怎么能和Jing和这座桥一起工作呢?
  • Is there a better/different set of libraries I should try? 我应该尝试一套更好/不同的库吗?

I need this to work with Java 5 and Java 6. 我需要这个来使用Java 5和Java 6。

Thanks! 谢谢!

I resolved this very error on Java 1.6 with the following line: 我使用以下行解决了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);

This allows me to use Jing to validate an XML document against a Compact RELAX NG schema. 这允许我使用Jing来针对Compact RELAX NG模式验证XML文档。 Full example below. 完整的例子如下。 I didn't use the bridge or anything else. 我没有使用这座桥或其他任何东西。 The runtime classpath only has jing.jar (20091111) and my own Validator class. 运行时类路径只有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());
            }
        }
    }

}

Once again, I've only tested this ion Java 1.6. 再一次,我只测试了这个离子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)

See Stefan Bodewig's Weblog written on March 7, 2008 titled RELAX NG Validation in XMLUnit : 请参阅2008年3月7日撰写的Stefan Bodewig的Weblog,标题为XMLUnit中的RELAX NG验证

Since last night XMLUnit's trunk contains a new Validator class that is based on javax.xml.validation which is part of JAXP 1.3 (ie Java5+). 从昨晚开始,XMLUnit的trunk包含一个新的Validator类,它基于javax.xml.validation,它是JAXP 1.3(即Java5 +)的一部分。

... ...

To the best of my knowledge there is no JAXP implementation that supported RELAX NG out of the box. 据我所知,没有JAXP实现支持RELAX NG开箱即用。 Sun's own JAXP 1.4 (Java6+) certainly doesn't. Sun自己的JAXP 1.4(Java6 +)肯定没有。 Some searching around brought me to Kohsuke Kawaguchi's Blog who should know, given his work on JAXP, Sun's Multi Schema Validator, isorelax and other stuff. 一些搜索带我到Kohsuke Kawaguchi的博客谁应该知道,因为他的工作在JAXP,Sun的多架构验证器,isorelax和其他东西。

Using his isorelax-bridge and Jing didn't get me anywhere on Java6. 使用他的isorelax-bridgeJing并没有让我在Java6上的任何地方。 I went back to Kohsuke Kawaguchi's article and read the comments: the bridge doesn't work with Java6 since they changed the SchemaFactory lookup algorithm. 我回到了Kohsuke Kawaguchi的文章并阅读了评论:由于他们改变了SchemaFactory查找算法,因此桥不能与Java6一起使用。 OK, tried Java5 instead - progress, I now get a NullPointerException somewhere inside of Jing, so at least it is loading the factory. 好了,尝试了Java5 - 进步,我现在在Jing内部的某个地方得到一个NullPointerException,所以至少它正在加载工厂。 Next I replaced Jing with MSV (which is here now, no matter how many links out there lead you to the WebServices stack page at Sun, so much for "good URLs never change") and really, my simplistic tests pass. 接下来我用MSV取代了Jing(现在就在这里 ,不管有多少链接引导你到Sun的WebServices堆栈页面,以及“好的URL永远不会改变”),真的,我的简单测试通过了。

So you may have to jump through some hoops to get RELAX NG support into your JAXP setup - in my case Java5, MSV and Kawaguchi's bridge worked, but the comments indicate it should be doable with Java6 as well - but once you manage to configure everything correctly, XMLUnit will now be there to let you assert your document's validity in Unit tests. 所以你可能不得不跳过一些环节来获得RELAX NG支持到你的JAXP设置 - 在我的例子中,Java5,MSV和Kawaguchi的桥工作,但是评论表明它应该也适用于Java6 - 但是一旦你设法配置一切正确地说,XMLUnit现在可以让你在单元测试中断言文档的有效性。 It seems that it doesn't work for compact syntax, though. 但它似乎不适用于紧凑语法。

To read the comments on Kohsuke Kawaguchi's blog, you have to use archive.org because somehow they are all gone now: 要阅读关于Kohsuke Kawaguchi博客的评论,你必须使用archive.org,因为他们现在都不见了:

Java 5 interprets the Service Provider file as a list of key/value pairs, which is a violation to the Java 5 & 6 JAR file specification but happens to match your example. Java 5将服务提供者文件解释为键/值对的列表,这违反了Java 5和6 JAR文件规范,但恰好与您的示例相匹配。

Java 6 parses the Service Provider file as specified, ie. Java 6按指定解析服务提供者文件,即。 as a list of fully qualified class names, but thus fails to instantiate your adapter's SchemaFactory as the Service Provider file's contents are invalid. 作为完全限定类名的列表,但因此无法实例化适配器的SchemaFactory,因为服务提供者文件的内容无效。

To be compatible with both Java 5 and Java 6 without having to change the JAXP-JARV-adapter JAR file, one can simply add another JAR file containing a correct javax.xml.validation.SchemaFactory Service Provider file. 要与Java 5和Java 6兼容而不必更改JAXP-JARV适配器JAR文件,可以简单地添加另一个包含正确的javax.xml.validation.SchemaFactory服务提供程序文件的JAR文件。

I can't help you with the JAXP validation API, but Nux provides a class that can validate virtually every type of schema known to man. 我无法帮助您使用JAXP验证API,但Nux提供了一个类,可以验证人类已知的几乎所有类型的模式。 Regarding RELAX NG schemata, use this factory method to create the relevant validator object. 关于RELAX NG模式,使用此工厂方法创建相关的验证器对象。

Another option is Trang , which is a RelaxNG-to-XMLSchema translator. 另一个选项是Trang ,它是一个RelaxNG-to-XMLSchema翻译器。 I believe it's designed to be used as a build tool rather than a runtime library, but your best option might be to convert your schema to XMLSchema using Trang at build time, and then validate against that instead. 我相信它被设计用作构建工具而不是运行时库,但您最好的选择可能是在构建时使用Trang将模式转换为XMLSchema,然后对其进行验证。 That way, you can see exactly what the translation looks like, whilst getting full advantage of the XML Schema support of JAXP. 这样,您可以准确地看到翻译的样子,同时充分利用JAXP的XML Schema支持。

... IllegalArgumentException as soon as it tries to instantiate a factory ... 一旦尝试实例化工厂,就会出现IllegalArgumentException

Means the schema language isn't recognized, there could be a few causes. 意味着模式语言无法识别,可能有几个原因。

  • Since the Sun JDK doesn't include a RELAX NG validator by default, it could be that it's not being found. 由于Sun JDK默认情况下不包含RELAX NG验证器,因此可能无法找到它。
  • It could be that you've made an error in the schema language identifier. 可能是您在架构语言标识符中出错了。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM