I have a servlet that uses a utility packaged in a .jar archive:
@Override public void init() throws ServletException { ... try (InputStream stream = getClass().getResourceAsStream("/fileToParse.xml")) { App.check(stream); } catch (Exception e) { throw new ServletException(e); } ... }
This utility accepts a stream of XML files, checks using the xsd schema, and parses it:
public class App { private static final String JAXP_SCHEMA_LANGUAGE = "http://java.sun.com/xml/jaxp/properties/schemaLanguage"; private static final String W3C_XML_SCHEMA = "http://www.w3.org/2001/XMLSchema"; ... public static void check(InputStream stream) { SAXParserFactory spf = SAXParserFactory.newInstance(); spf.setNamespaceAware(true); spf.setValidating(true); MyHandler handler = new MyHandler(); try { SAXParser sp = spf.newSAXParser(); sp.setProperty(JAXP_SCHEMA_LANGUAGE, W3C_XML_SCHEMA); XMLReader rdr = sp.getXMLReader(); rdr.setContentHandler(handler); rdr.setErrorHandler(new MyErrorHandler()); rdr.parse(new InputSource(stream)); } ... } ... }
The xsd file starts with:
<?xml version="1.0" encoding="UTF-8"?> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.mydomain.org" elementFormDefault="qualified" xmlns:t="http://www.mydomain.org"> <xs:element name="appContext"> ...
xml file:
<?xml version="1.0" encoding="UTF-8"?> <appContext xmlns="http://www.mydomain.org" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.mydomain.org appContext.xsd"> ...
.war structure:
css/ js/ WEB-INF/ classes/ mypackage/ MyServlet.class fileToParse.xml lib/ App.jar web.xml
App.jar structure:
mypackage2/ App.class appContext.xsd
The Servlet Init method throws an exception:
... at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) [na:1.7.0_21] at java.lang.Thread.run(Thread.java:722) [na:1.7.0_21] Caused by: java.io.FileNotFoundException: /PATH_TO_TOMCAT/bin/appContext.xsd (No such file or directory) at java.io.FileInputStream.open(Native Method) ~[na:1.7.0_21] at java.io.FileInputStream.<init>(FileInputStream.java:138) ~[na:1.7.0_21]
How can I tell SAXParser where the xsd schema is needed to validate the XML file?
PS sorry for my bad english
UPD:
I am trying to add this property:
private static final String JAXP_SCHEMA_SOURCE = "http://java.sun.com/xml/jaxp/properties/schemaSource"; .... public static void check(InputStream stream) { ... try { ... sp.setProperty(JAXP_SCHEMA_SOURCE, new File(getPath("/appContext.xsd"))); ... } } public static String getPath(String path) { return App.class.getResource(path).toString(); }
Now I have this exception:
ERROR mypackage2.App - Error: URI=null Line=5: schema_reference.4: Failed to read schema document 'jar:file:/PATH_TO_TOMCAT/webapps/myapp/WEB-INF/lib/App.jar!/appContext.xsd', because 1) could not find the document; 2) the document could not be read; 3) the root element of the document is not <xsd:schema>. org.xml.sax.SAXParseException: schema_reference.4: Failed to read schema document 'jar:file:/PATH_TO_TOMCAT/webapps/myapp/WEB-INF/lib/App.jar!/appContext.xsd', because 1) could not find the document; 2) the document could not be read; 3) the root element of the document is not <xsd:schema>. at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.createSAXParseException(ErrorHandlerWrapper.java:198) ~[na:1.7.0_21]
UPD2: From "classpath: appContext.xsd" in the xml file:
WARN mypackage.App - Warning: URI=null Line=5: schema_reference.4: Failed to read schema document 'classpath:appContext.xsd', because 1) could not find the document; 2) the document could not be read; 3) the root element of the document is not <xsd:schema>. org.xml.sax.SAXParseException: schema_reference.4: Failed to read schema document 'classpath:appContext.xsd', because 1) could not find the document; 2) the document could not be read; 3) the root element of the document is not <xsd:schema>. at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.createSAXParseException(ErrorHandlerWrapper.java:198) ~[na:1.7.0_21] ... at java.lang.Thread.run(Thread.java:722) [na:1.7.0_21] Caused by: java.net.MalformedURLException: unknown protocol: classpath at java.net.URL.<init>(URL.java:592) ~[na:1.7.0_21 ;;;