2015-12-03 80 views
0

我試圖驗證xml,但我試圖在沒有Internet連接的情況下執行此操作。因此,我嘗試下載所需的所有XSD,並將導入更改爲本地文件,但無法找到一些定義。奇怪的是,當我命令+單擊IntelliJ中的違規行時,它將我帶到正確的本地XSD。Java XML驗證:無法解析本地XSD文件中的定義

我已經寫了演示問題小例子,在這裏貼吧:https://github.com/spearskw/testXsd

這裏是堆棧跟蹤我得到的,當我嘗試運行它:

org.xml.sax.SAXParseException; systemId: file:/Users/kevin/repo/xsdTest/target/classes/schemas/saml-schema-protocol-2.0.xsd; lineNumber: 32; columnNumber: 56; src-resolve: Cannot resolve the name 'ds:Signature' to a(n) 'element declaration' component. 
at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.createSAXParseException(ErrorHandlerWrapper.java:203) 
at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.error(ErrorHandlerWrapper.java:134) 
at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(XMLErrorReporter.java:437) 
at com.sun.org.apache.xerces.internal.impl.xs.traversers.XSDHandler.reportSchemaErr(XSDHandler.java:4162) 
at com.sun.org.apache.xerces.internal.impl.xs.traversers.XSDHandler.reportSchemaError(XSDHandler.java:4145) 
at com.sun.org.apache.xerces.internal.impl.xs.traversers.XSDHandler.getGlobalDecl(XSDHandler.java:1678) 
at com.sun.org.apache.xerces.internal.impl.xs.traversers.XSDElementTraverser.traverseLocal(XSDElementTraverser.java:170) 
at com.sun.org.apache.xerces.internal.impl.xs.traversers.XSDHandler.traverseLocalElements(XSDHandler.java:3618) 
at com.sun.org.apache.xerces.internal.impl.xs.traversers.XSDHandler.parseSchema(XSDHandler.java:633) 
at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaLoader.loadSchema(XMLSchemaLoader.java:617) 
at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaLoader.loadGrammar(XMLSchemaLoader.java:575) 
at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaLoader.loadGrammar(XMLSchemaLoader.java:541) 
at com.sun.org.apache.xerces.internal.jaxp.validation.XMLSchemaFactory.newSchema(XMLSchemaFactory.java:255) 
at javax.xml.validation.SchemaFactory.newSchema(SchemaFactory.java:638) 
at javax.xml.validation.SchemaFactory.newSchema(SchemaFactory.java:670) 
at testXsd.TestSchemaValidation.validateSaml(TestSchemaValidation.java:35) 
at testXsd.TestSchemaValidation.main(TestSchemaValidation.java:57) 
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
at java.lang.reflect.Method.invoke(Method.java:497) 
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144) 

回答

2

由於您的架構引用在類路徑中,你必須提供一個資源定位符SchemaFactory可以:

SchemaFactory sf = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); 
     sf.setResourceResolver(new LocalSchemaLSResourceResolver()); 

凡解析器是類似的東西:

public static class LocalSchemaLSResourceResolver implements LSResourceResolver{ 
    private static final String CARPETA_XSD = "META-INF/xsd/"; 

    //@Override 
    public LSInput resolveResource(String type, String namespaceURI, String publicId, String systemId, String baseURI) 
    { 

     try { 
      LSInput input = ((DOMImplementationLS)DOMImplementationRegistry.newInstance().getDOMImplementation("LS")).createLSInput(); 
      input.setByteStream(Thread.currentThread().getContextClassLoader().getResourceAsStream(CARPETA_XSD+systemId.replace("../",""))); 

      return input; 
     } 
     catch(Exception e) 
     { 
      throw ExceptionWrapper.wrap(e,"Imposible encontrar importacion type=%, namespace=%, publicId=%, systemId=%, baseURI=%", type,namespaceURI, publicId, systemId, baseURI); 
     } 

    } 
} 

在您的情況下,您必須將「META-INF/xsd」替換爲「schemas /」。

+0

謝謝你的建議!我嘗試了這個,但它似乎仍然不工作 - 我收到了同樣的錯誤。 – Kevin

+0

「schemas /」目錄必須位於您的類路徑中,以便ContextClassLoader可以找到資源 – Mike