我有两个具有循环依赖关系的模式A和B(这是一个中间步骤)。我使用的XML文件作为输入,根据xmllint和Visual对模式进行验证。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:找不到元素foo的声明。
我已经通过(伪)设置了模式:
InputStream in = .. A.xsd
SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
return factory.newSchema(new StreamSource(in);
有人能解释我做错了什么吗?谢谢。
发布于 2010-02-12 06:27:18
<xs:import>
用于将其他架构中定义的命名空间导入到当前架构中。schemaLocation
属性只不过是在哪里找到其他名称空间的一个提示。
在B.xsd
的例子中,您说要导入名称空间http://blah.org
,并且该名称空间由A.xsd
中的模式处理。
在A.xsd
的情况下,B.xsd
的导入没有指定要导入的名称空间。
如果A.xsd
和B.xsd
表示不同的命名空间,那么import
需要显式地指定它。
另一方面,如果您只是试图在同一个命名空间中内联来自另一个模式文件的元素,那么include
指令就更合适了。
编辑: OK,看过您的模式片段之后,我可以说<xs:import>
绝对不是应该做的事情。A.xsd
和B.xsd
都在同一个名称空间(http://foo.org/A
)中定义元素,因此您应该使用<xs:include>
。
当Java遇到一个<xs:import>
,而且导入的名称空间是它已经知道的名称空间时,它实际上会忽略它。因此,当它解析B.xsd
(在名称空间http://foo.org/A
中)时,当它为同一个名称空间找到一个导入时,它会忽略它。
https://stackoverflow.com/questions/2252337
复制