Как проверить XML-документ, используя схему RELAX NG и JAXP? - PullRequest
14 голосов
/ 09 октября 2009

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

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

Так что я был бы признателен за ответы на любой вопрос:

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

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

Спасибо!

Ответы [ 5 ]

12 голосов
/ 20 января 2010

Я исправил эту самую ошибку в 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)
9 голосов
/ 21 октября 2009

См. Блог Штефана Бодевига, написанный 7 марта 2008 года, под названием RELAX NG Validation в XMLUnit :

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

...

Насколько мне известно, не существует реализации JAXP, которая бы поддерживала RELAX NG из коробки. Собственный JAXP 1.4 (Java6 +) от Sun определенно не работает. Некоторые поиски привели меня к Блогу Кохсуке Кавагути , который должен знать, учитывая его работу над JAXP, мультисхемным валидатором Sun, изорелаксом и другими вещами.

Использование его isorelax-bridge и Jing никуда меня не привело на Java6. Я вернулся к статье Kohsuke Kawaguchi и прочитал комментарии: мост не работает с Java6, так как они изменили алгоритм поиска SchemaFactory. Хорошо, попробовал Java5 вместо этого - прогресс, теперь я получаю исключение NullPointerException где-то внутри Jing, так что, по крайней мере, он загружает фабрику. Затем я заменил 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 без необходимости менять JAR-файл JAXP-JARV-адаптера, можно просто добавьте другой файл JAR, содержащий правильный javax.xml.validation.SchemaFactory Файл поставщика услуг.

1 голос
/ 21 октября 2009

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

1 голос
/ 21 октября 2009

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

0 голосов
/ 19 октября 2009

... IllegalArgumentException, как только он пытается создать фабрику

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

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