【问题标题】:How to validate an XML document using a RELAX NG schema and JAXP?如何使用 RELAX NG 模式和 JAXP 验证 XML 文档?
【发布时间】:2010-12-05 04:53:18
【问题描述】:

我想使用 RELAX NG 模式验证 XML 文档,并且我想使用 the JAXP validation API

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

因此,我希望您能回答任何一个问题:

  • 我怎样才能让 Jing 和这座桥一起工作?
  • 我应该尝试一组更好/不同的库吗?

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

谢谢!

【问题讨论】:

  • 我建议坚持使用 isorelax-jaxp-bridge 项目。它是由编写 JAXB 的人共同编写的,所以它很可能有效,可能只是需要一点鼓励。
  • @skaffman,感谢您的建议!我会努力做到的。

标签: java xml validation relaxng jaxp


【解决方案1】:

我在 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());
            }
        }
    }

}

再一次,我只测试了这个 ion 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)

【讨论】:

  • 将“System.setProperty”行:“com.thaiopensource.relaxng.jaxp.CompactSyntaxSchemaFactory”替换为“com.thaiopensource.relaxng.jaxp.XMLSyntaxSchemaFactory”,以针对基于 XML 的 RelaxNG 模式进行验证。谢谢你的样品,就像一个魅力!
  • 此代码非常适合验证 OPDS 提要。如果您使用的是 Maven,那么您只需要 jing:&lt;dependency&gt; &lt;groupId&gt;com.thaiopensource&lt;/groupId&gt; &lt;artifactId&gt;jing&lt;/artifactId&gt; &lt;version&gt;20091111&lt;/version&gt; &lt;/dependency&gt;
【解决方案2】:

请参阅 Stefan Bodewig 于 2008 年 3 月 7 日撰写的标题为 RELAX NG Validation in XMLUnit 的博客:

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

...

据我所知,没有开箱即用的支持 RELAX NG 的 JAXP 实现。 Sun 自己的 JAXP 1.4 (Java6+) 肯定不会。一些搜索把我带到了Kohsuke Kawaguchi's Blog,考虑到他在 JAXP、Sun 的多模式验证器、isorelax 和其他方面的工作,他应该知道。

使用他的isorelax-bridgeJing 并没有让我在Java6 上取得任何进展。我回到 Kohsuke Kawaguchi 的文章并阅读了 cmets:桥不适用于 Java6,因为它们更改了 SchemaFactory 查找算法。好的,改用 Java5 - 进步,我现在在 Jing 的某个地方得到一个 NullPointerException,所以至少它正在加载工厂。接下来,我将 Jing 替换为 MSV(现在是 here,无论有多少链接将您带到 Sun 的 WebServices 堆栈页面,“好的 URL 永远不会改变”),真的,我的简单测试通过了。

因此,您可能需要跳过一些障碍才能在您的 JAXP 设置中获得 RELAX NG 支持 - 在我的情况下,Java5、MSV 和 Kawaguchi 的桥可以工作,但 cmets 表明它也应该适用于 Java6 - 但是一旦你管理为了正确配置所有内容,XMLUnit 现在可以让您在单元测试中断言文档的有效性。不过,它似乎不适用于紧凑的语法。

要阅读 Kohsuke Kawaguchi 博客上的 cmets,您必须使用 archive.org,因为不知何故它们现在都不见了:

Java 5 解释服务提供者 文件作为键/值对列表, 这违反了 Java 5 & 6 JAR 文件规范,但碰巧 符合你的例子。

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

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

【讨论】:

    【解决方案3】:

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

    【讨论】:

      【解决方案4】:

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

      【讨论】:

        【解决方案5】:

        ...IllegalArgumentException 一旦它试图实例化一个工厂

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

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2013-06-01
          • 2011-07-07
          • 2011-09-13
          • 2012-07-11
          • 2011-05-05
          • 1970-01-01
          • 2012-10-15
          • 1970-01-01
          相关资源
          最近更新 更多