Невозможно разрешить имя "X" в (n) компоненте "определение типа"

Есть много сообщений с таким же названием, как это. Я смотрел на многих из них, но их ситуация, кажется, отличается от моей.

У меня есть приложение Java, которое настраивается во время выполнения с помощью файла XML. Существует соответствующая XML-схема, которая определяет структуру XML. Схема импортирует другую схему, чтобы использовать определения типов, которые они определяют. Приложение читает файл схемы и конфигурации и загружает XML как объекты Java.

Приложение построено с использованием Apache Maven, а maven-jaxb2-plugin используется для преобразования определений схемы в классы Java, чтобы приложение могло получать информацию о конфигурации XML. Все строится успешно, и, насколько я могу судить, сгенерированные XJC классы верны и находятся в правильных местах.

Я сталкиваюсь с проблемой, когда пытаюсь выполнить приложение, которое сначала читает XML и загружает его как объекты Java. Пример исключения приведен ниже.

[2018-08-09 10:31:05.056] ERROR: common.ConfigLoader:121 - Exception: 
org.xml.sax.SAXParseException; lineNumber: 291; columnNumber: 80; src-resolve: Cannot resolve the name 'sc:ExpectedDataFormatEnum' to a(n) 'type definition' component.
    at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.createSAXParseException(ErrorHandlerWrapper.java:198)
    at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.error(ErrorHandlerWrapper.java:134)
    at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(XMLErrorReporter.java:437)
    at com.sun.org.apache.xerces.internal.impl.xs.traversers.XSDHandler.reportSchemaErr(XSDHandler.java:4162)
    at com.sun.org.apache.xerces.internal.impl.xs.traversers.XSDHandler.reportSchemaError(XSDHandler.java:4145)
    at com.sun.org.apache.xerces.internal.impl.xs.traversers.XSDHandler.getGlobalDecl(XSDHandler.java:1678)
    at com.sun.org.apache.xerces.internal.impl.xs.traversers.XSDElementTraverser.traverseNamedElement(XSDElementTraverser.java:405)
    at com.sun.org.apache.xerces.internal.impl.xs.traversers.XSDElementTraverser.traverseLocal(XSDElementTraverser.java:194)
    at com.sun.org.apache.xerces.internal.impl.xs.traversers.XSDHandler.traverseLocalElements(XSDHandler.java:3618)
    at com.sun.org.apache.xerces.internal.impl.xs.traversers.XSDHandler.parseSchema(XSDHandler.java:633)
    at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaLoader.loadSchema(XMLSchemaLoader.java:617)
    at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaLoader.loadGrammar(XMLSchemaLoader.java:575)
    at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaLoader.loadGrammar(XMLSchemaLoader.java:541)
    at com.sun.org.apache.xerces.internal.jaxp.validation.XMLSchemaFactory.newSchema(XMLSchemaFactory.java:252)
    at javax.xml.validation.SchemaFactory.newSchema(SchemaFactory.java:627)
    at {removed}.ConfigLoader.load(ConfigLoader.java:91)
    at {removed}.Launcher.main(Launcher.java:121)
[2018-08-09 10:31:05.058] ERROR: wf.Launcher:122 - Unable to load configuration file

Я подозреваю, что проблема связана с тем, как на импортированные схемы ссылаются / решают во время выполнения. Я использую каталог XML (новая для меня концепция) для определения местоположения схемы во время сборки. Нужно ли что-то подобное для разрешения местоположения во время выполнения?

Для контекста, здесь приведены фрагменты соответствующих файлов.

Схема, которая импортируется схемой приложения (security-common.xsd):

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="security_common"
  xmlns:sc="security_common" elementFormDefault="qualified" attributeFormDefault="unqualified">

  <xs:simpleType name="TypeList">
    <xs:list itemType="xs:string" />
  </xs:simpleType>

  <xs:simpleType name="ExpectedDataFormatEnum">
    <xs:restriction base="xs:string">
      <xs:enumeration value="STRING" />
      <xs:enumeration value="BYTE_ARRAY" />
    </xs:restriction>
  </xs:simpleType>

</xs:schema>

Схема приложения, которая использует схему выше (config-schema.xsd):

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="injector"
  xmlns:inj="injector" xmlns:sc="security_common" xmlns:camel="camel_config"
  elementFormDefault="qualified" attributeFormDefault="unqualified">

  <xs:import namespace="security_common" />
  <xs:import namespace="camel_config" />

  ...
  <xs:complexType name="WireCaptureConfig">
    <xs:sequence>
      <xs:element name="expected-data-format" type="sc:ExpectedDataFormatEnum" />
      ...
    </xs:sequence>
  </xs:complexType>
  ...
</xs:schema>

Файл каталога XML:

PUBLIC "security_common" "maven:{removed}:security-common:jar::!/config/security-common.xsd"
PUBLIC "camel_config" "maven:{removed}:security-common:jar::!/config/camel-config.xsd"

Насколько я понимаю, файл каталога отображает пространства имен схемы на артефакты maven, которые представляют схемы, которые необходимо импортировать / ссылаться на них. Это похоже на немного черной магии, но это работает.

Созданное исключение может указывать на то, что приложение не может "увидеть" импортированные определения схемы. Основываясь на том, что было описано, есть ли решение этой проблемы? Если потребуется предоставить другую информацию, пожалуйста, дайте мне знать, и я посмотрю, что я могу сделать.

1 ответ

Решение

Вы совершенно правы, подозревая, что вам также нужно разместить каталог для своего XML-каталога в своем Java-коде времени выполнения.

См. Использование каталога XML с библиотекой Java, которая использует JAXP для внутренних целей, для получения подробной информации о том, как использовать CatalogResolver (или org.apache.xml.resolver.tools.CatalogResolver).

Также обратите внимание, что может быть полезно установить, что все остальное в порядке с вашими XSD, поместив их в URI-доступные места 1 и добавив @schemaLocation атрибуты вашего xs:imports, Многие диагностические сообщения реализации XML-каталога далеко не идеальны для отслеживания проблем.

1 См. Как правильно ссылаться на локальный файл XML-схемы?

Другие вопросы по тегам