Reputation: 1325
Just wondering if there are any ways to parse a xsd file AND an xsd that's imported in the original xsd at the same time, so I can get direct access to the elements in the imported xsd. Are there any frameworks that makes this possible?
Just an example of what I mean
From the XSD that I want to parse:
<xsd:import namespace="..." schemaLocation="anotherFile.xsd">
<xsd:element ref="anElement" />
From the XSD that's imported in the parsed file
<xsd:element name="anElement">
<xsd:simpleType>
<xsd:restriction base="xsd:string">
<xsd:enumeration value="THIS" />
<xsd:enumeration value="IS" />
<xsd:enumeration value="THE" />
<xsd:enumeration value="ELEMENTS" />
<xsd:enumeration value="I" />
<xsd:enumeration value="WANT" />
<xsd:enumeration value=":-)" />
</xsd:restriction>
</xsd:simpleType>
</xsd:element>
So, What I want is to get access to the elements in the imported xsd when I'm parsing the original xsd by some kind of inlining or something :-)
Is this possible in some way?
Upvotes: 3
Views: 4267
Reputation: 280
This works for me when the XSD files are either on local /src/main/resources directory or packed in a jar:
final SchemaFactory sf = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
final URL url = this.getClass().getClassLoader().getResource("META-INF/parent.xsd");
final Schema schema = sf.newSchema(url);
parent.xsd has included "kid.xsd" -- both XSD files are under the same directory
Upvotes: 1
Reputation: 12175
Yes, you just need to implement a LSResourceResolver class that will able to read from the schema locations you specify:
/**
* This function validates a DomResult. T
*
* @param domResult
* @param schemaFile path to the schmea file to validate against.
* @throws org.xml.sax.SAXException
* @throws java.io.IOException
*
*/
protected void validateDomResult(DOMResult domResult, String schemaFile) throws SAXException, IOException, Exception {
Schema schema = createSchema(schemaFile);
javax.xml.validation.Validator validator = schema.newValidator();
ErrorHandler mySchemaErrorHandler = new LoggingErrorHandler();
validator.setErrorHandler(mySchemaErrorHandler);
DOMSource domSource = new DOMSource(domResult.getNode());
validator.validate(domSource);
if (((LoggingErrorHandler) mySchemaErrorHandler).isError()) {
throw new Exception("Validation Error");
}
}
/**
*
* @param baseSchemaFilePath
* @return
* @throws java.lang.Exception
*
*/
protected Schema createSchema(String baseSchemaFilePath) throws Exception {
SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
LSResourceResolver resourceResolver = (LSResourceResolver) new LocalSchemaLSResourceResolver();
factory.setResourceResolver(resourceResolver);
Schema schema = factory.newSchema(new File(baseSchemaFilePath));
return schema;
}
Here is a simple LSResourceResolver implementation that looks for schemas in an xsd directory on the class path:
public class LocalSchemaLSResourceResolver implements LSResourceResolver{
protected final Log logger = LogFactory.getLog(getClass());
public LSInput resolveResource(String type, String namespaceURI, String publicId, String systemId, String baseURI) {
LSInput input = new DOMInputImpl();
try {
FileInputStream fis = new FileInputStream(new File("classpath:xsd/" + systemId));
input.setByteStream(fis);
return input;
} catch (FileNotFoundException ex) {
logger.error("File Not found", ex);
return null;
}
}
}
Upvotes: 2
Reputation: 2354
It look like you need JAXB to get your schema (including imported schema) into Java classes.
Upvotes: 1