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 楼答案
<xs:import>
用于将其他架构中定义的名称空间导入当前架构。schemaLocation
属性只不过是一个关于在哪里找到另一个名称空间的提示在
B.xsd
的情况下,您是说要导入名称空间http://blah.org
,该名称空间由A.xsd
中的模式处理在
A.xsd
的情况下,B.xsd
的导入没有指定要导入的名称空间如果
A.xsd
和B.xsd
代表不同的名称空间,那么import
需要显式指定另一方面,如果您只是试图将另一个模式文件中的元素内联到同一名称空间中,那么
include
指令更合适编辑:好的,看过你的模式片段后,我可以说
<xs:import>
绝对不是正确的做法。A.xsd
和B.xsd
都是在同一名称空间(http://foo.org/A
)中定义元素,因此应该使用<xs:include>
当Java遇到一个
<xs:import>
,并且该导入的名称空间是它已经知道的名称空间时,它实际上会忽略它。因此,当它解析B.xsd
(在名称空间http://foo.org/A
)时,它会为同一名称空间找到一个导入,它会忽略它