开发者

Why can't my JAXB Unmarshaller find an element declared in an imported schema?

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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