Как сопоставить catalog.xml сущности с базой данных?

Я должен проверить некоторые файлы XML с файлами.xsd, которые перечислены в catalog.xml, но они находятся в базе данных. Поэтому мне нужен распознаватель, который будет сопоставлять systemId из catalog.xml с файлом.xsd, хранящимся в виде BLOB-объекта в базе данных. я нашел это XMLInputSource resolveEntity(XMLResourceIdentifier resourceIdentifier) метод делает это, но я не могу найти, как синтаксический анализатор использует этот метод, поэтому я не уверен, как переопределить его, чтобы сделать это правильно. Я думал, что это возвращает XMLInputStram который содержит файл.xsd в Stream, но это не так из-за "оставления разрешения сущности и открытия входного потока до вызывающей стороны", согласно документации XMLInputSource.

Поэтому мой вопрос - как сопоставить сущности из catalog.xml с файлами.xsd, хранящимися в базе данных?

Я действительно надеюсь, что я объяснил проблему ясно, но я знаю, что мой английский действительно плохой - так что не стесняйтесь спрашивать больше деталей или лучшего объяснения.

Привет, Рзыся

2 ответа

Решение

Хорошо, я нашел решение - как я думал, метод XMLInputSource resolveEntity(XMLResourceIdentifier resourceIdentifier) shoud вернуть XMLInputSource с установленным моим собственным InputStream, содержащим конкретную xsd-схему. Моя версия этого переопределенного класса:

public XMLInputSource resolveEntity(XMLResourceIdentifier resourceIdentifier)
        throws XNIException, IOException {

    String resolvedId = resolveIdentifier(resourceIdentifier);

    if (resolvedId != null) {
        XMLInputSource xmlis = new XMLInputSource(resourceIdentifier.getPublicId(),
                resolvedId,
                resourceIdentifier.getBaseSystemId());

        try {
            InputStream is = getXSDFromDb(resourceIdentifier.getLiteralSystemId());                
            xmlis.setByteStream(is);
        } catch (SQLException ex) {
            ex.printStackTrace();
        }

        return xmlis;
    }
    return null;

Вот решатель, который я написал для плагина maven-jaxb2-. Этот преобразователь разрешает системные идентификаторы для ресурсов в артефактах Maven. Это несколько похоже на вашу задачу.

  • Ваша задача, в основном, реализовать resolveEntity метод.
  • Обычно целесообразно расширить существующий CatalogResolver,
  • Тогда вы можете переопределить getResolvedEntity метод.
  • Обычно вы сначала вызываете метод super для разрешения systemId / publicId,
  • Затем вы пытаетесь сделать собственное разрешение.
  • systemId обычно это URL-адрес расположения ресурса (или логический URI).
  • publicId часто это URI пространства имен.

Вот простой фрагмент кода от другого распознавателя, который разрешает classpath:com/acme/foo/schema.xsd в пути к классам:

public static final String URI_SCHEME_CLASSPATH = "classpath";

@Override
public String getResolvedEntity(String publicId, String systemId) {
    final String result = super.getResolvedEntity(publicId, systemId);

    if (result == null) {
        return null;
    }

    try {
        final URI uri = new URI(result);
        if (URI_SCHEME_CLASSPATH.equals(uri.getScheme())) {
            final String schemeSpecificPart = uri.getSchemeSpecificPart();
            final URL resource = Thread.currentThread()
                    .getContextClassLoader()
                    .getResource(schemeSpecificPart);
            if (resource == null) {
                return null;
            } else {
                return resource.toString();
            }
        } else {
            return result;
        }
    } catch (URISyntaxException urisex) {
        return result;
    }
}

В вашем сценарии я бы сделал следующее:

  • Определите схему URI как database:schema:table:value:id:schema.xsd,
  • Напишите средство распознавания каталога, способное разрешать такие URI.
  • Определите файл каталога, который перезаписывает URI пространства имен или URL-адреса абсолютного расположения схемы для вашего database:... URIs.

В простой записи это будет что-то вроде:

REWRITE_SYSTEM "http://example.com/schemas" "database:schemas:content:schema_id:example/schemas"
  • Таким образом, "базовый" преобразователь каталога сначала разрешит http://example.com/schemas/schema.xsd в database:schemas:content:schema_id:example/schemas/schema.xsd,
  • Тогда ваш код разрешается database:schemas:content:schema_id:example/schemas/schema.xsd в ресурс базы данных.
Другие вопросы по тегам