averbraeck / opentrafficsim

Open Source Multi-Level Traffic Simulator
BSD 3-Clause "New" or "Revised" License
29 stars 11 forks source link

Merge ots-xsd into ots-xml #56

Closed WJSchakel closed 1 year ago

WJSchakel commented 1 year ago

These two projects are small and highly coupled. There is no point in two separate projects.

averbraeck commented 1 year ago

Originally, versioned resources were available in ots-xsd and on the Internet, requiring a live connection to Internet to parse xml-files (with a fallback to local files). This has been replaced by a version-dependent local file in ots-parser-xml (where the parsing takes place anyhow). When we update the XML standard for OTS, a new release will include the correct version of the XSD files.

averbraeck commented 1 year ago

One of the issues is how to handle include files. Absolute paths work, but the include that you would want to do such as: <xi:include href="../xsd/defaults/default_gtutypes.xml" /> or <xi:include href="/resources/xsd/defaults/default_gtutypes.xml" /> do not work.

This is probably due to the fact that the XML is read as a stream, where '..' does not make sense anymore, since the URI or URL for the location is not available anymore. Maybe an EntityResolver class can help here.

averbraeck commented 1 year ago

An EntityResolver is indeed the way to go.

With:

    static class DefaultsResolver implements EntityResolver
    {
        /** {@inheritDoc} */
        @Override
        public InputSource resolveEntity(final String publicId, final String systemId)
        {
            if (systemId.contains("defaults/"))
            {
                String location = "/resources/xsd/defaults" + systemId.substring(systemId.lastIndexOf('/'));
                InputStream stream = URLResource.getResourceAsStream(location);
                return new InputSource(stream);
            }
            else
            {
                return new InputSource(URLResource.getResourceAsStream(systemId));
            }
        }
    }

and

        JAXBContext jc = JAXBContext.newInstance(OTS.class);
        Unmarshaller unmarshaller = jc.createUnmarshaller();
        SAXParserFactory spf = SAXParserFactory.newInstance();
        spf.setXIncludeAware(true);
        spf.setNamespaceAware(true);
        spf.setValidating(false);
        XMLReader xmlReader = spf.newSAXParser().getXMLReader();
        xmlReader.setEntityResolver(new DefaultsResolver());
        SAXSource saxSource = new SAXSource(xmlReader, new InputSource(xmlStream));
        return (OTS) unmarshaller.unmarshal(saxSource);

the includes work fine. The includes can simply be indicated as:

    <xi:include href="../xsd/defaults/default_gtutypes.xml" />
    <xi:include href="../xsd/defaults/default_linktypes.xml" />
    <xi:include href="../xsd/defaults/default_lanetypes.xml" />
averbraeck commented 1 year ago

Project ots-xsd removed as a project, as a module, and an included dependency.

averbraeck commented 1 year ago

Branch without ots-xsd merged into main branch. Merge of ots-xsd and ots-parser-xml completed.