public void parse(Database db, XHTMLContentHandler xhtml)
            throws IOException, SAXException, TikaException {


        String pw = db.getDatabasePassword();
        if (pw != null) {
            parentMetadata.set(JackcessParser.MDB_PW, pw);
        }
        db.setDateTimeType(DateTimeType.DATE);
        PropertyMap dbp = db.getDatabaseProperties();
        for (PropertyMap.Property p : dbp) {
            parentMetadata.add(JackcessParser.MDB_PROPERTY_PREFIX + p.getName(),
                    toString(p.getValue(), p.getType()));
        }

        PropertyMap up = db.getUserDefinedProperties();
        for (PropertyMap.Property p : up) {
            parentMetadata.add(JackcessParser.USER_DEFINED_PROPERTY_PREFIX + p.getName(),
                    toString(p.getValue(), p.getType()));
        }

        Set<String> found = new HashSet<>();
        PropertyMap summaryProperties = db.getSummaryProperties();
        if (summaryProperties != null) {
            //try to get core properties
            PropertyMap.Property title = summaryProperties.get(TITLE_PROP_KEY);
            if (title != null) {
                parentMetadata
                        .set(TikaCoreProperties.TITLE, toString(title.getValue(), title.getType()));
                found.add(title.getName());
            }
            PropertyMap.Property author = summaryProperties.get(AUTHOR_PROP_KEY);
            if (author != null && author.getValue() != null) {
                String authorString = toString(author.getValue(), author.getType());
                SummaryExtractor.addMulti(parentMetadata, TikaCoreProperties.CREATOR, authorString);
                found.add(author.getName());
            }
            PropertyMap.Property company = summaryProperties.get(COMPANY_PROP_KEY);
            if (company != null) {
                parentMetadata.set(OfficeOpenXMLExtended.COMPANY,
                        toString(company.getValue(), company.getType()));
                found.add(company.getName());
            }

            for (PropertyMap.Property p : db.getSummaryProperties()) {
                if (!found.contains(p.getName())) {
                    parentMetadata.add(JackcessParser.SUMMARY_PROPERTY_PREFIX + p.getName(),
                            toString(p.getValue(), p.getType()));
                }
            }
        }

        for (Table table : db.newIterable().setIncludeLinkedTables(false)
                .setIncludeSystemTables(false)) {
            if (table == null) {
                break;
            }
            String tableName = table.getName();
            List<? extends Column> columns = table.getColumns();
            xhtml.startElement("table", "name", tableName);
            addHeaders(columns, xhtml);
            xhtml.startElement("tbody");

            Row r = table.getNextRow();

            while (r != null) {
                xhtml.startElement("tr");
                for (Column c : columns) {
                    handleCell(r, c, xhtml);
                }
                xhtml.endElement("tr");
                r = table.getNextRow();
            }
            xhtml.endElement("tbody");
            xhtml.endElement("table");
        }

        for (Query q : db.getQueries()) {
            xhtml.startElement("div", "type", "sqlQuery");
            String sqlString = "unsupported query type";
            //unknownqueryimpl can throw an UnsupportedOperationException
            try {
                sqlString = q.toSQLString();
            } catch (UnsupportedOperationException e) {
                //swallow
            }
            xhtml.characters(sqlString);
            xhtml.endElement("div");
        }
    }
Internal class.  Needs to be instantiated for each parse because of
the lack of thread safety with the dateTimeFormatter
tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-microsoft-module/src/main/java/org/apache/tika/parser/microsoft/JackcessExtractor.java