带有 import 关键字的异常 "schema_reference.4: Failed to read schema document xxx.xsd"
Exificient exception "schema_reference.4: Failed to read schema document xxx.xsd" with import keyword
我正在尝试使用 Android 15 中的 exificient-grammars 库创建语法(c 是上下文)
Grammars g = GrammarFactory.newInstance().createGrammars(c.getAssets().open("svg.xsd"));
from svg.xsd,它又导入了两个模式:xlink.xsd 和 namespace.xsd。这两个文件随 svg.xsd 一起出现(如您所见,它们位于 svg.xsd here 的根目录中)。但是我没有创建语法,而是得到了这个异常:
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>.
svg.xsd
中使用import的两行是:
<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"/>
到目前为止我尝试过的:
- 我曾经天真地尝试将两个 xsd 合并到 svg.xsd 中,结果只明白我根本不知道 xsd 文件是如何工作的。
- 一直关注到
SchemaInformedGrammars.class
但我不明白 systemId
是什么。
- (编辑)按照支持 here(第二个 post)的建议,我使用
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);
只得到完全相同的错误...
我的问题:
问题似乎是解析器无法找到另外两个文件。有没有办法以某种方式包含这些文件以便解析器可以找到它们?
来自 exificient 开发团队的 danielpeintner 将我推向了正确的方向(issue here)。
Daniel 建议我使用 createGrammar(String, XMLEntityResolver)
而不是 createGrammar(InputStream)
,并提供我自己的 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)));
我正在尝试使用 Android 15 中的 exificient-grammars 库创建语法(c 是上下文)
Grammars g = GrammarFactory.newInstance().createGrammars(c.getAssets().open("svg.xsd"));
from svg.xsd,它又导入了两个模式:xlink.xsd 和 namespace.xsd。这两个文件随 svg.xsd 一起出现(如您所见,它们位于 svg.xsd here 的根目录中)。但是我没有创建语法,而是得到了这个异常:
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>.
svg.xsd
中使用import的两行是:
<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"/>
到目前为止我尝试过的:
- 我曾经天真地尝试将两个 xsd 合并到 svg.xsd 中,结果只明白我根本不知道 xsd 文件是如何工作的。
- 一直关注到
SchemaInformedGrammars.class
但我不明白systemId
是什么。 - (编辑)按照支持 here(第二个 post)的建议,我使用
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);
只得到完全相同的错误...
我的问题: 问题似乎是解析器无法找到另外两个文件。有没有办法以某种方式包含这些文件以便解析器可以找到它们?
danielpeintner 将我推向了正确的方向(issue here)。
Daniel 建议我使用 createGrammar(String, XMLEntityResolver)
而不是 createGrammar(InputStream)
,并提供我自己的 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)));