0

我正在尝试使用 Android 15 中的 exificient-grammars 库创建语法(c 是上下文)

Grammars g = GrammarFactory.newInstance().createGrammars(c.getAssets().open("svg.xsd"));

从 svg.xsd 导入另外两个模式:xlink.xsd 和 namespace.xsd。这两个文件随 svg.xsd 出现(如您所见,它们位于 svg.xsd 的根目录中。但是我没有创建语法,而是得到了这个异常:

com.siemens.ct.exi.exceptions.EXIException: Problem occured while building XML Schema Model (XSModel)!
    . [xs-warning] schema_reference.4: Failed to read schema document 'xlink.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>.
    . [xs-warning] schema_reference.4: Failed to read schema document 'namespace.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>.

使用 import的两行svg.xsd是:

<xs:import namespace="http://www.w3.org/1999/xlink" schemaLocation="xlink.xsd"/>
<xs:import namespace="http://www.w3.org/XML/1998/namespace" schemaLocation="namespace.xsd"/>

到目前为止我已经尝试过:

  1. 我天真地试图合并 svg.xsd 中的两个 xsd 只是明白我根本不知道 xsd 文件是如何工作的。
  2. 跟踪消息来源,SchemaInformedGrammars.class但我不明白是什么systemId
  3. (编辑)按照此处支持的建议(第二篇文章)我用来com.siemens.ct.exi.grammars.XSDGrammarsBuilder创建语法:
XSDGrammarsBuilder xsd = XSDGrammarsBuilder.newInstance();
xsd.loadGrammars(c.getAssets().open("namespace.xsd"));
xsd.loadGrammars(c.getAssets().open("xlink.xsd"));
xsd.loadGrammars(c.getAssets().open("svg.xsd"));
SchemaInformedGrammars sig = xsd.toGrammars();
exiFactory.setGrammars(sig);

只是为了得到完全相同的错误......

我的问题: 问题似乎是解析器无法找到另外两个文件。有没有办法以某种方式包含这些文件,以便解析器可以找到它们?

4

1 回答 1

0

exificient开发团队的 danielpeintner 将我推向了正确的方向(issue here)。

createGrammar(InputStream)Daniel 建议我使用,而不是使用createGrammar(String, XMLEntityResolver),并且还提供了我自己的XMLEntityResolver实现。我的实现是这样的:

public class XSDResolver implements XMLEntityResolver {

    Context context;

    public XSDResolver(Context context){
        this.context = context;
    }

    @Override
    public XMLInputSource resolveEntity(XMLResourceIdentifier resourceIdentifier) throws XNIException, IOException {
        String literalSystemId = resourceIdentifier.getLiteralSystemId();

        if("xlink.xsd".equals(literalSystemId)){
            InputStream is = context.getAssets().open("xlink.xsd");
            return new XMLInputSource(null, null, null, is, null);
        } else if("namespace.xsd".equals(literalSystemId)){
            InputStream is = context.getAssets().open("namespace.xsd");
            return new XMLInputSource(null, null, null, is, null);
        } else if("svg.xsd".equals(literalSystemId)){
            InputStream is = context.getAssets().open("svg.xsd");
            return new XMLInputSource(null, null, null, is, null);
        }
        return null;
    }
}

像这样调用createGrammar(String, XMLEntityResolver)

exiFactory.setGrammars(GrammarFactory.newInstance().createGrammars("svg.xsd", new XSDResolver(c)));
于 2019-10-07T13:42:57.177 回答