2016-04-28 10 views
0

私はインポートとインクルードを使用するスキーマのxsdバリデータを実装しようとしています。私は例えばthis answerを取った。リソースを解決してストリームを閉じました

public void validate(String filePath, String schemaName) throws Exception 
{ 
    SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); 
    factory.setResourceResolver(new ResourceResolver()); 
    Source schemaFile = new StreamSource(getClass().getClassLoader().getResourceAsStream(schemaName)); 
    Schema schema = factory.newSchema(schemaFile); 
    Validator validator = schema.newValidator(); 
    validator.setErrorHandler(new MySAXParseErrorHandler()); 
    validator.validate(new StreamSource(filePath)); 
} 

LSInput(全く同じ):

public class LSInputImpl implements LSInput 
{ 

private String publicId; 

private String systemId; 

public String getPublicId() 
{ 
    return publicId; 
} 

public void setPublicId(String publicId) 
{ 
    this.publicId = publicId; 
} 

public String getBaseURI() 
{ 
    return null; 
} 

public InputStream getByteStream() 
{ 
    return null; 
} 

public boolean getCertifiedText() 
{ 
    return false; 
} 

public Reader getCharacterStream() 
{ 
    return null; 
} 

public String getEncoding() 
{ 
    return null; 
} 

public String getStringData() 
{ 
    synchronized (inputStream) { 
     try { 
      byte[] input = new byte[inputStream.available()]; 
      inputStream.read(input); 
      String contents = new String(input); 
      return contents; 
     } catch (IOException e) { 
      e.printStackTrace(); 
      System.out.println("Exception " + e); 
     } 
     return null; 
    } 
} 

public void setBaseURI(String baseURI) 
{ 
} 

public void setByteStream(InputStream byteStream) 
{ 
} 

public void setCertifiedText(boolean certifiedText) 
{ 
} 

public void setCharacterStream(Reader characterStream) 
{ 
} 

public void setEncoding(String encoding) 
{ 
} 

public void setStringData(String stringData) 
{ 
} 

public String getSystemId() 
{ 
    return systemId; 
} 

public void setSystemId(String systemId) 
{ 
    this.systemId = systemId; 
} 

public BufferedInputStream getInputStream() 
{ 
    return inputStream; 
} 

public void setInputStream(BufferedInputStream inputStream) 
{ 
    this.inputStream = inputStream; 
} 

private BufferedInputStream inputStream; 

public LSInputImpl(String publicId, String sysId, InputStream input) 
{ 
    this.publicId = publicId; 
    this.systemId = sysId; 
    this.inputStream = new BufferedInputStream(input); 
} 

}

ResourceResolver:

public class ResourceResolver implements LSResourceResolver 
{ 

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


    InputStream resourceAsStream = this.getClass().getClassLoader().getResourceAsStream(systemId);  
    return new LSInputImpl(publicId, systemId, resourceAsStream); 
} 

}

012ここ

は私の検証方法であって、

私はxsdでインポートのみを持つxmlを検証しようとしていますが、正常に動作します。しかし、私には、使用して、2つに1つのスキーマを分割するとき、プロセスはIOExceptionを表示して失敗します。

java.io.IOException: Stream closed 
at java.io.BufferedInputStream.getInIfOpen(BufferedInputStream.java:159) 
at java.io.BufferedInputStream.available(BufferedInputStream.java:410) 
at LSInputImpl.getStringData(LSInputImpl.java:57) 
at com.sun.org.apache.xerces.internal.util.DOMEntityResolverWrapper.resolveEntity(DOMEntityResolverWrapper.java:130) 
at com.sun.org.apache.xerces.internal.impl.XMLEntityManager.resolveEntity(XMLEntityManager.java:1073) 
at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaLoader.resolveDocument(XMLSchemaLoader.java:659) 
at com.sun.org.apache.xerces.internal.impl.xs.traversers.XSDHandler.resolveSchemaSource(XSDHandler.java:2105) 
at com.sun.org.apache.xerces.internal.impl.xs.traversers.XSDHandler.constructTrees(XSDHandler.java:1088) 
at com.sun.org.apache.xerces.internal.impl.xs.traversers.XSDHandler.constructTrees(XSDHandler.java:1120) 
at com.sun.org.apache.xerces.internal.impl.xs.traversers.XSDHandler.parseSchema(XSDHandler.java:620) 
at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaLoader.loadSchema(XMLSchemaLoader.java:616) 
at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaLoader.loadGrammar(XMLSchemaLoader.java:574) 
at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaLoader.loadGrammar(XMLSchemaLoader.java:540) 
at com.sun.org.apache.xerces.internal.jaxp.validation.XMLSchemaFactory.newSchema(XMLSchemaFactory.java:255) 
at javax.xml.validation.SchemaFactory.newSchema(SchemaFactory.java:638) 
at Main.validate(Main.java:54) 
at Main.main(Main.java:68) 
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:483) 
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144) 

