Специфическое исключение schema_reference.4: не удалось прочитать документ схемы xxx.xsd с ключевым словом import
Я пытаюсь создать грамматики, используя библиотеку exificient-grammars в Android 15 (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>.
Две строки 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"/>
Что я пробовал до сих пор:
- Я наивно пытался объединить два xsd в svg.xsd только для того, чтобы понять, что я просто не знал, как работают файлы xsd.
- Следил за источником до
SchemaInformedGrammars.class
но я не понимаю чтоsystemId
является. - (править) Следуя предложениям поддержки здесь (второй пост), я использовал
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);
Только чтобы получить ту же ошибку...
Мой вопрос: проблема, похоже, в том, что парсер не может найти два других файла. Есть ли способ каким-то образом включить эти файлы, чтобы синтаксический анализатор мог их найти?
1 ответ
danielpeintner из команды разработчиков exificient подтолкнул меня в правильном направлении (проблема здесь).
Вместо использования createGrammar(InputStream)
, Даниэль предложил мне использовать 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)));