0

私のプログラムでは、XML ファイルを生成しており、異なる URL にある複数のスキーマに対してその XML ファイルを検証する必要があります。その XML ファイルをすべてのスキーマに対して 1 回だけ検証する必要があります。

ソースフラグメント:

// here source array contain the locations of schemas, located at diff servers.
Source[] source = {
        new StreamSource(
                new URL("http://localhost:8081/test1/testSchema1.xsd")
                        .openStream()),
        new StreamSource(
                new URL(
                        "http://ccr.internal.ericsson.com/test2/testSchema2.xsd")
                        .openStream()) };

try {
    // Compile the schema, which loaded from schemaFileLocation.
    Schema schemaGrammar = schemaFactory.newSchema(source);

    // Create a validator for schema.
    Validator configValidator = schemaGrammar.newValidator();

    // set error handler with validator.
    SchemaValidator schemaValidator = new SchemaValidator();
    configValidator
            .setErrorHandler(schemaValidator.new MessageHandler());

    // validate xml instance against the grammar.
    configValidator.validate(new StreamSource(new File("xmlFile.xml")));
    System.out.println("\n");
} catch (SAXException e) {
    e.printStackTrace();
} catch (IOException e) {
    e.printStackTrace();
}

上記のコード フラグメントを実行すると、次のエラーが発生します。

org.xml.sax.SAXParseException: src-resolve: 名前 'xn:SubNetwork' を (n) '要素宣言' コンポーネントに解決できません。org.apache.xerces.util.ErrorHandlerWrapper.createSAXParseException (未知のソース) で org.apache.xerces.util.ErrorHandlerWrapper.error (未知のソース) で org.apache.xerces.impl.XMLErrorReporter.reportError (未知のソース) で org org.apache.xerces.impl.xs.traversers.XSDHandler.reportSchemaError (不明なソース) org.apache.xerces.impl.xs.traversers.XSDHandler.getGlobalDecl (不明なソース) org.apache.xerces.impl.xs.traversers で.XSDElementTraverser.traverseLocal (不明なソース) org.apache.xerces.impl.xs.traversers.XSDElementTraverser.traverseLocal (不明なソース) org.apache.xerces.impl.xs.traversers.XSDAbstractParticleTraverser.

コードの問題は何ですか?複数のスキーマに対して検証する他の方法はありますか?

4

2 に答える 2

1

このトピックに関する投稿はかなり多く、満足のいく解決策も見つかりませんでした。これが私にとってどのように機能したかです。SchemaFactory にカスタム リソース リゾルバーを与える


    Source source = new StreamSource(this.getClass().getResourceAsStream("ebics.xsd"));
    LSResourceResolver resolver = new ResourceResolver(schemaFactory.getResourceResolver());
    schemaFactory.setResourceResolver(resolver);
    

最上位のスキーマのみを解析します。その後、リゾルバは(うまくいけば)埋め込まれた参照を解決できます


public class ResourceResolver implements LSResourceResolver {
    private LSResourceResolver parent = null;
    private Set returnedResources = new HashSet();


    public ResourceResolver(LSResourceResolver r){
    parent = r;
    }

    private ResourceResolver() {
    }

    public LSInput resolveResource(String type, String namespaceURI, String publicId, String systemId, String baseURI) {
    LSInput input = new LSInputImpl();

    if (returnedResources.contains(systemId)) {
        return null;
    } else if (systemId.equals("ebics_hev.xsd")) {
        input.setByteStream(this.getClass().getResourceAsStream("ebics_hev.xsd"));
    } else if (systemId.equals("ebics_keymgmt_request.xsd")) {
        input.setByteStream(this.getClass().getResourceAsStream("ebics_keymgmt_request.xsd"));
    } else if (systemId.equals("ebics_keymgmt_response.xsd")) {
        input.setByteStream(this.getClass().getResourceAsStream("ebics_keymgmt_response.xsd"));
    } else if (systemId.equals("ebics_orders.xsd")) {
        input.setByteStream(this.getClass().getResourceAsStream("ebics_orders.xsd"));
    } else if (systemId.equals("ebics_request.xsd")) {
        input.setByteStream(this.getClass().getResourceAsStream("ebics_request.xsd"));
    } else if (systemId.equals("ebics_response.xsd")) {
        input.setByteStream(this.getClass().getResourceAsStream("ebics_response.xsd"));
    } else if (systemId.equals("ebics_signature.xsd")) {
        input.setByteStream(this.getClass().getResourceAsStream("ebics_signature.xsd"));
    } else if (systemId.equals("ebics_types.xsd")) {
        input.setByteStream(this.getClass().getResourceAsStream("ebics_types.xsd"));
    } else if (systemId.equals("ebics.xsd")) {
        input.setByteStream(this.getClass().getResourceAsStream("ebics.xsd"));
    } else if (systemId.equals("xmldsig-core-schema.xsd")) {
        input.setByteStream(this.getClass().getResourceAsStream("xmldsig-core-schema.xsd"));
    } else {
        return parent.resolveResource(type, namespaceURI, publicId, systemId, baseURI);
    }
    returnedResources.add(systemId);
    return input;
    }

}

ここにLSInputImplがあります


public class LSInputImpl implements LSInput
{

    public Reader getCharacterStream () {
        return null;
    }

    public void setCharacterStream ( Reader characterStream ) {}

    public InputStream getByteStream () {
        InputStream retval = null;
        if ( byteStream != null ) {
            retval = byteStream;
        }
        return retval;
    }

    public void setByteStream ( InputStream byteStream ) {
        this.byteStream = byteStream;
    }

    public String getStringData () {
        return null;
    }

    public void setStringData ( String stringData ) {}

    public String getSystemId () {
        return systemId;
    }

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

    public String getPublicId () {
        return null;
    }

    public void setPublicId ( String publicId ) {}

    public String getBaseURI () {
        return null;
    }

    public void setBaseURI ( String baseURI ) {}

    public String getEncoding () {
        return null;
    }

    public void setEncoding ( String encoding ) {}

    public boolean getCertifiedText () {
        return false;
    }

    public void setCertifiedText ( boolean certifiedText ) {}


    private String systemId = null;
    private InputStream byteStream = null;
}

于 2011-02-09T13:35:40.557 に答える
1

私も同じ問題を抱えていました。

スキーマの順序を入れ替えました。

最初にすべての子スキーマをインポートし、最後にメイン スキーマを設定しました。

Source[] sources = new Source[] { new StreamSource(new InputStreamReader(SomeClass.class.getResourceAsStream("/com/foo/subschema1.xsd"), "UTF-8")), 
                              new StreamSource(new InputStreamReader(SomeClass.class.getResourceAsStream("/com/foo/subschema2.xsd"), "UTF-8")),
                              new StreamSource(new InputStreamReader(SomeClass.class.getResourceAsStream("/com/foo/subschema3.xsd"), "UTF-8")),
                              ...
                              new StreamSource(new InputStreamReader(SomeClass.class.getResourceAsStream("/com/foo/mainschema.xsd"), "UTF-8"))};
于 2013-12-18T09:09:20.220 に答える