views:

433

answers:

1

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.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.

+1  A: 

<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.

skaffman
Thanks for the reply. I added details to my question by showing how my <xs:schema> elements are defined.
Elliot