Исключительная исключительная ситуация "schema_reference.4: не удалось прочитать документ схемы xxx.xsd" с ключевым словом импорта - PullRequest
0 голосов
/ 06 октября 2019

Я пытаюсь создать грамматику, используя библиотеку 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"/>

Что я имеюдо сих пор пытался:

  1. Я наивно пытался объединить два xsd в svg.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);

Только для того, чтобы получить точно такую ​​же ошибку ...

Мой вопрос: Кажется, проблема в том, чтопарсер не может найти два других файла. Есть ли способ как-то включить эти файлы, чтобы парсер мог их найти?

1 Ответ

0 голосов
/ 07 октября 2019

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)));
...