views:

115

answers:

1

I'm attempting to parse load a rather complicated XML schema into a Schema object in Java so I can do some validation on XML messages.

My code looks similar to this:

SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
Schema schema = factory.newSchema(new StreamSource(new File("schema/schema.xsd")));

My schema has quite a few imports:

<?xml version="1.0" encoding="UTF-8"?>
  <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns="base_1">
  <xs:import namespace="base_1" schemaLocation="common/MessageBase.xsd"/>
</xs:schema>

...etc. When I attempt to load the schema, I get lots of errors. Based on one other question related to this, it looks like I need to specify a resource resolver, but isn't this something that should be handled by default?

If so, is there a specific directory I need to put the schema in relative to where I run the application I'm writing or relative to the base schema file?

Finally, when I load the schema with XMLSpy or similar, it works fine and I can validate XML instances with no problem.

+1  A: 

I think that the use of StreamSource, without specifying the base location, is the source of your problem.

The parser has no way of knowing where the main schema is, so it can't resolve common/MessageBase.xml.

Use the two-argument constructor and pass in a SystemID that is the pathname where you're starting from.

See the javadoc for StreamSource.

bmargulies
Tried this and still get the following error: src-resolve: Cannot resolve the name 'base:StatusWithError_optional' to a(n) 'attribute group' component.
magneticMonster
That's a different issue. It suggests that your schema is not complete and self-contained. Do you have an attribute group named StatusWithError_optional? Is it in the right namespace?
bmargulies
Yep, it's defined in a separate file at the same level as the base schema file. Same namespace. Should the systemID be the path to the root .xsd file or to the root directory for the schema? How about the other argument of the 2-arg constructor?
magneticMonster
the system ID should be the path to the entire schema. Again, the error you are getting indicates that finding the imported schema is working, but now there's an actual problem with the content of the schema. The first arg is just the stream or the reader, after all.
bmargulies
Is there a way to get more information about how the schema is being parsed? What order the files are being loaded, where in the file it's running into these errors, etc.? (Thanks for your help, by the way)
magneticMonster
You need to read it all into a text editor and poke around. You could also try reading it with Apache XmlSchema, it might or might not be more informative.
bmargulies