有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java为什么我的JAXB解组器找不到导入模式中声明的元素?

我有两个模式A和B,它们具有循环依赖关系(这是一个中间步骤)。根据xmllint和Visual Studio,我使用的XML文件作为输入,根据模式进行验证。Eclipse告诉我,两个模式都包含两个同名的全局组件

A.xsd:

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-Instance"
  targetNamespace="http://foo.org/A"
  xmlns="http://foo.org/A"
  elementFormDefault="unqualified"
  attributeFormDefault="unqualified">

<xs:import schemaLocation="b.xsd" />

B.xsd:

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-Instance"
  xmlns:foo="http://foo.org/A"
  elementFormDefault="unqualified"
  attributeFormDefault="unqualified">

  <xs:import namespace="http://foo.org/A" schemaLocation="a.xsd" />

我要传递给解组器的XSD是A.XSD。当遇到B.xsd中定义的元素时,它会抱怨:

org.xml.sax.SAXParseException: cvc-elt.1: Cannot find declaration of element 'foo'.

我通过(伪)设置了模式:

InputStream in = .. A.xsd
SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
return factory.newSchema(new StreamSource(in);

谁能解释我做错了什么?谢谢


共 (1) 个答案

  1. # 1 楼答案

    <xs:import>用于将其他架构中定义的名称空间导入当前架构。schemaLocation属性只不过是一个关于在哪里找到另一个名称空间的提示

    B.xsd的情况下,您是说要导入名称空间http://blah.org,该名称空间由A.xsd中的模式处理

    A.xsd的情况下,B.xsd的导入没有指定要导入的名称空间

    如果A.xsdB.xsd代表不同的名称空间,那么import需要显式指定

    另一方面,如果您只是试图将另一个模式文件中的元素内联到同一名称空间中,那么include指令更合适


    编辑:好的,看过你的模式片段后,我可以说<xs:import>绝对不是正确的做法。A.xsdB.xsd都是在同一名称空间(http://foo.org/A)中定义元素,因此应该使用<xs:include>

    当Java遇到一个<xs:import>,并且该导入的名称空间是它已经知道的名称空间时,它实际上会忽略它。因此,当它解析B.xsd(在名称空间http://foo.org/A)时,它会为同一名称空间找到一个导入,它会忽略它