java - 无法将名称 'X' 解析为 (n) 'type definition' 组件

标签 java xml xsd jaxb xmlcatalog

与此同名的帖子很多。我看过很多,但他们的情况似乎和我的不一样。

我有一个在运行时通过 XML 文件配置的 Java 应用程序。有一个对应的 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"

我的理解是目录文件将模式 namespace 映射到 Maven 工件,它表示要导入/引用的模式。这似乎有点黑魔法,但确实有效。

抛出的异常似乎表明应用程序无法“看到”导入的模式定义。根据所描述的内容,是否有解决此问题的方法?如果需要提供其他信息,请告诉我,我会尽力而为。

最佳答案

您怀疑您也必须在运行时 Java 代码中为您的 XML 目录提供住宿是对的。

参见 Using an XML Catalog with a Java library that uses JAXP internally有关如何使用 CatalogResolver 的详细信息(或 org.apache.xml.resolver.tools.CatalogResolver )。

另请注意,通过将 XSD 放置在 URI 可访问的位置1 并将 @schemaLocation 属性添加到你的 xs:imports。许多 XML 目录实现的诊断消息对于跟踪问题而言并不理想。

1参见How to reference a local XML Schema file correctly?

关于java - 无法将名称 'X' 解析为 (n) 'type definition' 组件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51771197/

相关文章:

java - Spring AOP 自定义注释未针对我的 Controller 触发

java - 如何在 Java 中将字节数组转换为 AudioInputStream

xml - XSL : Xpath Query in <xsl:apply-templates> Isn't Returning Any Results

xml - 是否可以从XPath值列表和XML XSD构建XML文档?

java - 使用继承和 Java 接口(interface)使用为 Java 创建 XML 模式

java - 如何在android中获取当前时间戳?

java - Spring 国际奥委会 : depends-on overrides lazy-init

xml - 在 Chrome 中加载本地 XML 文件

PHP 获取 XML 格式的日期

python - 用于验证 xsd :ID string in Python? 的正则表达式