I have two schemas A and B with a circular dependency (it's an intermediate step). The XML files I'm using as input validate against the schema according to xmllint and Visual Studio. Eclipse is telling me that both schemas contain two global components with the same name.
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.开发者_JAVA技巧xsd" />
The XSD I'm passing to the Unmarshaller is A.xsd. When it encounters an element defined in B.xsd, it complains:
org.xml.sax.SAXParseException: cvc-elt.1: Cannot find declaration of element 'foo'.
I've set the schema via (pseudo):
InputStream in = .. A.xsd
SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
return factory.newSchema(new StreamSource(in);
Can anyone explain what I'm doing wrong? Thanks.
<xs:import>
is used to import namespaces defined in other schema into the current schema. The schemaLocation
attribute is nothing more than a hint as to where to find that other namespace.
In the case of B.xsd
, you're saying that you want to import the namespace http://blah.org
, and that that namespace is handled by the schema in A.xsd
.
In the case of A.xsd
, your import of B.xsd
is not specifying which namespace you're importing.
If A.xsd
and B.xsd
are representing different namespaces, then the import
needs to specify that explicitly.
If, on the other hand, you're just trying to inline the elements from another schema file, in the same namespace, then the include
directive is more appropriate.
edit: OK, having seen your schema fragments, I can say that <xs:import>
is definitely not the right thing to do. Both A.xsd
and B.xsd
are defining elements in the same namespace (http://foo.org/A
), and so you should be using <xs:include>
instead.
When Java encounters an <xs:import>
, and the namespace of that import is a namespace that it already knows about, then it effectively ignores it. So as it's parsing B.xsd
(in namespace http://foo.org/A
), and it finds an import for that same namespace, it ignores it.
精彩评论