0

I'm trying to create grammars using the exificient-grammars library in Android 15 (c is context)

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

from svg.xsd, which imports two more schemas: xlink.xsd and namespace.xsd. Those two files came along svg.xsd (as you can see they lie in the root directory along svg.xsd here). But instead of creating the grammars I get this exception:

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

The two lines of the svg.xsd that use import are these:

<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"/>

What I've tried so far:

  1. I've naively tried to merge the two xsd in the svg.xsd to only understand that I was simply unaware of how xsd files work.
  2. Followed the source up to SchemaInformedGrammars.class but I don't understand what systemId is.
  3. (edit) Following the suggestions of the support here (second post) I used com.siemens.ct.exi.grammars.XSDGrammarsBuilder to create the grammars:
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);

Only to get the exact same error...

My question: The problem seems to be that the parser cannot locate the two other files. Is there a way to include those files somehow so the parser can locate them?

venge
  • 177
  • 1
  • 9

1 Answers1

0

danielpeintner from the development team of exificient nudged me to the correct direction (issue here).

Instead of using the createGrammar(InputStream), Daniel suggested me that I use createGrammar(String, XMLEntityResolver) instead, and also provide my own XMLEntityResolver implementation. My implementation is this:

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;
    }
}

Calling in createGrammar(String, XMLEntityResolver) like this:

exiFactory.setGrammars(GrammarFactory.newInstance().createGrammars("svg.xsd", new XSDResolver(c)));
venge
  • 177
  • 1
  • 9