Как проверить XML-документ с помощью схемы RELAX NG и JAXP?

Я хотел бы проверить документы XML с использованием схем RELAX NG, и я хотел бы использовать API проверки JAXP.

Из Googling вокруг появилось, что я могу использовать Jing и ISO RELAX JARV на мост JAXP. К сожалению, добавив оба пути в класс, я не могу заставить его работать. SchemaFactory просто бросает IllegalArgumentException, как только он пытается создать экземпляр factory - я заглянул внутрь SchemaFactory, видимо, SchemaFactoryFinder возвращает нулевой результат.

Поэтому я буду благодарен за ответы на любой вопрос:

  • Как я могу выполнить эту работу с Jing и этим мостом?
  • Есть ли лучший/другой набор библиотек, который я должен попробовать?

Мне нужно это для работы с Java 5 и Java 6.

Спасибо!

Ответы

Ответ 1

Смотрите веб-журнал Stefan Bodewig, написанный 7 марта 2008 года под названием RELAX NG Validation в XMLUnit:

С прошлой ночи соединительная линия XMLUnit содержит новый класс Validator, основанный на javax.xml.validation, который является частью JAXP 1.3 (т.е. Java5 +).

...

Насколько я знаю, нет реализации JAXP, которая поддерживала RELAX NG из коробки. Sun собственный JAXP 1.4 (Java6 +), конечно же, нет. Некоторые поиски привели меня к Kohsuke Kawaguchi Blog, который должен знать, учитывая его работу над JAXP, Sun Multi Schema Validator, isorelax и другие вещи.

Используя его isorelax-bridge и Jing не достал меня нигде на Java6. Я вернулся к статье Кохсуке Кавагути и прочитал комментарии: мост не работает с Java6, так как они изменили алгоритм поиска SchemaFactory. ОК, попробовал Java5 вместо этого - прогресс, теперь я получаю исключение NullPointerException где-то внутри Jing, поэтому по крайней мере он загружает factory. Затем я заменил Jing на MSV (который здесь, независимо от того, сколько ссылок на нем приводит вас на страницу стека WebServices на Sun, так много поскольку "хорошие URL-адреса никогда не меняются" ), и действительно, мои упрощенные тесты проходят.

Таким образом, вам, возможно, придется перепрыгнуть через некоторые обручи, чтобы получить поддержку RELAX NG в вашей настройке JAXP - в моем случае работали мосты Java5, MSV и Kawaguchi, но комментарии указывают, что это также должно выполняться с Java6, но если вы управляете чтобы все было правильно настроено, теперь будет доступен XMLUnit, чтобы вы могли утверждать свою документацию в модульных тестах. Кажется, что это не работает для компактного синтаксиса.

Чтобы прочитать комментарии к блогу Kohsuke Kawaguchi, вы должны использовать archive.org, потому что теперь они все ушли:

Java 5 интерпретирует поставщика услуг файл как список пар ключ/значение, что является нарушением Java 5 и 6 Спецификация файла JAR, но происходит с соответствует вашему примеру.

Java 6 анализирует поставщика услуг файл, как указано, т.е. как список полностью квалифицированные имена классов, но при этом не удалось создать экземпляр адаптера SchemaFactory как поставщик услуг Недопустимое содержимое файла.

Для совместимости с Java 5 и Java 6 без изменения JAXP-JARV-адаптер JAR файл, можно просто добавьте еще один JAR файл, содержащий правильный javax.xml.validation.SchemaFactory Файл поставщика услуг.

Ответ 2

Я решил эту самую ошибку на 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 для проверки XML-документа по схеме Compact RELAX NG. Полный пример ниже. Я не использовал мост или что-то еще. Путь к классам времени выполнения имеет только 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)

Ответ 3

Я не могу помочь вам с API проверки достоверности JAXP, но Nux предоставляет класс, который может проверять практически все типы схем известный человеку. Что касается схем RELAX NG, используйте этот метод factory для создания соответствующего объекта валидатора.

Ответ 4

Другим вариантом является Trang, который является переводчиком RelaxNG-to-XMLSchema. Я считаю, что он предназначен для использования в качестве инструмента сборки, а не для библиотеки времени выполнения, но лучшим вариантом может быть преобразование вашей схемы в XMLSchema с помощью Trang во время сборки, а затем вместо этого проверка на это. Таким образом, вы можете точно увидеть, как выглядит перевод, в то же время полностью используя поддержку XML-схемы JAXP.

Ответ 5

... IllegalArgumentException, как только он пытается создать экземпляр factory

Указывает, что язык схемы не распознается, может быть несколько причин.

  • Так как Sun JDK по умолчанию не включает RELAX NG validator, возможно, он не найден.
  • Возможно, вы указали ошибку в идентификаторе языка схемы.