org.xml.sax.SAXParseException; systemId: file:///C:/Users/adobryn/Java/sub/schema.xsd; lineNumber: 456; columnNumber: 73; src-resolve: Cannot resolve the name 'st_Term' to a(n) 'type definition' 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:1741) 
at com.sun.org.apache.xerces.internal.impl.xs.traversers.XSDElementTraverser.traverseNamedElement(XSDElementTraverser.java:405) 
at com.sun.org.apache.xerces.internal.impl.xs.traversers.XSDElementTraverser.traverseLocal(XSDElementTraverser.java:194) 
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:616) 
at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaLoader.loadGrammar(XMLSchemaLoader.java:574) 
at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaLoader.loadGrammar(XMLSchemaLoader.java:540) 
at com.sun.org.apache.xerces.internal.jaxp.validation.XMLSchemaFactory.newSchema(XMLSchemaFactory.java:255) 
at javax.xml.validation.SchemaFactory.newSchema(SchemaFactory.java:638) 
at Main.validate(Main.java:54) 
at Main.main(Main.java:68) 
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:483) 
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144) 

スキーマでは、次のとおり

<?xml version="1.0" encoding="UTF-8"?> 
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://www.w3.org/schema" targetNamespace="http://www.w3.org/schema" elementFormDefault="qualified">  
    <xsd:include schemaLocation="st_Term.xsd"/> 
    <xsd:element name="Term" type="st_Term" minOccurs="0" maxOccurs="1"/> 
</xsd:schema> 

は、私が思うに、getStringData()メソッドに何か問題があります。どうすれば修正できますか?ご協力いただきありがとうございます!

+0

'InputStream.available()'の使用は、特にJavadocで警告されています。あなたは 'InputStream.read()'の結果を無視しています。これは1にもなるかもしれませんが、実際は-1です。 – EJP

答えて

1

、それはまた、XSDを含まインクルードを持っていて、ResourceResolverはそのサブフォルダが含まれていたresources/subではなく、resourcesフォルダ内でそれを探しました。これはpath trackingという別の例をとりました。それは今働いています:)そのschemaBasePathは "/"で始まることに注意してください。

-1

私は数年前に.xsdのインクルードに同じ問題がありました。

私の問題は、.xsdリソースとそのインクルードがリソース内のいくつかのパッケージ(ディレクトリ)に配置されていたことを思い出すことができます。

私はパッケージがコンストラクタに渡され、次のResourceResolver(resourceRoot引数)でそれを解決してきました:

class ResourceResolver implements LSResourceResolver { 

    private String resourceRoot; 

    public ResourceResolver(String resourceRoot) { 
     this.resourceRoot = resourceRoot; 
    } 

    public LSInput resolveResource(String type, String namespaceURI,String publicId, String systemId, String baseURI) { 
     InputStream resourceAsStream = this.getClass().getResourceAsStream(resourceRoot + "/" + systemId); 
     return new Input(publicId, systemId, resourceAsStream); 
    } 

} 

と入力:

問題だった
static class Input implements LSInput { 

    private String publicId; 

    private String systemId; 

    public String getPublicId() { 
     return publicId; 
    } 

    public void setPublicId(String publicId) { 
     this.publicId = publicId; 
    } 

    public String getBaseURI() { 
     return null; 
    } 

    public InputStream getByteStream() { 
     return null; 
    } 

    public boolean getCertifiedText() { 
     return false; 
    } 

    public Reader getCharacterStream() { 
     return null; 
    } 

    public String getEncoding() { 
     return null; 
    } 

    public String getStringData() { 
     synchronized (inputStream) { 
      try { 
       byte[] input = new byte[inputStream.available()]; 
       inputStream.read(input); 
       String contents = new String(input, "UTF-8"); 
       return contents; 
      } catch (IOException e) { 
       e.printStackTrace(); 
       System.out.println("Exception " + e); 
       return null; 
      } 
     } 
    } 

    public void setBaseURI(String baseURI) { 
    } 

    public void setByteStream(InputStream byteStream) { 
    } 

    public void setCertifiedText(boolean certifiedText) { 
    } 

    public void setCharacterStream(Reader characterStream) { 
    } 

    public void setEncoding(String encoding) { 
    } 

    public void setStringData(String stringData) { 
    } 

    public String getSystemId() { 
     return systemId; 
    } 

    public void setSystemId(String systemId) { 
     this.systemId = systemId; 
    } 

    private final BufferedInputStream inputStream; 

    public Input(String publicId, String sysId, InputStream input) { 
     this.publicId = publicId; 
     this.systemId = sysId; 
     this.inputStream = new BufferedInputStream(input); 
    } 
} 
+0

'InputStream.available()'の使用は、特にJavadocで警告されます。あなたは 'InputStream.read()'の結果を無視しています。 – EJP

関連する問題