[pycsw] 01/02: Imported Upstream version 2.0.0~alpha1+dfsg

Bas Couwenberg sebastic at debian.org
Thu Jul 7 01:02:10 UTC 2016


This is an automated email from the git hooks/post-receive script.

sebastic pushed a commit to branch upstream
in repository pycsw.

commit c4c7946ef925ed990c593a1fee45f4d2f3f856a2
Author: Bas Couwenberg <sebastic at xs4all.nl>
Date:   Wed Jul 6 17:45:55 2016 +0200

    Imported Upstream version 2.0.0~alpha1+dfsg
---
 .github/ISSUE_TEMPLATE.md                          |   21 +
 .github/PULL_REQUEST_TEMPLATE.md                   |   12 +
 .travis.yml                                        |   32 +-
 COMMITTERS.txt                                     |   15 +-
 CONTRIBUTING.rst                                   |   33 +-
 LICENSE.txt                                        |    5 +-
 VERSION.txt                                        |    2 +-
 bin/pycsw-admin.py                                 |   64 +-
 bin/pycsw-pylint.sh                                |    2 +-
 csw.py                                             |   60 +-
 default-sample.cfg                                 |    6 +-
 docs/_templates/layout.html                        |    2 +-
 docs/administration.rst                            |    2 +-
 docs/conf.py                                       |   34 +-
 docs/hhypermap.rst                                 |   17 +
 docs/index.rst                                     |    2 +
 docs/installation.rst                              |   23 +-
 docs/introduction.rst                              |    8 +-
 docs/json.rst                                      |    7 +
 docs/license.rst                                   |    7 +
 docs/outputschemas.rst                             |    3 +-
 docs/testing.rst                                   |    2 +
 docs/tools.rst                                     |    3 +-
 docs/transactions.rst                              |    2 +
 etc/dist/opensuse/python-pycsw.spec                |   12 +-
 etc/mappings.py                                    |    4 +-
 pavement.py                                        |   45 +-
 pycsw/__init__.py                                  |    6 +-
 pycsw/config.py                                    |  339 ---
 pycsw/{plugins/profiles => core}/__init__.py       |    4 +-
 pycsw/{ => core}/admin.py                          |   40 +-
 pycsw/core/config.py                               |  593 +++++
 .../profiles/__init__.py => core/etree.py}         |    6 +-
 .../{plugins/profiles => core/formats}/__init__.py |    4 +-
 pycsw/{ => core}/formats/fmt_json.py               |   19 +-
 pycsw/{ => core}/log.py                            |    4 +-
 pycsw/{ => core}/metadata.py                       |  300 ++-
 pycsw/{ => core}/repository.py                     |   10 +-
 .../core/schemas/catalog.xml                       |   20 +-
 .../{ => core}/schemas/ogc/OGC-SOFTWARE-NOTICE.txt |    0
 pycsw/{ => core}/schemas/ogc/README.txt            |    0
 .../schemas/ogc/csw/2.0.2/CSW-discovery.xsd        |    0
 .../schemas/ogc/csw/2.0.2/CSW-publication.xsd      |    0
 .../{ => core}/schemas/ogc/csw/2.0.2/rec-dcmes.xsd |    0
 .../schemas/ogc/csw/2.0.2/rec-dcterms.xsd          |    0
 pycsw/{ => core}/schemas/ogc/csw/2.0.2/record.xsd  |    0
 pycsw/core/schemas/ogc/csw/3.0/README.txt          |   25 +
 pycsw/core/schemas/ogc/csw/3.0/cswAll.xsd          |   33 +
 pycsw/core/schemas/ogc/csw/3.0/cswCommon.xsd       |   71 +
 .../schemas/ogc/csw/3.0/cswGetCapabilities.xsd     |   80 +
 pycsw/core/schemas/ogc/csw/3.0/cswGetDomain.xsd    |  146 ++
 .../core/schemas/ogc/csw/3.0/cswGetRecordById.xsd  |   58 +
 pycsw/core/schemas/ogc/csw/3.0/cswGetRecords.xsd   |  391 +++
 pycsw/core/schemas/ogc/csw/3.0/cswHarvest.xsd      |   95 +
 pycsw/core/schemas/ogc/csw/3.0/cswTransaction.xsd  |  187 ++
 pycsw/core/schemas/ogc/csw/3.0/cswUnHarvest.xsd    |   77 +
 pycsw/core/schemas/ogc/csw/3.0/rec-dcmes.xsd       |  245 ++
 .../schemas/ogc/csw/3.0}/rec-dcterms.xsd           |   33 +-
 pycsw/core/schemas/ogc/csw/3.0/record.xsd          |  170 ++
 pycsw/{ => core}/schemas/ogc/filter/1.1.0/expr.xsd |    0
 .../{ => core}/schemas/ogc/filter/1.1.0/filter.xsd |    0
 .../ogc/filter/1.1.0/filterCapabilities.xsd        |    0
 pycsw/{ => core}/schemas/ogc/filter/1.1.0/sort.xsd |    0
 pycsw/core/schemas/ogc/filter/2.0/expr.xsd         |   44 +
 pycsw/core/schemas/ogc/filter/2.0/filter.xsd       |  395 +++
 pycsw/core/schemas/ogc/filter/2.0/filterAll.xsd    |   23 +
 .../schemas/ogc/filter/2.0/filterCapabilities.xsd  |  286 +++
 pycsw/core/schemas/ogc/filter/2.0/query.xsd        |   70 +
 .../1.1.0 => core/schemas/ogc/filter/2.0}/sort.xsd |   37 +-
 .../schemas/ogc/gml/3.1.1/base/basicTypes.xsd      |    0
 .../ogc/gml/3.1.1/base/coordinateOperations.xsd    |    0
 .../gml/3.1.1/base/coordinateReferenceSystems.xsd  |    0
 .../ogc/gml/3.1.1/base/coordinateSystems.xsd       |    0
 .../schemas/ogc/gml/3.1.1/base/coverage.xsd        |    0
 .../schemas/ogc/gml/3.1.1/base/dataQuality.xsd     |    0
 .../schemas/ogc/gml/3.1.1/base/datums.xsd          |    0
 .../schemas/ogc/gml/3.1.1/base/defaultStyle.xsd    |    2 +-
 .../schemas/ogc/gml/3.1.1/base/dictionary.xsd      |    0
 .../schemas/ogc/gml/3.1.1/base/direction.xsd       |    0
 .../schemas/ogc/gml/3.1.1/base/dynamicFeature.xsd  |    0
 .../schemas/ogc/gml/3.1.1/base/feature.xsd         |    0
 .../ogc/gml/3.1.1/base/geometryAggregates.xsd      |    0
 .../ogc/gml/3.1.1/base/geometryBasic0d1d.xsd       |    0
 .../schemas/ogc/gml/3.1.1/base/geometryBasic2d.xsd |    0
 .../ogc/gml/3.1.1/base/geometryComplexes.xsd       |    0
 .../ogc/gml/3.1.1/base/geometryPrimitives.xsd      |    0
 .../{ => core}/schemas/ogc/gml/3.1.1/base/gml.xsd  |    0
 .../schemas/ogc/gml/3.1.1/base/gmlBase.xsd         |    0
 .../schemas/ogc/gml/3.1.1/base/grids.xsd           |    0
 .../schemas/ogc/gml/3.1.1/base/measures.xsd        |    0
 .../schemas/ogc/gml/3.1.1/base/observation.xsd     |    0
 .../ogc/gml/3.1.1/base/referenceSystems.xsd        |    0
 .../schemas/ogc/gml/3.1.1/base/temporal.xsd        |    0
 .../gml/3.1.1/base/temporalReferenceSystems.xsd    |    0
 .../ogc/gml/3.1.1/base/temporalTopology.xsd        |    0
 .../schemas/ogc/gml/3.1.1/base/topology.xsd        |    0
 .../schemas/ogc/gml/3.1.1/base/units.xsd           |    0
 .../schemas/ogc/gml/3.1.1/base/valueObjects.xsd    |    0
 .../ogc/gml/3.2.1/SchematronConstraints.xml        |   71 +
 pycsw/core/schemas/ogc/gml/3.2.1/basicTypes.xsd    |  268 ++
 .../schemas/ogc/gml/3.2.1/coordinateOperations.xsd |  525 ++++
 .../ogc/gml/3.2.1/coordinateReferenceSystems.xsd   |  373 +++
 .../schemas/ogc/gml/3.2.1/coordinateSystems.xsd    |  297 +++
 pycsw/core/schemas/ogc/gml/3.2.1/coverage.xsd      |  292 +++
 pycsw/core/schemas/ogc/gml/3.2.1/datums.xsd        |  287 +++
 .../schemas/ogc/gml/3.2.1}/defaultStyle.xsd        |   27 +-
 .../core/schemas/ogc/gml/3.2.1/deprecatedTypes.xsd | 1133 +++++++++
 pycsw/core/schemas/ogc/gml/3.2.1/dictionary.xsd    |   90 +
 pycsw/core/schemas/ogc/gml/3.2.1/direction.xsd     |   84 +
 .../core/schemas/ogc/gml/3.2.1/dynamicFeature.xsd  |  109 +
 pycsw/core/schemas/ogc/gml/3.2.1/feature.xsd       |   94 +
 .../schemas/ogc/gml/3.2.1/geometryAggregates.xsd   |  197 ++
 .../schemas/ogc/gml/3.2.1/geometryBasic0d1d.xsd    |  277 ++
 .../core/schemas/ogc/gml/3.2.1/geometryBasic2d.xsd |  124 +
 .../schemas/ogc/gml/3.2.1/geometryComplexes.xsd    |   95 +
 .../schemas/ogc/gml/3.2.1/geometryPrimitives.xsd   |  846 +++++++
 .../base => core/schemas/ogc/gml/3.2.1}/gml.xsd    |   14 +-
 .../gml => core/schemas/ogc/gml/3.2.1}/gmlBase.xsd |  166 +-
 .../schemas/ogc/gml/3.2.1/gml_32_geometries.rdf    |  368 +++
 .../schemas/ogc/gml/3.2.1/gml_3_2_1-ReadMe.txt     |   58 +
 pycsw/core/schemas/ogc/gml/3.2.1/grids.xsd         |   64 +
 pycsw/core/schemas/ogc/gml/3.2.1/measures.xsd      |   68 +
 pycsw/core/schemas/ogc/gml/3.2.1/observation.xsd   |   95 +
 .../schemas/ogc/gml/3.2.1/referenceSystems.xsd     |   70 +
 pycsw/core/schemas/ogc/gml/3.2.1/temporal.xsd      |  269 ++
 .../ogc/gml/3.2.1/temporalReferenceSystems.xsd     |  189 ++
 .../schemas/ogc/gml/3.2.1/temporalTopology.xsd     |  119 +
 pycsw/core/schemas/ogc/gml/3.2.1/topology.xsd      |  386 +++
 pycsw/core/schemas/ogc/gml/3.2.1/units.xsd         |  162 ++
 pycsw/core/schemas/ogc/gml/3.2.1/valueObjects.xsd  |  205 ++
 .../schemas/ogc/ows/1.0.0/ows19115subset.xsd       |    0
 pycsw/{ => core}/schemas/ogc/ows/1.0.0/owsAll.xsd  |    0
 .../{ => core}/schemas/ogc/ows/1.0.0/owsCommon.xsd |    0
 .../ogc/ows/1.0.0/owsDataIdentification.xsd        |    0
 .../schemas/ogc/ows/1.0.0/owsExceptionReport.xsd   |    0
 .../schemas/ogc/ows/1.0.0/owsGetCapabilities.xsd   |    0
 .../ogc/ows/1.0.0/owsOperationsMetadata.xsd        |    0
 .../ogc/ows/1.0.0/owsServiceIdentification.xsd     |    0
 .../schemas/ogc/ows/1.0.0/owsServiceProvider.xsd   |    0
 .../schemas/ogc/ows/1.1.0}/ows19115subset.xsd      |   36 +-
 .../schemas/ogc/ows/1.1.0}/owsAll.xsd              |   15 +-
 .../schemas/ogc/ows/1.1.0}/owsCommon.xsd           |   15 +-
 pycsw/core/schemas/ogc/ows/1.1.0/owsContents.xsd   |   87 +
 .../ogc/ows/1.1.0}/owsDataIdentification.xsd       |   50 +-
 pycsw/core/schemas/ogc/ows/1.1.0/owsDomainType.xsd |  280 ++
 .../schemas/ogc/ows/1.1.0}/owsExceptionReport.xsd  |   26 +-
 .../schemas/ogc/ows/1.1.0}/owsGetCapabilities.xsd  |   17 +-
 .../schemas/ogc/ows/1.1.0/owsGetResourceByID.xsd   |   52 +
 .../schemas/ogc/ows/1.1.0/owsInputOutputData.xsd   |   60 +
 pycsw/core/schemas/ogc/ows/1.1.0/owsManifest.xsd   |  125 +
 .../ogc/ows/1.1.0}/owsOperationsMetadata.xsd       |   40 +-
 .../ogc/ows/1.1.0}/owsServiceIdentification.xsd    |   20 +-
 .../schemas/ogc/ows/1.1.0}/owsServiceProvider.xsd  |   14 +-
 pycsw/core/schemas/ogc/ows/2.0/ows19115subset.xsd  |  364 +++
 .../ogc/ows/2.0/owsAdditionalParameters.xsd        |  114 +
 pycsw/core/schemas/ogc/ows/2.0/owsAll.xsd          |   29 +
 pycsw/core/schemas/ogc/ows/2.0/owsCommon.xsd       |  275 ++
 pycsw/core/schemas/ogc/ows/2.0/owsContents.xsd     |  163 ++
 .../schemas/ogc/ows/2.0/owsDataIdentification.xsd  |  202 ++
 pycsw/core/schemas/ogc/ows/2.0/owsDomainType.xsd   |  388 +++
 .../schemas/ogc/ows/2.0/owsExceptionReport.xsd     |  126 +
 .../schemas/ogc/ows/2.0/owsGetCapabilities.xsd     |  220 ++
 .../schemas/ogc/ows/2.0/owsGetResourceByID.xsd     |   83 +
 .../schemas/ogc/ows/2.0/owsInputOutputData.xsd     |   98 +
 pycsw/core/schemas/ogc/ows/2.0/owsManifest.xsd     |  181 ++
 .../schemas/ogc/ows/2.0/owsOperationsMetadata.xsd  |  234 ++
 .../ogc/ows/2.0/owsServiceIdentification.xsd       |   98 +
 .../schemas/ogc/ows/2.0/owsServiceProvider.xsd     |   64 +
 pycsw/{ => core}/schemas/w3c/1999/xlink.xsd        |    0
 pycsw/{ => core}/schemas/w3c/2001/xml.xsd          |    0
 pycsw/{ => core}/util.py                           |   81 +-
 pycsw/oaipmh.py                                    |   36 +-
 pycsw/{plugins/profiles => ogc}/__init__.py        |    4 +-
 pycsw/{plugins/profiles => ogc/csw}/__init__.py    |    4 +-
 pycsw/ogc/csw/csw2.py                              | 1988 +++++++++++++++
 pycsw/ogc/csw/csw3.py                              | 2136 ++++++++++++++++
 pycsw/{plugins/profiles => ogc/fes}/__init__.py    |    4 +-
 pycsw/{fes.py => ogc/fes/fes1.py}                  |   23 +-
 pycsw/{fes.py => ogc/fes/fes2.py}                  |   74 +-
 pycsw/{plugins/profiles => ogc/gml}/__init__.py    |    4 +-
 pycsw/{gml.py => ogc/gml/gml3.py}                  |    7 +-
 pycsw/opensearch.py                                |  269 +-
 pycsw/plugins/__init__.py                          |    4 +-
 pycsw/plugins/outputschemas/__init__.py            |    7 +-
 pycsw/plugins/outputschemas/atom.py                |   50 +-
 pycsw/plugins/outputschemas/dif.py                 |   38 +-
 pycsw/plugins/outputschemas/fgdc.py                |   10 +-
 pycsw/plugins/outputschemas/gm03.py                |  240 ++
 pycsw/plugins/profiles/__init__.py                 |    4 +-
 pycsw/plugins/profiles/apiso/__init__.py           |    4 +-
 pycsw/plugins/profiles/apiso/apiso.py              |   74 +-
 .../ogc/iso/19139/20060504/gco/basicTypes.xsd      |    2 +-
 .../schemas/ogc/iso/19139/20060504/gco/gcoBase.xsd |    2 +-
 .../schemas/ogc/iso/19139/20060504/gml/gmlBase.xsd |    2 +-
 .../ogc/iso/19139/20060504/gmx/extendedTypes.xsd   |    2 +-
 .../resources/Codelist/ML_gmxCodelists.xml         |    2 +-
 .../20060504/resources/Codelist/gmxCodelists.xml   |    2 +-
 .../iso/19139/20060504/resources/crs/ML_gmxCrs.xml |    2 +-
 .../iso/19139/20060504/resources/crs/gmxCrs.xml    |    2 +-
 .../iso/19139/20060504/resources/example/fr-fr.xml |    2 +-
 .../iso/19139/20060504/resources/uom/ML_gmxUom.xml |    2 +-
 .../iso/19139/20060504/resources/uom/gmxUom.xml    |    2 +-
 .../schemas/ogc/iso/19139/20070417/ReadMe.txt      |   26 +
 .../schemas/ogc/iso/19139/20070417/gco/ReadMe.txt  |   47 +
 .../{20060504 => 20070417}/gco/basicTypes.xsd      |   12 +-
 .../schemas/ogc/iso/19139/20070417/gco/gco.xsd     |   12 +
 .../19139/{20060504 => 20070417}/gco/gcoBase.xsd   |   10 +-
 .../schemas/ogc/iso/19139/20070417/gmd/ReadMe.txt  |   45 +
 .../iso/19139/20070417/gmd/applicationSchema.xsd   |   43 +
 .../ogc/iso/19139/20070417/gmd/citation.xsd        |  276 ++
 .../ogc/iso/19139/20070417/gmd/constraints.xsd     |  107 +
 .../schemas/ogc/iso/19139/20070417/gmd/content.xsd |  190 ++
 .../ogc/iso/19139/20070417/gmd/dataQuality.xsd     |  556 ++++
 .../ogc/iso/19139/20070417/gmd/distribution.xsd    |  203 ++
 .../schemas/ogc/iso/19139/20070417/gmd/extent.xsd  |  206 ++
 .../ogc/iso/19139/20070417/gmd/freeText.xsd        |  123 +
 .../schemas/ogc/iso/19139/20070417/gmd/gmd.xsd     |   12 +
 .../ogc/iso/19139/20070417/gmd/identification.xsd  |  216 +-
 .../ogc/iso/19139/20070417/gmd/maintenance.xsd     |   87 +
 .../iso/19139/20070417/gmd/metadataApplication.xsd |  176 ++
 .../ogc/iso/19139/20070417/gmd/metadataEntity.xsd  |   71 +
 .../iso/19139/20070417/gmd/metadataExtension.xsd   |  100 +
 .../iso/19139/20070417/gmd/portrayalCatalogue.xsd  |   37 +
 .../ogc/iso/19139/20070417/gmd/referenceSystem.xsd |  101 +
 .../19139/20070417/gmd/spatialRepresentation.xsd   |  238 ++
 .../schemas/ogc/iso/19139/20070417/gmx/ReadMe.txt  |   47 +
 .../ogc/iso/19139/20070417/gmx/catalogues.xsd      |  113 +
 .../ogc/iso/19139/20070417/gmx/codelistItem.xsd    |  169 ++
 .../schemas/ogc/iso/19139/20070417/gmx/crsItem.xsd | 1031 ++++++++
 .../{20060504 => 20070417}/gmx/extendedTypes.xsd   |    7 +-
 .../schemas/ogc/iso/19139/20070417/gmx/gmx.xsd     |   12 +
 .../ogc/iso/19139/20070417/gmx/gmxUsage.xsd        |  128 +
 .../schemas/ogc/iso/19139/20070417/gmx/uomItem.xsd |  163 ++
 .../schemas/ogc/iso/19139/20070417/gsr/ReadMe.txt  |   45 +
 .../schemas/ogc/iso/19139/20070417/gsr/gsr.xsd     |   12 +
 .../iso/19139/20070417/gsr/spatialReferencing.xsd  |   25 +
 .../schemas/ogc/iso/19139/20070417/gss/ReadMe.txt  |   44 +
 .../ogc/iso/19139/20070417/gss/geometry.xsd        |   36 +
 .../schemas/ogc/iso/19139/20070417/gss/gss.xsd     |   12 +
 .../schemas/ogc/iso/19139/20070417/gts/ReadMe.txt  |   44 +
 .../schemas/ogc/iso/19139/20070417/gts/gts.xsd     |   12 +
 .../ogc/iso/19139/20070417/gts/temporalObjects.xsd |   35 +
 .../ogc/iso/19139/20070417/resources/ReadMe.txt    |   20 +
 .../resources/codelist}/ML_gmxCodelists.xml        |   34 +-
 .../resources/codelist}/gmxCodelists.xml           |   44 +-
 .../20070417/resources/codelist/tcCodelists.xml    |   63 +
 .../resources/crs/ML_gmxCrs.xml                    |  105 +-
 .../resources/crs/gmxCrs.xml                       |   89 +-
 .../iso/19139/20070417/resources/example/fr-fr.xml |   83 +
 .../iso/19139/20070417/resources/uom/ML_gmxUom.xml |  125 +
 .../iso/19139/20070417/resources/uom/gmxUom.xml    |   66 +
 pycsw/plugins/profiles/ebrim/__init__.py           |    4 +-
 pycsw/plugins/profiles/ebrim/ebrim.py              |   27 +-
 .../ogc/csw/2.0.2/profiles/ebrim/1.0/csw-ebrim.xsd |    6 +-
 pycsw/plugins/profiles/profile.py                  |   34 +-
 pycsw/plugins/repository/__init__.py               |    4 +-
 pycsw/plugins/repository/geonode/__init__.py       |    4 +-
 pycsw/plugins/repository/geonode/geonode_.py       |    8 +-
 .../repository/hhypermap}/__init__.py              |    2 +-
 .../{odc/odc.py => hhypermap/hhypermap.py}         |   97 +-
 pycsw/plugins/repository/odc/__init__.py           |    4 +-
 pycsw/plugins/repository/odc/odc.py                |   10 +-
 pycsw/server.py                                    | 2675 ++++----------------
 pycsw/sru.py                                       |   23 +-
 csw.wsgi => pycsw/wsgi.py                          |   35 +-
 requirements-pg.txt                                |    1 +
 requirements-standalone.txt                        |    3 +-
 requirements.txt                                   |    8 +-
 setup.py                                           |   20 +-
 ...ites_apiso-inspire_get_GetCapabilities-lang.xml |  252 +-
 .../suites_apiso-inspire_get_GetCapabilities.xml   |  252 +-
 .../expected/suites_apiso_post_DescribeRecord.xml  |    2 +-
 .../expected/suites_apiso_post_GetCapabilities.xml |  252 +-
 .../suites_apiso_post_GetDomain-property.xml       |    2 +-
 .../suites_apiso_post_GetRecordById-brief.xml      |    2 +-
 .../suites_apiso_post_GetRecordById-full-dc.xml    |    3 +-
 .../suites_apiso_post_GetRecordById-full.xml       |    2 +-
 .../suites_apiso_post_GetRecordById-srv-brief.xml  |    2 +-
 ...suites_apiso_post_GetRecords-all-csw-output.xml |    2 +-
 .../expected/suites_apiso_post_GetRecords-all.xml  |    2 +-
 .../suites_apiso_post_GetRecords-cql-title.xml     |    2 +-
 .../suites_apiso_post_GetRecords-elementname.xml   |    2 +-
 ...cords-filter-and-nested-spatial-or-dateline.xml |    4 +-
 ...suites_apiso_post_GetRecords-filter-anytext.xml |    2 +-
 ...piso_post_GetRecords-filter-bbox-csw-output.xml |    2 +-
 .../suites_apiso_post_GetRecords-filter-bbox.xml   |    2 +-
 ...es_apiso_post_GetRecords-filter-servicetype.xml |    2 +-
 .../suites_atom_get_opensearch-description.xml     |   22 +-
 ...uites_atom_get_opensearch-ogc-bbox-and-time.xml |   38 +-
 .../suites_atom_get_opensearch-ogc-bbox.xml        |   54 +-
 ...tes_atom_get_opensearch-ogc-count-and-page1.xml |   27 +-
 ...tes_atom_get_opensearch-ogc-count-and-page2.xml |    8 +-
 .../suites_atom_get_opensearch-ogc-q-and-bbox.xml  |   21 +-
 .../suites_atom_get_opensearch-ogc-q-and-time.xml  |   10 +-
 .../expected/suites_atom_get_opensearch-ogc-q.xml  |   10 +-
 .../suites_atom_get_opensearch-ogc-time.xml        |   10 +-
 .../suites_atom_get_opensearch-ogc-timeend.xml     |   10 +-
 .../suites_atom_get_opensearch-ogc-timestart.xml   |   46 +-
 tests/expected/suites_atom_get_opensearch.xml      |   99 +-
 tests/expected/suites_atom_post_DescribeRecord.xml |    2 +-
 .../expected/suites_atom_post_GetCapabilities.xml  |  158 +-
 .../suites_atom_post_GetRecords-filter-bbox.xml    |   34 +-
 ...te_get_27e17158-c57a-4493-92ac-dba8934cf462.xml |  197 +-
 ...te_get_27f69b66-5f05-4311-a89c-73ca55c2686b.xml |    2 +-
 ...te_get_2ab7d1fa-885b-459f-80e4-b6282eab4f8c.xml |  197 +-
 ...te_get_37aa90e2-6ff0-420c-af15-8b9463099a73.xml |    2 +-
 ...te_get_3a8a3c47-455f-4f49-9078-03119f3e70b3.xml |  290 +--
 ...te_get_4515831f-834a-4699-95f6-ab0c2cbfcfd0.xml |    2 +-
 ...te_get_477b23a3-baa9-47c8-9541-5fe27735ed49.xml |  594 ++++-
 ...te_get_48f26761-3a9d-48db-bee1-da089f5fb857.xml |  197 +-
 ...te_get_4e38092f-1586-44b8-988e-0acfa5855916.xml |    2 +-
 ...te_get_55c38f00-2553-42c1-99ab-33edbb561ad7.xml |  647 +++--
 ...te_get_5ab5db18-c87a-4fbf-a8d8-b7289b09ac81.xml |   10 +-
 ...te_get_6a4f57ca-a1bd-4802-89c2-44860dbdb0f0.xml |    2 +-
 ...te_get_6c375703-9c00-4aef-bec7-d2e964f849eb.xml |   10 +-
 ...te_get_80f31def-4185-48b9-983a-960566918eae.xml |  824 +++---
 ...te_get_8e2232ed-05d9-44ae-8b04-0911cbe6a507.xml |   10 +-
 ...te_get_9697f0aa-3b6a-4125-83a5-61e8826127c4.xml |  824 +++---
 ...te_get_9bfd17fa-15dc-4a10-8fa7-b3cff7013dd7.xml |    2 +-
 ...te_get_b81c3595-06d6-4693-82ea-1ff8650755ac.xml |    2 +-
 ...te_get_ba5fc729-3b71-47a0-b7d0-42ec565cd185.xml |  197 +-
 ...te_get_c4ea754f-c158-4d8d-8253-dc8f86021b52.xml |   10 +-
 ...te_get_f4692ec5-9547-4a05-88ab-e6154af2640a.xml |  197 +-
 ...te_get_f997f25e-c865-4d53-a362-0ed1846337f2.xml |    2 +-
 ...e_post_0c976d98-c896-4b10-b1fe-a22ef50434e7.xml |    2 +-
 ...e_post_19d2a6ed-be28-4866-ae15-e3bb634486cb.xml |    2 +-
 ...e_post_1ab55aa3-6685-4595-8ecd-45987a7b8b59.xml |    4 +-
 ...e_post_1c958b7a-ca09-4c38-98bd-ef1d1d28cc14.xml |    2 +-
 ...e_post_1c97fc1a-61cd-4c1d-8054-933e17a6c5ee.xml |    2 +-
 ...e_post_2102a460-5d62-465f-9668-d70b3faafbfa.xml |    2 +-
 ...e_post_225f455a-0035-486b-a94e-fee7ae881b2b.xml |    2 +-
 ...e_post_2d53ffea-60e4-4652-abf5-36eb23042fd5.xml |    2 +-
 ...e_post_34a019a9-1581-42cb-9827-fbfdda2773b7.xml |    2 +-
 ...e_post_3e76fd38-e035-41c9-83dc-61356f680c97.xml |    2 +-
 ...e_post_418a6fb0-a89c-4a94-afc9-3f8168eb2980.xml |    2 +-
 ...e_post_420b745e-0c4b-404e-9f2d-61fa580ff05a.xml |    2 +-
 ...e_post_4735d649-a2b1-42fd-a101-14e1d7e4607f.xml |    2 +-
 ...e_post_5c5861bc-f742-40a5-9998-5342615d674b.xml |    2 +-
 ...e_post_6e736fd0-c266-4852-9eb3-0656f5d0f5c4.xml |    2 +-
 ...e_post_73f1551c-e269-4ef9-9dae-e535b5eebfc7.xml |    2 +-
 ...e_post_78297c88-4850-4927-adc6-511cd9a3d539.xml |    2 +-
 ...e_post_7c89cdf5-0def-4cfb-8c55-2b8ffea5d92f.xml |   46 +-
 ...e_post_7e2cd105-daec-4d25-bc8e-d49d21364912.xml |    2 +-
 ...e_post_87f2f670-9cd6-4907-b82c-1b46a7dd2a78.xml |    2 +-
 ...e_post_88b4e1ba-3bd4-4cbe-81e5-e004056d6ca3.xml |    2 +-
 ...e_post_898cd63b-2585-4ec0-8720-d554bd324174.xml |    2 +-
 ...e_post_8fb13dc3-5818-45e2-9e29-46abc16e7d38.xml |    2 +-
 ...e_post_928c1896-52d4-4ac7-9832-f98e3eb65f02.xml |    2 +-
 ...e_post_93bdbb9d-2734-4f01-92fb-48634cca41de.xml |    2 +-
 ...e_post_948b39d5-bb4f-45b8-a8f2-4ff9501aaedd.xml |    2 +-
 ...e_post_9fd64fcc-f69c-4626-b72e-5c7776a29aa9.xml |    2 +-
 ...e_post_a06d04ab-e0d0-4a86-bfe8-71460f41fe37.xml |    2 +-
 ...e_post_ad61686c-d304-42d1-b845-8c1f3070c83e.xml |    2 +-
 ...e_post_af39c020-7b1d-429c-b474-f45c3164cb79.xml |    2 +-
 ...e_post_b90e2de6-3d25-4298-a13e-dc9492a8fc73.xml |    2 +-
 ...e_post_ba9b0107-dcee-46ef-823a-a2e25a911a96.xml |    2 +-
 ...e_post_bb66ebc5-7121-48b5-9f53-b56537d9561b.xml |    2 +-
 ...e_post_c02d1c85-df9f-45ee-bea7-345c35e02a98.xml |    2 +-
 ...e_post_c311a342-72e3-4983-be39-868e6ed9740f.xml |    2 +-
 ...e_post_c38916c2-4bc6-446d-b7aa-ab006d6ba31c.xml |    2 +-
 ...e_post_c8588f47-8e65-45f5-ad34-ff4524cad84d.xml |    2 +-
 ...e_post_da228d4c-e1be-43d7-9ccb-c3f27ee32541.xml |    2 +-
 ...e_post_dc92c2c4-87d8-4a13-964e-ff9b0e0c27b3.xml |    2 +-
 ...e_post_dcb13791-379e-4739-bcd4-dbaa69f0efdb.xml |    2 +-
 ...e_post_e308f030-c097-4036-a838-44bad74c9ef7.xml |    2 +-
 ...e_post_e6e9efb2-e2b7-4b0a-a3a2-7deea3f9b8e2.xml |    2 +-
 ...e_post_f7976c55-a156-4421-8199-bc0487da4b0f.xml |    2 +-
 ...e_post_f7d79701-f10b-4087-a33c-f62df0a04fd1.xml |    2 +-
 ...e_post_fc1bc094-88f1-4851-bc2b-dfc56be9f3c7.xml |    2 +-
 ...e_post_fe20960f-a26c-4f13-852d-470a0d3233f9.xml |    2 +-
 ...30_get_002258f0-627f-457f-b2ad-025777c77ac8.xml |   15 +
 ...30_get_045c600d-973d-41eb-9f60-eba1b717b720.xml |   24 +
 ...30_get_0bbcf862-5211-4351-9988-63f8bec49c98.xml |  116 +
 ...30_get_0bdf8457-971e-4ed1-be4a-5feca4dcd8fa.xml |  491 ++++
 ...30_get_0d8bbdec-0846-42ca-8dc8-b7f4cba41d67.xml |   47 +
 ...30_get_0e1dca37-477a-4060-99fe-7799b52d656c.xml |   15 +
 ...0_get_13c87956-51a4-4780-a8e9-6e0b5c0bb473.xml} |   77 +-
 ...30_get_151d982f-ebd3-4cb2-b507-a667713a1e92.xml |    7 +
 ...30_get_1869e495-1a61-4713-8285-76d1336ee1a6.xml |    7 +
 ...30_get_1bcb42a9-538c-4f0a-9d4c-d6f10b720aa6.xml |    7 +
 ...30_get_22f44168-2ccf-4801-ad96-204212566d56.xml |  491 ++++
 ...30_get_2499a9c9-8d33-449c-bc92-d494adfcc84d.xml |  491 ++++
 ...30_get_27f4f39c-d92a-4e3c-b961-c6aa8c24e513.xml |  491 ++++
 ...30_get_28e569df-8596-4128-8d9a-29ad03138915.xml |    8 +
 ...30_get_2b06a5c8-0df2-4af1-8d2e-a425de11c845.xml |  491 ++++
 ...30_get_2ba1418a-444d-4cce-9cfe-4c94efcf8b55.xml |   32 +
 ...30_get_397fe17a-d5b4-4f96-8cc4-4ce467ed4d0a.xml |   30 +
 ...30_get_3dcd1b15-73d2-4b7d-a3e3-ff15bf14aae4.xml |   69 +
 ...30_get_405e1ff1-5c75-4846-a28b-cfaff2a6921a.xml |   23 +
 ...30_get_43cd6471-6ac7-45bd-8ff9-148cb2de9a52.xml |  491 ++++
 ...30_get_4566d2ec-1283-4a02-baed-a74fc5b47e37.xml |   18 +
 ...30_get_461bd4c5-6623-490d-9036-d91a2201e87b.xml |    3 +
 ...30_get_5496894a-3877-4f62-a20b-5d7126f94925.xml |    7 +
 ...30_get_5a015f6a-bf14-4977-b1e3-6577eb0223c8.xml |   40 +
 ...30_get_5c3a2390-1fb9-43f0-b96c-f48c7a69c990.xml |    7 +
 ...30_get_5e9e67dc-18d6-4645-8111-c6263c88a61f.xml |  326 +++
 ...30_get_604d9379-741c-42e5-b4cf-92e56c87fa64.xml |   32 +
 ...30_get_60e6af95-d5fc-465a-82e2-fd2e6d85e4af.xml |    7 +
 ...30_get_62ad94c2-b558-4265-a427-23d6677975d6.xml |    7 +
 ...30_get_6a5e247b-0961-4b8a-a0d6-35a491d9cfe7.xml |    7 +
 ...30_get_6a9d0558-9d87-495b-b999-b49a3ef1cf99.xml |  491 ++++
 ...30_get_6bd790c9-6019-4652-9c91-330a894d6700.xml |   16 +
 ...30_get_6e9cba43-5e27-415d-adbd-a92851c2c173.xml |  491 ++++
 ...30_get_7630d230-e142-4a09-accf-f091000b90cd.xml |   10 +
 ...30_get_7e82446a-b5dc-43fe-9a73-4cc1f2f2f0bf.xml |  491 ++++
 ...30_get_8025978e-1a35-4d70-80c2-e8329e0c7864.xml |  491 ++++
 ...30_get_8184ae4f-536d-4978-8b28-ad703be96967.xml |   34 +
 ...30_get_88f63a89-664f-4315-b4f8-04a0b33803a7.xml |   18 +
 ...30_get_8987f8f0-4d93-4481-968c-a2ccbd6b8be2.xml |    7 +
 ...30_get_8e5fa0f6-3f29-4d1f-abe2-d9866f3def98.xml |   58 +
 ...30_get_9000ec29-5649-474e-b2d6-55c00f8a52c0.xml |    7 +
 ...30_get_91914d35-7bbf-45e6-9b37-5ef484869a4e.xml |   38 +
 ...30_get_92d4844d-57d5-4cf3-8f47-ba50e369dc04.xml |    6 +
 ...30_get_9c0e2a4b-b4e6-41c0-b630-c8c99fc89ff3.xml |    7 +
 ...30_get_9d7ffac8-9798-428d-8e27-3cd12497ee6b.xml |    7 +
 ...w30_get_Exception-GetDomain-value-reference.xml |    7 +
 .../suites_csw30_get_Exception-GetDomain.xml       |    7 +
 ...uites_csw30_get_Exception-GetRecordById-404.xml |    7 +
 ...es_csw30_get_Exception-GetRecordById-dc.xml.xml |    9 +
 ...30_get_Exception-GetRepositoryItem-notfound.xml |    7 +
 .../suites_csw30_get_Exception-invalid-request.xml |    7 +
 .../suites_csw30_get_GetCapabilities-base-url.xml  |  491 ++++
 ...suites_csw30_get_GetCapabilities-no-version.xml |  491 ++++
 .../expected/suites_csw30_get_GetCapabilities.xml  |  491 ++++
 .../suites_csw30_get_GetDomain-parameter.xml       |   12 +
 .../suites_csw30_get_GetDomain-value-reference.xml |   18 +
 .../suites_csw30_get_GetRepositoryItem.xml         |   11 +
 .../suites_csw30_get_OpenSearch-description.xml    |   15 +
 ...30_get_a2f18643-e24e-4fa5-b780-6de4a2dbc814.xml |    9 +
 ...30_get_abc90c8c-5868-4405-a73e-64c849be3b2a.xml |    7 +
 ...30_get_ad0c0571-09ed-436a-9a4f-a5de744c88fe.xml |   22 +
 ...30_get_af502903-f4ee-47ee-b76e-af878d238bcc.xml |   40 +
 ...30_get_b2aafc3f-4f35-47bc-affd-08590972deae.xml |   58 +
 ...30_get_b6069623-f7d8-4021-8582-98f0aea0f763.xml |   48 +
 ...30_get_b9a07a54-75a8-45bd-b341-2823600211e3.xml |    8 +
 ...30_get_baa4a7d0-0c01-42b6-adc3-0d03e9949fa3.xml |    7 +
 ...30_get_bfbe6409-f64a-4c89-acb3-50f260a5c743.xml |   15 +
 ...30_get_bfe20134-d1da-42ef-9c0f-8e1307bbf92b.xml |   38 +
 ...30_get_c03d173a-3f42-4956-89c8-1fe02c3a0873.xml |  491 ++++
 ...30_get_cb43d8c3-e14c-4a9f-9231-4384b7dd21f3.xml |    7 +
 ...30_get_d03c6fd3-e821-4a26-b62f-d20a474e25af.xml |   30 +
 ...30_get_d4ccbf96-a529-480e-a53d-5b88dc1dea7f.xml |    7 +
 ...30_get_d94c801a-1207-4897-b84a-53f3a192515b.xml |    6 +
 ...30_get_da859e34-91fc-495a-8c09-285a40c0900b.xml |   14 +
 ...30_get_dc246fb8-5af5-4fda-82bb-c18b3ecd439c.xml |   40 +
 ...30_get_de016645-6d5c-4855-943c-2db07ae9f49a.xml |   30 +
 ...0_get_dff3ec6b-bb2d-4887-bd17-8fcf15def042.xml} |   74 +-
 ...30_get_e38e6bfb-8ac4-4ae4-8b87-0aafbc8d3c6b.xml |   11 +
 ...30_get_e67ca935-d65d-4d8c-8302-1405333dded0.xml |  491 ++++
 ...30_get_e7704509-3441-458f-8ef0-e333c6b6043f.xml |    7 +
 ...30_get_f1223a49-6d08-44ff-97fe-4c32cbbfad82.xml |    6 +
 ...30_get_f89dd4e1-3a81-4433-afd2-a3fa1bdb1e18.xml |    7 +
 ..._post_Exception-GetDomain-parametername-bad.xml |    7 +
 ...post_Exception-GetDomain-valuereference-bad.xml |    7 +
 ...ites_csw30_post_Exception-GetRecordById-404.xml |    7 +
 ..._csw30_post_Exception-GetRecordById-bad-esn.xml |    7 +
 .../suites_csw30_post_Exception-bad-xml.xml        |    8 +
 .../suites_csw30_post_Exception-not-xml.xml        |    8 +
 .../expected/suites_csw30_post_GetCapabilities.xml |  491 ++++
 .../suites_csw30_post_GetDomain-parametername.xml  |   12 +
 .../suites_csw30_post_GetDomain-valuereference.xml |   18 +
 .../suites_csw30_post_GetRecordById-dc-full.xml    |   10 +
 .../suites_csw30_post_GetRecordById-dc.xml         |   10 +
 ...lt_get_Exception-GetRepositoryItem-notfound.xml |    7 +
 ...default_get_GetCapabilities-invalid-request.xml |    2 +-
 .../suites_default_get_GetCapabilities.xml         |  158 +-
 .../expected/suites_default_get_GetRecords-all.xml |    2 +-
 ...tes_default_get_GetRecords-empty-maxrecords.xml |    6 +
 .../suites_default_get_GetRecords-filter.xml       |    2 +-
 .../suites_default_get_GetRecords-sortby-asc.xml   |    2 +-
 .../suites_default_get_GetRecords-sortby-desc.xml  |    2 +-
 ...default_get_GetRecords-sortby-invalid-order.xml |    2 +-
 ..._get_GetRecords-sortby-invalid-propertyname.xml |    2 +-
 .../suites_default_get_GetRepositoryItem.xml       |   14 +
 .../suites_default_post_DescribeRecord-json.xml    |  595 ++---
 .../suites_default_post_DescribeRecord.xml         |    2 +-
 ...efault_post_Exception-GetRecords-badsrsname.xml |    2 +-
 ...fault_post_Exception-GetRecords-elementname.xml |    2 +-
 ...fault_post_Exception-GetRecords-invalid-xml.xml |    2 +-
 .../suites_default_post_GetCapabilities-SOAP.xml   |  158 +-
 ...uites_default_post_GetCapabilities-sections.xml |    8 +-
 ...default_post_GetCapabilities-updatesequence.xml |  158 +-
 .../suites_default_post_GetCapabilities.xml        |  158 +-
 .../suites_default_post_GetDomain-parameter.xml    |    4 +-
 .../suites_default_post_GetDomain-property.xml     |    2 +-
 .../suites_default_post_GetRecordById-json.xml     |   62 +-
 .../expected/suites_default_post_GetRecordById.xml |    2 +-
 .../suites_default_post_GetRecords-all-json.xml    |  227 +-
 ...default_post_GetRecords-all-resulttype-hits.xml |    2 +-
 ...ult_post_GetRecords-all-resulttype-validate.xml |    2 +-
 ...tes_default_post_GetRecords-all-sortby-bbox.xml |    2 +-
 .../suites_default_post_GetRecords-all.xml         |    2 +-
 ...s_default_post_GetRecords-bbox-filter-crs84.xml |    2 +-
 .../suites_default_post_GetRecords-cql-title.xml   |    2 +-
 ...s_default_post_GetRecords-distributedsearch.xml |    4 +-
 .../suites_default_post_GetRecords-elementname.xml |    2 +-
 .../suites_default_post_GetRecords-end.xml         |    2 +-
 ...lt_post_GetRecords-filter-and-bbox-freetext.xml |    2 +-
 ...efault_post_GetRecords-filter-and-nested-or.xml |    2 +-
 ...fault_post_GetRecords-filter-and-nested-or2.xml |    2 +-
 ...ault_post_GetRecords-filter-anytext-and-not.xml |    2 +-
 ...efault_post_GetRecords-filter-anytext-equal.xml |    2 +-
 ...ites_default_post_GetRecords-filter-anytext.xml |    2 +-
 ...fault_post_GetRecords-filter-bbox-reproject.xml |    2 +-
 ..._default_post_GetRecords-filter-bbox-sortby.xml |    2 +-
 .../suites_default_post_GetRecords-filter-bbox.xml |    2 +-
 ...ites_default_post_GetRecords-filter-between.xml |    2 +-
 ...default_post_GetRecords-filter-function-bad.xml |    2 +-
 ...tes_default_post_GetRecords-filter-function.xml |    2 +-
 ...tes_default_post_GetRecords-filter-not-bbox.xml |    2 +-
 ...ult_post_GetRecords-filter-or-bbox-freetext.xml |    2 +-
 ...efault_post_GetRecords-filter-or-nested-and.xml |    2 +-
 ...lt_post_GetRecords-filter-or-title-abstract.xml |    2 +-
 .../suites_default_post_GetRecords-maxrecords.xml  |    2 +-
 .../suites_default_post_GetRecords-requestid.xml   |    2 +-
 .../suites_default_post_Harvest-default.xml        |    2 +-
 ...uites_default_post_Harvest-response-handler.xml |    2 +-
 .../suites_default_post_Transaction-delete.xml     |    2 +-
 .../suites_default_post_Transaction-insert.xml     |    2 +-
 ...suites_default_post_Transaction-update-full.xml |    2 +-
 ...ault_post_Transaction-update-recordproperty.xml |    2 +-
 tests/expected/suites_dif_post_DescribeRecord.xml  |    2 +-
 tests/expected/suites_dif_post_GetCapabilities.xml |  158 +-
 .../suites_dif_post_GetRecords-filter-bbox.xml     |    2 +-
 .../expected/suites_ebrim_post_DescribeRecord.xml  |    8 +-
 .../expected/suites_ebrim_post_GetCapabilities.xml |  162 +-
 ...ites_ebrim_post_GetRecords-filter-bbox-full.xml |    2 +-
 .../suites_ebrim_post_GetRecords-filter-bbox.xml   |    2 +-
 tests/expected/suites_fgdc_post_DescribeRecord.xml |    2 +-
 .../expected/suites_fgdc_post_GetCapabilities.xml  |  158 +-
 .../suites_fgdc_post_GetRecords-filter-bbox.xml    |    2 +-
 ...es.xml => suites_gm03_post_GetCapabilities.xml} |  174 +-
 .../suites_gm03_post_GetRecords-filter-bbox.xml    |  137 +
 ..._get_Exception-Harvest-invalid-resourcetype.xml |    4 +-
 ..._get_Exception-Harvest-missing-resourcetype.xml |    2 +-
 ...esting_get_Exception-Harvest-missing-source.xml |    2 +-
 ...vesting_get_Exception-Harvest-waf-bad-value.xml |    2 +-
 ..._get_Exception-Harvest-waf-no-records-found.xml |    2 +-
 ...suites_harvesting_post_Clear-000-delete-all.xml |    2 +-
 ...es_harvesting_post_Exception-Havest-csw-404.xml |    2 +-
 .../suites_harvesting_post_GetCapabilities.xml     |   41 +-
 .../suites_harvesting_post_GetDomain-parameter.xml |   11 +-
 .../suites_harvesting_post_Harvest-csw-iso.xml     |  160 +-
 .../suites_harvesting_post_Harvest-csw-run1.xml    |    4 +-
 .../suites_harvesting_post_Harvest-csw-run2.xml    |    2 +-
 .../expected/suites_harvesting_post_Harvest-dc.xml |    2 +-
 .../suites_harvesting_post_Harvest-fgdc.xml        |    2 +-
 .../suites_harvesting_post_Harvest-iso.xml         |    2 +-
 .../suites_harvesting_post_Harvest-rdf.xml         |    2 +-
 .../suites_harvesting_post_Harvest-sos100.xml      |    2 +-
 .../suites_harvesting_post_Harvest-sos200.xml      |    2 +-
 .../suites_harvesting_post_Harvest-waf.xml         |    2 +-
 .../suites_harvesting_post_Harvest-wcs.xml         |    2 +-
 .../suites_harvesting_post_Harvest-wfs.xml         |    2 +-
 .../suites_harvesting_post_Harvest-wms-run1.xml    |   10 +-
 .../suites_harvesting_post_Harvest-wms-run2.xml    |    2 +-
 .../suites_harvesting_post_Harvest-wmts.xml        |  713 ++++++
 .../suites_harvesting_post_Harvest-wps.xml         |    2 +-
 ...t_Harvest-zzz-post-GetRecords-filter-ows-dc.xml |   25 +-
 ...-zzz-post-GetRecords-filter-sos-abstract-dc.xml |    2 +-
 ...t_Harvest-zzz-post-GetRecords-filter-sos-dc.xml |    2 +-
 ..._Harvest-zzz-post-GetRecords-filter-sos-iso.xml |    2 +-
 ..._Harvest-zzz-post-GetRecords-filter-wfs-iso.xml |   10 +-
 ...t_Harvest-zzz-post-GetRecords-filter-wms-dc.xml |   68 +-
 ..._Harvest-zzz-post-GetRecords-filter-wms-iso.xml | 1065 +++++++-
 ...arvest-zzz-post-GetRecords-filter-wms-layer.xml |    2 +-
 ..._harvesting_post_Transaction-000-delete-all.xml |    4 +-
 .../suites_manager_post_Clear-000-delete-all.xml   |    2 +-
 .../suites_manager_post_GetCapabilities.xml        |  293 ++-
 .../suites_manager_post_GetDomain-parameter.xml    |   25 +-
 ...tes_manager_post_Transaction-000-delete-all.xml |    2 +-
 ...uites_manager_post_Transaction-dc-01-insert.xml |    2 +-
 ..._manager_post_Transaction-dc-02-update-full.xml |    2 +-
 ...tes_manager_post_Transaction-fgdc-01-insert.xml |    2 +-
 ...ger_post_Transaction-fgdc-02-update-recprop.xml |    2 +-
 ...manager_post_Transaction-fgdc-03-delete-all.xml |    2 +-
 ..._manager_post_Transaction-iso-00-delete-all.xml |    2 +-
 ...ites_manager_post_Transaction-iso-01-insert.xml |    2 +-
 ...manager_post_Transaction-iso-02-update-full.xml |    2 +-
 ...ager_post_Transaction-iso-03-update-recprop.xml |    2 +-
 ...ransaction-iso-04-update-recprop-no-matches.xml |    2 +-
 ...ites_manager_post_Transaction-iso-05-delete.xml |    2 +-
 ...tes_manager_post_Transaction-xxx-delete-all.xml |    2 +-
 ...es_oaipmh_get_GetRecord_bad_metadata_prefix.xml |    2 +-
 tests/expected/suites_oaipmh_get_GetRecord_dc.xml  |    2 +-
 tests/expected/suites_oaipmh_get_GetRecord_iso.xml |    2 +-
 .../suites_oaipmh_get_GetRecord_oai_dc.xml         |    2 +-
 tests/expected/suites_oaipmh_get_Identify.xml      |    2 +-
 ...pmh_get_ListIdentifiers_bad_metadata_prefix.xml |    2 +-
 .../suites_oaipmh_get_ListIdentifiers_dc.xml       |    2 +-
 .../suites_oaipmh_get_ListIdentifiers_iso.xml      |    2 +-
 ...get_ListIdentifiers_missing_metadata_prefix.xml |    2 +-
 .../suites_oaipmh_get_ListIdentifiers_oai_dc.xml   |    2 +-
 .../suites_oaipmh_get_ListMetadataFormats.xml      |   29 +-
 .../expected/suites_oaipmh_get_ListRecords_dc.xml  |    2 +-
 ...ipmh_get_ListRecords_dc_bad_metadata_prefix.xml |    2 +-
 .../suites_oaipmh_get_ListRecords_iso19139.xml     |    2 +-
 .../suites_oaipmh_get_ListRecords_oai_dc.xml       |    2 +-
 tests/expected/suites_oaipmh_get_ListSets.xml      |    2 +-
 tests/expected/suites_oaipmh_get_bad_verb.xml      |    2 +-
 tests/expected/suites_oaipmh_get_empty.xml         |    2 +-
 .../expected/suites_oaipmh_get_empty_with_amp.xml  |    2 +-
 tests/expected/suites_oaipmh_get_illegal_verb.xml  |    2 +-
 ...suites_repofilter_post_GetRecordById-masked.xml |    2 +-
 .../suites_repofilter_post_GetRecords-all.xml      |    2 +-
 tests/expected/suites_sru_get_explain.xml          |   78 +-
 tests/expected/suites_sru_get_search.xml           |    8 +-
 tests/expected/suites_sru_get_search_cql.xml       |   36 +-
 .../expected/suites_sru_get_search_maxrecords.xml  |   36 +-
 ...uites_sru_get_search_startrecord_maxrecords.xml |   36 +-
 .../expected/suites_utf-8_post_GetCapabilities.xml |  158 +-
 tests/gen_html.py                                  |   34 +-
 tests/index.html                                   |   99 +
 tests/run_tests.py                                 |  433 +++-
 tests/suites/apiso/data/README.txt                 |    7 +
 tests/suites/cite/data/README.txt                  |   65 +
 tests/suites/cite/data/{records.db => cite.db}     |  Bin
 .../suites/csw30/default.cfg                       |   60 +-
 tests/suites/csw30/get/requests.txt                |   82 +
 .../post/Exception-GetDomain-parametername-bad.xml |    4 +
 .../Exception-GetDomain-valuereference-bad.xml     |    4 +
 .../csw30/post/Exception-GetRecordById-404.xml     |    4 +
 .../csw30/post/Exception-GetRecordById-bad-esn.xml |    5 +
 tests/suites/csw30/post/Exception-bad-xml.xml      |    9 +
 tests/suites/csw30/post/Exception-not-xml.xml      |    1 +
 tests/suites/csw30/post/GetCapabilities.xml        |    9 +
 .../suites/csw30/post/GetDomain-parametername.xml  |    4 +
 .../suites/csw30/post/GetDomain-valuereference.xml |    4 +
 tests/suites/csw30/post/GetRecordById-dc-full.xml  |    5 +
 tests/suites/csw30/post/GetRecordById-dc.xml       |    4 +
 tests/suites/default/get/requests.txt              |    3 +
 .../suites/gm03/default.cfg                        |   60 +-
 tests/suites/gm03/post/GetCapabilities.xml         |    9 +
 tests/suites/gm03/post/GetRecords-filter-bbox.xml  |   17 +
 tests/suites/harvesting/post/Harvest-csw-iso.xml   |    5 +-
 tests/suites/harvesting/post/Harvest-wmts.xml      |    6 +
 636 files changed, 42191 insertions(+), 8146 deletions(-)

diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md
new file mode 100644
index 0000000..6f75fc0
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE.md
@@ -0,0 +1,21 @@
+# Description
+
+# Environment
+
+- operating system:
+- Python version:
+- pycsw version:
+- source/distribution
+ - [ ] git clone
+ - [ ] DebianGIS/UbuntuGIS
+ - [ ] PyPI
+ - [ ] zip/tar.gz
+ - [ ] other (please specify):
+- web server
+ - [ ] Apache/mod_wsgi
+ - [ ] CGI
+ - [ ] other (please specify): 
+
+# Steps to Reproduce
+
+# Additional Information
diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md
new file mode 100644
index 0000000..4042f50
--- /dev/null
+++ b/.github/PULL_REQUEST_TEMPLATE.md
@@ -0,0 +1,12 @@
+# Overview
+
+# Related Issue / Discussion
+
+# Additional Information
+
+# Contributions and Licensing
+
+(as per https://github.com/geopython/pycsw/blob/master/CONTRIBUTING.rst#contributions-and-licensing)
+
+- [ ] I'd like to contribute [feature X|bugfix Y|docs|something else] to pycsw. I confirm that my contributions to pycsw will be compatible with the pycsw license guidelines at the time of contribution.
+- [ ] I have already previously agreed to the pycsw Contributions and Licensing Guidelines
diff --git a/.travis.yml b/.travis.yml
index a25d57d..c34d7b6 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,18 +1,31 @@
 language: python
 
+sudo: required
+dist: trusty
+
 python:
-  - "2.7"
   - "2.6"
+  - "2.7"
+  - "3.4"
 
-install:
-  - sudo apt-get install -y libgeos-c1
-  - pip install . --use-mirrors
-  - pip install -r ./requirements-standalone.txt
-  - pip install -r ./requirements-dev.txt
-  - python ./setup.py -q install
+#matrix:
+#  allow_failures:
+#    - python: "3.4"
 
-#before_script:
-#  - paver start
+addons:
+  apt:
+    packages:
+      - libgeos-c1
+      - libxml2-dev
+
+before_script:
+  - pycsw-admin.py -c get_sysprof
+
+install:
+  - pip install -r requirements.txt
+  - pip install -r requirements-dev.txt
+  - pip install -r requirements-standalone.txt
+  - python setup.py -q install
 
 script:
   - paver test
@@ -23,6 +36,5 @@ after_script:
 notifications:
   irc:
     channels:
-      #- "irc.freenode.org#geopython"
       - "irc.freenode.org#pycsw"
     use_notice: true
diff --git a/COMMITTERS.txt b/COMMITTERS.txt
index 4fb8b80..b0474d9 100644
--- a/COMMITTERS.txt
+++ b/COMMITTERS.txt
@@ -1,7 +1,8 @@
-============ ===================== =========================== ==================================
-Login(s)     Name                  Email / Contact             Area(s)
-============ ===================== =========================== ==================================
-tomkralidis  Tom Kralidis          tomkralidis at gmail.com    Overall 
-kalxas       Angelos Tzotsos       tzotsos at gmail.com        INSPIRE, APISO profiles, Packaging 
-adamhinz     Adam Hinz             hinz dot adam at gmail.com  WSGI/Server Deployment
-============ ===================== =========================== ==================================
+============== ===================== ================================== ==================================
+Login(s)       Name                  Email / Contact                    Area(s)
+============== ===================== ================================== ==================================
+tomkralidis    Tom Kralidis          tomkralidis at gmail.com           Overall 
+kalxas         Angelos Tzotsos       tzotsos at gmail.com               INSPIRE, APISO profiles, Packaging 
+adamhinz       Adam Hinz             hinz dot adam at gmail.com         WSGI/Server Deployment
+ricardogsilva  Ricardo Garcia Silva  ricardo.garcia.silva at gmail.com  Overall
+============== ===================== ================================== ==================================
diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst
index 306f819..e551cc6 100644
--- a/CONTRIBUTING.rst
+++ b/CONTRIBUTING.rst
@@ -3,7 +3,7 @@ Contributing to pycsw
 
 The pycsw project openly welcomes contributions (bug reports, bug fixes, code
 enhancements/features, etc.).  This document will outline some guidelines on
-contributing to pycsw.  As well, pycsw `community </community.html>`_ is a great place to
+contributing to pycsw.  As well, the pycsw `community </community.html>`_ is a great place to
 get an idea of how to connect and participate in pycsw community and development.
 
 pycsw has the following modes of contribution:
@@ -11,6 +11,11 @@ pycsw has the following modes of contribution:
 - GitHub Commit Access
 - GitHub Pull Requests
 
+Code of Conduct
+---------------
+
+Contributors to this project are expected to act respectfully toward others in accordance with the `OSGeo Code of Conduct <http://www.osgeo.org/code_of_conduct>`_.
+
 Contributions and Licensing
 ---------------------------
 
@@ -102,24 +107,24 @@ This section will guide you through steps of working on pycsw.  This section ass
 .. code-block:: bash
 
   # setup a virtualenv
-  $ virtualenv mypycsw && cd mypycsw
-  $ . ./bin/activate
+  virtualenv mypycsw && cd mypycsw
+  . ./bin/activate
   # clone the repository locally
-  $ git clone git at github.com:USERNAME/pycsw.git
-  $ cd pycsw
-  $ pip install -e . && pip install -r requirements-standalone.txt
+  git clone git at github.com:USERNAME/pycsw.git
+  cd pycsw
+  pip install -e . && pip install -r requirements-standalone.txt
   # add the main pycsw master branch to keep up to date with upstream changes
-  $ git remote add upstream https://github.com/geopython/pycsw.git
-  $ git pull upstream master
+  git remote add upstream https://github.com/geopython/pycsw.git
+  git pull upstream master
   # create a local branch off master
   # The name of the branch should include the issue number if it exists
-  $ git branch 72-foo
-  $ git checkout 72-foo
+  git branch issue-72
+  git checkout issue-72
   # 
   # make code/doc changes
   #
-  $ git commit -am 'fix xyz (#72-foo)'
-  $ git push origin 72-foo
+  git commit -am 'fix xyz (#72)'
+  git push origin issue-72
 
 Your changes are now visible on your pycsw repository on GitHub.  You are now ready to create a pull request.
 A member of the pycsw team will review the pull request and provide feedback / suggestions if required.  If changes are
@@ -130,8 +135,8 @@ your own repository to ensure your pycsw repository is up to date with pycsw mas
 
 .. code-block:: bash
 
-  $ git checkout master
-  $ git pull upstream master
+  git checkout master
+  git pull upstream master
 
 .. _`Corporate`: http://www.osgeo.org/sites/osgeo.org/files/Page/corporate_contributor.txt
 .. _`Individual`: http://www.osgeo.org/sites/osgeo.org/files/Page/individual_contributor.txt
diff --git a/LICENSE.txt b/LICENSE.txt
index 1400127..a7e635b 100644
--- a/LICENSE.txt
+++ b/LICENSE.txt
@@ -1,6 +1,9 @@
 The MIT License (MIT)
 
-Copyright (c) 2010-2014 Tom Kralidis
+Copyright (c) 2010-2015 Tom Kralidis
+Copyright (c) 2011-2015 Angelos Tzotsos
+Copyright (c) 2012-2015 Adam Hinz
+Copyright (c) 2015      Ricardo Garcia Silva
 
 Permission is hereby granted, free of charge, to any person obtaining a copy
 of this software and associated documentation files (the "Software"), to deal
diff --git a/VERSION.txt b/VERSION.txt
index 18b3114..5d8955f 100644
--- a/VERSION.txt
+++ b/VERSION.txt
@@ -1 +1 @@
-1.10.4
+2.0.0-alpha1
diff --git a/bin/pycsw-admin.py b/bin/pycsw-admin.py
index 2a18a9f..65481bd 100755
--- a/bin/pycsw-admin.py
+++ b/bin/pycsw-admin.py
@@ -1,11 +1,11 @@
 #!/usr/bin/python
-# -*- coding: ISO-8859-15 -*-
+# -*- coding: utf-8 -*-
 # =================================================================
 #
 # Authors: Tom Kralidis <tomkralidis at gmail.com>
 #          Angelos Tzotsos <tzotsos at gmail.com>
 #
-# Copyright (c) 2012 Tom Kralidis
+# Copyright (c) 2015 Tom Kralidis
 #
 # Permission is hereby granted, free of charge, to any person
 # obtaining a copy of this software and associated documentation
@@ -30,12 +30,13 @@
 #
 # =================================================================
 
-import ConfigParser
+from six.moves import configparser
+from six.moves import input
 import getopt
 import logging
 import sys
 
-from pycsw import admin, config
+from pycsw.core import admin, config
 
 logging.basicConfig(format='%(message)s', level=logging.DEBUG)
 
@@ -72,7 +73,7 @@ SYNOPSIS
 
     -o    path to output file
 
-    -p    path to input/output directory to read/write metadata records
+    -p    path to input/output directory or file to read/write metadata records
 
     -r    load records from directory recursively
 
@@ -93,7 +94,7 @@ EXAMPLES
 
         pycsw-admin.py -c setup_db -f default.cfg
         
-    2.) load_records: Loads metadata records from directory into repository
+    2.) load_records: Loads metadata records from directory or file into repository
 
         pycsw-admin.py -c load_records -p /path/to/records -f default.cfg
 
@@ -105,6 +106,10 @@ EXAMPLES
 
         pycsw-admin.py -c load_records -p /path/to/records -f default.cfg -y
 
+        Load metadata record from file into repository
+
+        pycsw-admin.py -c load_records -p /path/to/file.xml -f default.cfg
+
     3.) export_records: Dump metadata records from repository into directory
 
         pycsw-admin.py -c export_records -p /path/to/records -f default.cfg
@@ -160,14 +165,14 @@ TIMEOUT = 30
 FORCE_CONFIRM = False
 
 if len(sys.argv) == 1:
-    print usage()
+    print(usage())
     sys.exit(1)
 
 try:
     OPTS, ARGS = getopt.getopt(sys.argv[1:], 'c:f:ho:p:ru:x:s:t:y')
 except getopt.GetoptError as err:
-    print '\nERROR: %s' % err
-    print usage()
+    print('\nERROR: %s' % err)
+    print(usage())
     sys.exit(2)
 
 for o, a in OPTS:
@@ -190,13 +195,13 @@ for o, a in OPTS:
     if o == '-t':
         TIMEOUT = int(a)
     if o == '-h':  # dump help and exit
-        print usage()
+        print(usage())
         sys.exit(3)
     if o == '-y':
         FORCE_CONFIRM = True
 
 if COMMAND is None:
-    print '-c <command> is a required argument'
+    print('-c <command> is a required argument')
     sys.exit(4)
 
 if COMMAND not in ['setup_db', 'load_records', 'export_records',
@@ -204,24 +209,25 @@ if COMMAND not in ['setup_db', 'load_records', 'export_records',
                    'refresh_harvested_records', 'gen_sitemap',
                    'post_xml', 'get_sysprof',
                    'validate_xml', 'delete_records']:
-    print 'ERROR: invalid command name: %s' % COMMAND
+    print('ERROR: invalid command name: %s' % COMMAND)
     sys.exit(5)
 
 if CFG is None and COMMAND not in ['post_xml', 'get_sysprof', 'validate_xml']:
-    print 'ERROR: -f <cfg> is a required argument'
+    print('ERROR: -f <cfg> is a required argument')
     sys.exit(6)
 
 if COMMAND in ['load_records', 'export_records'] and XML_DIRPATH is None:
-    print 'ERROR: -p </path/to/records> is a required argument'
+    print('ERROR: -p </path/to/records> is a required argument')
     sys.exit(7)
 
 if COMMAND == 'gen_sitemap' and OUTPUT_FILE is None:
-    print 'ERROR: -o </path/to/sitemap.xml> is a required argument'
+    print('ERROR: -o </path/to/sitemap.xml> is a required argument')
     sys.exit(8)
 
 if COMMAND not in ['post_xml', 'get_sysprof', 'validate_xml']:
-    SCP = ConfigParser.SafeConfigParser()
-    SCP.readfp(open(CFG))
+    SCP = configparser.SafeConfigParser()
+    with open(CFG) as f:
+        SCP.readfp(f)
 
     DATABASE = SCP.get('repository', 'database')
     URL = SCP.get('server', 'url')
@@ -229,31 +235,31 @@ if COMMAND not in ['post_xml', 'get_sysprof', 'validate_xml']:
     METADATA = dict(SCP.items('metadata:main'))
     try:
         TABLE = SCP.get('repository', 'table')
-    except ConfigParser.NoOptionError:
+    except configparser.NoOptionError:
         TABLE = 'records'
 
 elif COMMAND not in ['get_sysprof', 'validate_xml']:
     if CSW_URL is None:
-        print 'ERROR: -u <http://host/csw> is a required argument'
+        print('ERROR: -u <http://host/csw> is a required argument')
         sys.exit(9)
     if XML is None:
-        print 'ERROR: -x /path/to/request.xml is a required argument'
+        print('ERROR: -x /path/to/request.xml is a required argument')
         sys.exit(10)
 elif COMMAND == 'validate_xml':
     if XML is None:
-        print 'ERROR: -x /path/to/file.xml is a required argument'
+        print('ERROR: -x /path/to/file.xml is a required argument')
         sys.exit(11)
     if XSD is None:
-        print 'ERROR: -s /path/to/file.xsd is a required argument'
+        print('ERROR: -s /path/to/file.xsd is a required argument')
         sys.exit(12)
 
 if COMMAND == 'setup_db':
     try:
         admin.setup_db(DATABASE, TABLE, HOME)
     except Exception as err:
-        print err
-        print 'ERROR: DB creation error.  Database tables already exist'
-        print 'Delete tables or database to reinitialize'
+        print(err)
+        print('ERROR: DB creation error.  Database tables already exist')
+        print('Delete tables or database to reinitialize')
 elif COMMAND == 'load_records':
     admin.load_records(CONTEXT, DATABASE, TABLE, XML_DIRPATH, RECURSIVE, FORCE_CONFIRM)
 elif COMMAND == 'export_records':
@@ -267,16 +273,16 @@ elif COMMAND == 'refresh_harvested_records':
 elif COMMAND == 'gen_sitemap':
     admin.gen_sitemap(CONTEXT, DATABASE, TABLE, URL, OUTPUT_FILE)
 elif COMMAND == 'post_xml':
-    print admin.post_xml(CSW_URL, XML, TIMEOUT)
+    print(admin.post_xml(CSW_URL, XML, TIMEOUT))
 elif COMMAND == 'get_sysprof':
-    print admin.get_sysprof()
+    print(admin.get_sysprof())
 elif COMMAND == 'validate_xml':
     admin.validate_xml(XML, XSD)
 elif COMMAND == 'delete_records':
     if not FORCE_CONFIRM:
-        if raw_input('This will delete all records! Continue? [Y/n] ') == 'Y':
+        if input('This will delete all records! Continue? [Y/n] ') == 'Y':
             FORCE_CONFIRM = True
     if FORCE_CONFIRM:
         admin.delete_records(CONTEXT, DATABASE, TABLE)
 
-print 'Done'
+print('Done')
diff --git a/bin/pycsw-pylint.sh b/bin/pycsw-pylint.sh
index 43e262c..b15f50e 100755
--- a/bin/pycsw-pylint.sh
+++ b/bin/pycsw-pylint.sh
@@ -3,7 +3,7 @@
 #
 # Authors: Tom Kralidis <tomkralidis at gmail.com>
 #
-# Copyright (c) 2011 Tom Kralidis
+# Copyright (c) 2015 Tom Kralidis
 #
 # Permission is hereby granted, free of charge, to any person
 # obtaining a copy of this software and associated documentation
diff --git a/csw.py b/csw.py
index 79fb7a7..ca48728 100755
--- a/csw.py
+++ b/csw.py
@@ -1,10 +1,10 @@
 #!/usr/bin/python -u
-# -*- coding: iso-8859-15 -*-
+# -*- coding: utf-8 -*-
 # =================================================================
 #
 # Authors: Tom Kralidis <tomkralidis at gmail.com>
 #
-# Copyright (c) 2010 Tom Kralidis
+# Copyright (c) 2015 Tom Kralidis
 #
 # Permission is hereby granted, free of charge, to any person
 # obtaining a copy of this software and associated documentation
@@ -29,56 +29,14 @@
 #
 # =================================================================
 
-# CGI wrapper for pycsw
+"""
+A CGI wrapper for pycsw that reuses code from the wsgi wrapper.
+"""
 
-import os
-import sys
-from StringIO import StringIO
-from pycsw import server
+from wsgiref.handlers import CGIHandler
 
-CONFIG = 'default.cfg'
-GZIP = False
+from pycsw.wsgi import application
 
-if 'PYCSW_CONFIG' in os.environ:
-    CONFIG = os.environ['PYCSW_CONFIG']
-if os.environ['QUERY_STRING'].lower().find('config') != -1:
-    for kvp in os.environ['QUERY_STRING'].split('&'):
-        if kvp.lower().find('config') != -1:
-            CONFIG = kvp.split('=')[1]
 
-if ('HTTP_ACCEPT_ENCODING' in os.environ and
-        os.environ['HTTP_ACCEPT_ENCODING'].find('gzip') != -1):
-    # set for gzip compressed response
-    GZIP = True
-
-# get runtime configuration
-CSW = server.Csw(CONFIG)
-
-# set compression level
-if CSW.config.has_option('server', 'gzip_compresslevel'):
-    GZIP_COMPRESSLEVEL = \
-        int(CSW.config.get('server', 'gzip_compresslevel'))
-else:
-    GZIP_COMPRESSLEVEL = 0
-
-# go!
-OUTP = CSW.dispatch_cgi()
-
-sys.stdout.write("Content-Type:%s\r\n" % CSW.contenttype)
-
-if GZIP and GZIP_COMPRESSLEVEL > 0:
-    import gzip
-
-    BUF = StringIO()
-    GZIPFILE = gzip.GzipFile(mode='wb', fileobj=BUF,
-                             compresslevel=GZIP_COMPRESSLEVEL)
-    GZIPFILE.write(OUTP)
-    GZIPFILE.close()
-
-    OUTP = BUF.getvalue()
-
-    sys.stdout.write('Content-Encoding: gzip\r\n')
-
-sys.stdout.write('Content-Length: %d\r\n' % len(OUTP))
-sys.stdout.write('\r\n')
-sys.stdout.write(OUTP)
+handler = CGIHandler()
+handler.run(application)
diff --git a/default-sample.cfg b/default-sample.cfg
index 5420a7f..b8ed08f 100644
--- a/default-sample.cfg
+++ b/default-sample.cfg
@@ -2,7 +2,7 @@
 #
 # Authors: Tom Kralidis <tomkralidis at gmail.com>
 #
-# Copyright (c) 2010 Tom Kralidis
+# Copyright (c) 2015 Tom Kralidis
 #
 # Permission is hereby granted, free of charge, to any person
 # obtaining a copy of this software and associated documentation
@@ -37,7 +37,7 @@ maxrecords=10
 #loglevel=DEBUG
 #logfile=/tmp/pycsw.log
 #ogc_schemas_base=http://foo
-#federatedcatalogues=http://geo.data.gov/geoportal/csw/discovery
+#federatedcatalogues=http://catalog.data.gov/csw
 #pretty_print=true
 #gzip_compresslevel=8
 #domainquerytype=range
@@ -76,7 +76,7 @@ contact_role=pointOfContact
 
 [repository]
 # sqlite
-database=sqlite:////var/www/pycsw/tests/suites/cite/data/records.db
+database=sqlite:////var/www/pycsw/tests/suites/cite/data/cite.db
 # postgres
 #database=postgresql://username:password@localhost/pycsw
 # mysql
diff --git a/docs/_templates/layout.html b/docs/_templates/layout.html
index 631e4ee..8ede7b4 100644
--- a/docs/_templates/layout.html
+++ b/docs/_templates/layout.html
@@ -34,7 +34,7 @@
 {% block footer %}
 
 <div class="footer">
-    <p>© Copyright {{ copyright }}. Last updated on {{ last_updated }}</p>
+    <p>© Copyright {{ copyright }}<br/>Last updated on {{ last_updated }}</p>
     <p>
         <a href="http://pycsw.org">Website</a> —
         <a href="http://pycsw.org/community">Community</a> —
diff --git a/docs/administration.rst b/docs/administration.rst
index e7a5068..a5e0dc4 100644
--- a/docs/administration.rst
+++ b/docs/administration.rst
@@ -74,7 +74,7 @@ Loading Records
 
   $ pycsw-admin.py -c load_records -f default.cfg -p /path/to/records
 
-This will import all ``*.xml`` records from ``/path/to/records`` into the database specified in ``default.cfg`` (``repository.database``).  Passing ``-r`` to the script will process ``/path/to/records`` recursively.  Passing ``-y`` to the script will force overwrite existing metadata with the same identifier.
+This will import all ``*.xml`` records from ``/path/to/records`` into the database specified in ``default.cfg`` (``repository.database``).  Passing ``-r`` to the script will process ``/path/to/records`` recursively.  Passing ``-y`` to the script will force overwrite existing metadata with the same identifier.  Note that ``-p`` accepts either a directory path or single file.
 
 .. note::
   Records can also be imported using CSW-T (see :ref:`transactions`).
diff --git a/docs/conf.py b/docs/conf.py
index 0b46ad3..2444d54 100644
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -1,4 +1,32 @@
 # -*- coding: utf-8 -*-
+# =================================================================
+#
+# Authors: Tom Kralidis <tomkralidis at gmail.com>
+#
+# Copyright (c) 2015 Tom Kralidis
+#
+# Permission is hereby granted, free of charge, to any person
+# obtaining a copy of this software and associated documentation
+# files (the "Software"), to deal in the Software without
+# restriction, including without limitation the rights to use,
+# copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the
+# Software is furnished to do so, subject to the following
+# conditions:
+#
+# The above copyright notice and this permission notice shall be
+# included in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+# OTHER DEALINGS IN THE SOFTWARE.
+#
+# =================================================================
 #
 # pycsw documentation build configuration file, created by
 # sphinx-quickstart on Fri Aug  2 19:48:50 2013.
@@ -42,14 +70,16 @@ master_doc = 'index'
 # General information about the project.
 project = u'pycsw'
 authors = u'Tom Kralidis'
-copyright = u'2010-2015, ' + authors
+license = u'This work is licensed under a Creative Commons Attribution 4.0 International License'
+copyright = u'2010-2015, ' + authors + ' ' + license
 
 # The version info for the project you're documenting, acts as replacement for
 # |version| and |release|, also used in various other places throughout the
 # built documents.
 #
 # The short X.Y version.
-version = open('../VERSION.txt').read().strip()
+with open('../VERSION.txt') as f:
+    version = f.read().strip()
 # The full version, including alpha/beta/rc tags.
 release = version
 
diff --git a/docs/hhypermap.rst b/docs/hhypermap.rst
new file mode 100644
index 0000000..5b3d889
--- /dev/null
+++ b/docs/hhypermap.rst
@@ -0,0 +1,17 @@
+.. _hhypermap:
+
+HHypermap Configuration
+=======================
+
+HHypermap (Harvard Hypermap) Supervisor (https://github.com/cga-harvard/HHypermap) is an application that manages OWS, Esri REST, and other types of map service harvesting, and maintains uptime statistics for services and layers. HHypermap Supervisor will publish to HHypermap Search (based on Lucene) which provides a fast search and visualization environment for spatio-temporal materials. 
+
+HHypermap uses CSW as a cataloguing mechanism to ingest, query and present geospatial metadata.
+
+pycsw supports binding to an existing HHypermap repository for metadata query.
+
+HHypermap Setup
+---------------
+
+pycsw is enabled and configured by default in HHypermap, so there are no additional steps required once HHypermap is setup.  See the ``PYCSW`` `settings/default.py entries`_ for customizing pycsw within HHypermap.
+
+.. _`settings/default.py entries`: https://github.com/cga-harvard/HHypermap/blob/master/hypermap/settings/default.py#L197
diff --git a/docs/index.rst b/docs/index.rst
index 868fa6d..6407d22 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -20,6 +20,7 @@ pycsw |release| Documentation
    sru
    opensearch
    oaipmh
+   json
    soap
    sitemaps
    transactions
@@ -27,6 +28,7 @@ pycsw |release| Documentation
    profiles
    outputschemas
    geonode
+   hhypermap
    odc
    ckan
    testing
diff --git a/docs/installation.rst b/docs/installation.rst
index 9e0f1b9..3128224 100644
--- a/docs/installation.rst
+++ b/docs/installation.rst
@@ -45,7 +45,7 @@ The 4 minute install:
   # - server.home
   # - repository.database
   # set server.url to http://localhost:8000/
-  $ python csw.wsgi
+  $ python pycsw/wsgi.py
   $ curl http://localhost:8000/?service=CSW&version=2.0.2&request=GetCapabilities
 
 
@@ -80,7 +80,9 @@ The Clean and Proper Way
   $ python setup.py build
   $ python setup.py install
 
-At this point, pycsw is installed as a library and requires a CGI ``csw.py`` or WSGI ``csw.wsgi`` script to be served into your web server environment (see below for WSGI configuration/deployment).
+At this point, pycsw is installed as a library and requires a CGI ``csw.py``
+or WSGI ``pycsw/wsgi.py`` script to be served into your web server environment
+(see below for WSGI configuration/deployment).
 
 .. _pypi:
 
@@ -165,23 +167,33 @@ By default, ``default.cfg`` is at the root of the pycsw install.  If pycsw is se
 Running on WSGI
 ---------------
 
-pycsw supports the `Web Server Gateway Interface`_ (WSGI).  To run pycsw in WSGI mode, use ``csw.wsgi`` in your WSGI server environment.  Below is an example of configuring with Apache:
+pycsw supports the `Web Server Gateway Interface`_ (WSGI).  To run pycsw in
+WSGI mode, use ``pycsw/wsgi.py`` in your WSGI server environment.
+
+.. note::
+
+  ``mod_wsgi`` supports only the version of python it was compiled with. If the target server
+  already supports WSGI applications, pycsw will need to use the same python version.
+  `WSGIDaemonProcess`_ provides a ``python-path`` directive that may allow a virtualenv created from the python version ``mod_wsgi`` uses.
+
+Below is an example of configuring with Apache:
 
 .. code-block:: none
 
   WSGIDaemonProcess host1 home=/var/www/pycsw processes=2
   WSGIProcessGroup host1
-  WSGIScriptAlias /pycsw-wsgi /var/www/pycsw/csw.wsgi
+  WSGIScriptAlias /pycsw-wsgi /var/www/pycsw/wsgi.py
   <Directory /var/www/pycsw>
     Order deny,allow
     Allow from all
   </Directory>
 
+
 or use the `WSGI reference implementation`_:
 
 .. code-block:: bash
 
-  $ python ./csw.wsgi
+  $ python ./pycsw/wsgi.py
   Serving on port 8000...
 
 which will publish pycsw to ``http://localhost:8000/``
@@ -194,4 +206,5 @@ which will publish pycsw to ``http://localhost:8000/``
 .. _`easy_install`: http://packages.python.org/distribute/easy_install.html
 .. _`pip`: http://www.pip-installer.org
 .. _`Web Server Gateway Interface`: http://en.wikipedia.org/wiki/Web_Server_Gateway_Interface
+.. _`WSGIDaemonProcess`: https://code.google.com/p/modwsgi/wiki/ConfigurationDirectives#WSGIDaemonProcess
 .. _`WSGI reference implementation`: http://docs.python.org/library/wsgiref.html
diff --git a/docs/introduction.rst b/docs/introduction.rst
index 22cf968..b3681c8 100644
--- a/docs/introduction.rst
+++ b/docs/introduction.rst
@@ -17,12 +17,13 @@ Features
 - implements Full Text Search capabilities
 - implements OGC OpenSearch Geo and Time Extensions
 - implements Open Archives Initiative Protocol for Metadata Harvesting
-- supports ISO, Dublin Core, DIF, FGDC and Atom metadata models
+- supports ISO, Dublin Core, DIF, FGDC, Atom and GM03 metadata models
 - CGI or WSGI deployment
 - simple configuration
 - transactional capabilities (CSW-T)
 - flexible repository configuration
 - `GeoNode`_ connectivity
+- `HHypermap`_ connectivity
 - `Open Data Catalog`_ connectivity
 - `CKAN`_ connectivity
 - federated catalogue distributed searching
@@ -59,6 +60,8 @@ Standards Support
 +-------------------+------------+
 | `FGDC CSDGM`_     | 1998       | 
 +-------------------+------------+
+| `GM03`_           | 2.1        |
++-------------------+------------+
 | `SRU`_            | 1.1        | 
 +-------------------+------------+
 | `OGC OpenSearch`_ | 1.0        | 
@@ -103,6 +106,7 @@ Supported Output Schemas
 - FGDC CSDGM
 - NASA DIF
 - Atom
+- GM03
 
 Supported Sorting Functionality
 -------------------------------
@@ -188,7 +192,9 @@ Functions
 .. _`SRU`: http://www.loc.gov/standards/sru/
 .. _`OGC OpenSearch`: http://www.opengeospatial.org/standards/opensearchgeo
 .. _`GeoNode`: http://geonode.org/
+.. _`HHypermap`: https://github.com/cga-harvard/HHypermap
 .. _`Open Data Catalog`: https://github.com/azavea/Open-Data-Catalog/
 .. _`CKAN`: http://ckan.org/
 .. _`Compliant`: http://www.opengeospatial.org/resource/products/details/?pid=1325
 .. _`OAI-PMH`: http://www.openarchives.org/OAI/openarchivesprotocol.html
+.. _`GM03`: http://www.geocat.ch/internet/geocat/en/home/documentation/gm03.html
diff --git a/docs/json.rst b/docs/json.rst
new file mode 100644
index 0000000..a0e219b
--- /dev/null
+++ b/docs/json.rst
@@ -0,0 +1,7 @@
+.. _json:
+
+JSON Support
+============
+
+pycsw supports JSON support for ``DescribeRecord``, ``GetRecords`` and ``GetRecordById`` requests.  Adding ``outputFormat=application/json`` to your CSW request will return the response as a JSON representation.
+
diff --git a/docs/license.rst b/docs/license.rst
index eeb2337..1116f21 100644
--- a/docs/license.rst
+++ b/docs/license.rst
@@ -4,3 +4,10 @@ License
 =======
 
 .. include:: ../LICENSE.txt
+
+Documentation
+-------------
+
+The documentation is released under the `Creative Commons Attribution 4.0 International (CC BY 4.0)`_ license.
+
+.. _`Creative Commons Attribution 4.0 International (CC BY 4.0)`: http://creativecommons.org/licenses/by/4.0/
diff --git a/docs/outputschemas.rst b/docs/outputschemas.rst
index f364547..8e2fc9e 100644
--- a/docs/outputschemas.rst
+++ b/docs/outputschemas.rst
@@ -6,7 +6,7 @@ Output Schema Plugins
 Overview
 --------
 
-pycsw allows for extending the implementation of output schemas to the core standard.  outputschemas allow for a client to request metadata in a specific format (ISO, Dublin Core, FGDC, NASA DIF and Atom are default).
+pycsw allows for extending the implementation of output schemas to the core standard.  outputschemas allow for a client to request metadata in a specific format (ISO, Dublin Core, FGDC, NASA DIF Atom and GM03 are default).
 
 All outputschemas must be placed in the ``pycsw/plugins/outputschemas`` directory.
 
@@ -23,6 +23,7 @@ Requirements
        atom.py # default
        dif.py # default
        fgdc.py # default
+       gm03.py # default
 
 Implementing a new outputschema
 -------------------------------
diff --git a/docs/testing.rst b/docs/testing.rst
index c5c90d3..8729e8a 100644
--- a/docs/testing.rst
+++ b/docs/testing.rst
@@ -31,6 +31,8 @@ The tests framework can be run from ``tests`` using `Paver`_ (see ``pavement.py`
   $ paver test -s apiso,fgdc
   # run all tests, including harvesting (this is turned off by default given the volatility of remote services/data testing)
   $ paver test -r
+  # run all tests with 1000ms time benchmark
+  $ paver test -t 1000
 
 The tests perform HTTP GET and POST requests against ``http://localhost:8000``.  The expected output for each test can be found in ``expected``.  Results are categorized as ``passed``, ``failed``, or ``initialized``.  A summary of results is output at the end of the run.
 
diff --git a/docs/tools.rst b/docs/tools.rst
index c07ba1b..affb4e7 100644
--- a/docs/tools.rst
+++ b/docs/tools.rst
@@ -8,7 +8,7 @@ CSW Clients
 
 - `Geoportal CSW Clients <http://sourceforge.net/apps/mediawiki/geoportal/index.php?title=Geoportal_CSW_Clients>`_
 - `OWSLib <http://geopython.github.io/OWSLib>`_
-- `MetaSearch <http://geopython.github.io/MetaSearch>`_ (`QGIS <http://qgis.org/>`_ plugin)
+- `MetaSearch <https://hub.qgis.org/wiki/quantum-gis/MetaSearch>`_ (`QGIS <http://qgis.org/>`_ plugin)
 
 CSW Servers
 -----------
@@ -24,3 +24,4 @@ Metadata Editing Tools
 - `EUOSME <https://joinup.ec.europa.eu/software/euosme/description>`_
 - `GIMED <http://sourceforge.net/projects/gimed/>`_
 - `Metatools <http://hub.qgis.org/projects/metatools>`_ (`QGIS <http://qgis.org/>`_ plugin)
+- `QSphere <http://hub.qgis.org/plugins/qsphere>`_ (`QGIS <http://qgis.org/>`_ plugin)
diff --git a/docs/transactions.rst b/docs/transactions.rst
index ebc1bf0..1eb47da 100644
--- a/docs/transactions.rst
+++ b/docs/transactions.rst
@@ -15,10 +15,12 @@ For transactions and harvesting, pycsw supports the following metadata resource
 
   Dublin Core,``http://www.opengis.net/cat/csw/2.0.2``,yes,yes
   FGDC,``http://www.opengis.net/cat/csw/csdgm``,yes,yes
+  GM03,``http://www.interlis.ch/INTERLIS2.3``,yes,yes
   ISO 19139,``http://www.isotc211.org/2005/gmd``,yes,yes
   ISO GMI,``http://www.isotc211.org/2005/gmi``,yes,yes
   OGC:CSW 2.0.2,``http://www.opengis.net/cat/csw/2.0.2``,,yes
   OGC:WMS 1.1.1,``http://www.opengis.net/wms``,,yes
+  OGC:WMTS 1.0.0,``http://www.opengis.net/wmts/1.0``,,yes
   OGC:WFS 1.1.0,``http://www.opengis.net/wfs``,,yes
   OGC:WCS 1.0.0,``http://www.opengis.net/wcs``,,yes
   OGC:WPS 1.0.0,``http://www.opengis.net/wps/1.0.0``,,yes
diff --git a/etc/dist/opensuse/python-pycsw.spec b/etc/dist/opensuse/python-pycsw.spec
index 6056103..50fada2 100644
--- a/etc/dist/opensuse/python-pycsw.spec
+++ b/etc/dist/opensuse/python-pycsw.spec
@@ -1,7 +1,8 @@
+# =================================================================
 #
-# spec file for package python-pycsw (1.6.0)
+# Authors: Angelos Tzotsos <tzotsos at opensuse.org>
 #
-# Copyright (c) 2013 Angelos Tzotsos <tzotsos at opensuse.org>
+# Copyright (c) 2015 Angelos Tzotsos
 #
 # Permission is hereby granted, free of charge, to any person
 # obtaining a copy of this software and associated documentation
@@ -23,7 +24,8 @@
 # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 # OTHER DEALINGS IN THE SOFTWARE.
-
+#
+# =================================================================
 
 %define _webappconfdir /etc/apache2/conf.d/
 %define _htdocsdir /srv/www/htdocs/
@@ -87,7 +89,7 @@ mkdir -p %{buildroot}%{_sysconfdir}/apache2/conf.d
 #mv data %{buildroot}/srv/www/htdocs/pycsw/
 mv tests %{buildroot}/srv/www/htdocs/pycsw/
 mv csw.py %{buildroot}/srv/www/htdocs/pycsw/
-mv csw.wsgi %{buildroot}/srv/www/htdocs/pycsw/
+mv pycsw/wsgi.py %{buildroot}/srv/www/htdocs/pycsw/
 mv COMMITTERS.txt %{buildroot}/srv/www/htdocs/pycsw/
 mv default-sample.cfg %{buildroot}/srv/www/htdocs/pycsw/
 mv HISTORY.txt %{buildroot}/srv/www/htdocs/pycsw/
@@ -152,7 +154,7 @@ contact_role=pointOfContact
 
 [repository]
 # sqlite
-database=sqlite:////srv/www/htdocs/pycsw/tests/suites/cite/data/records.db
+database=sqlite:////srv/www/htdocs/pycsw/tests/suites/cite/data/cite.db
 # postgres
 #database=postgresql://username:password@localhost/pycsw
 # mysql
diff --git a/etc/mappings.py b/etc/mappings.py
index acf8826..cfb2a4d 100644
--- a/etc/mappings.py
+++ b/etc/mappings.py
@@ -1,9 +1,9 @@
-# -*- coding: ISO-8859-15 -*-
+# -*- coding: utf-8 -*-
 # =================================================================
 #
 # Authors: Tom Kralidis <tomkralidis at gmail.com>
 #
-# Copyright (c) 2012 Tom Kralidis
+# Copyright (c) 2015 Tom Kralidis
 #
 # Permission is hereby granted, free of charge, to any person
 # obtaining a copy of this software and associated documentation
diff --git a/pavement.py b/pavement.py
index 34e530b..1e10692 100644
--- a/pavement.py
+++ b/pavement.py
@@ -1,9 +1,9 @@
-# -*- coding: iso-8859-15 -*-
+# -*- coding: utf-8 -*-
 # =================================================================
 #
 # Authors: Tom Kralidis <tomkralidis at gmail.com>
 #
-# Copyright (c) 2012 Tom Kralidis
+# Copyright (c) 2015 Tom Kralidis
 #
 # Permission is hereby granted, free of charge, to any person
 # obtaining a copy of this software and associated documentation
@@ -28,13 +28,17 @@
 #
 # =================================================================
 
-from ConfigParser import SafeConfigParser
+from __future__ import (absolute_import, division, print_function)
+
 import glob
 import os
 import sys
 import time
+
+from six.moves import configparser
+
 from paver.easy import task, cmdopts, needs, \
-    pushd, sh, call_task, path, info
+    pushd, sh, call_task, path, info, BuildFailure
 
 DOCS = 'docs'
 STAGE_DIR = '/tmp'
@@ -74,9 +78,9 @@ def publish_docs(options):
         # change privs to be group writeable
         for root, dirs, files in os.walk(local_path):
             for dfile in files:
-                os.chmod(os.path.join(root, dfile), 0664)
+                os.chmod(os.path.join(root, dfile), 0o664)
             for ddir in dirs:
-                os.chmod(os.path.join(root, ddir), 0775)
+                os.chmod(os.path.join(root, ddir), 0o775)
 
         # copy documentation
         sh('scp -r %s%s* %s@%s:%s' % (local_path, os.sep, user, remote_host,
@@ -88,7 +92,7 @@ def gen_tests_html():
     """Generate tests/index.html for online testing"""
     with pushd('tests'):
         # ensure manager testsuite is writeable
-        os.chmod(os.path.join('suites', 'manager', 'data'), 0777)
+        os.chmod(os.path.join('suites', 'manager', 'data'), 0o777)
         sh('python gen_html.py > index.html')
 
 
@@ -154,13 +158,12 @@ def setup_testdata():
         'manager': False
     }
 
-    # remove CITE database so we can build fresh
     for suite in test_database_parameters.keys():
         dbfile = 'tests/suites/%s/data/records.db' % suite
         if os.path.isfile(dbfile):
             os.remove(dbfile)
 
-    for database, has_testdata in test_database_parameters.iteritems():
+    for database, has_testdata in test_database_parameters.items():
         info('Setting up test database %s' % database)
         cfg = path('tests/suites/%s/default.cfg' % database)
         sh('pycsw-admin.py -c setup_db -f %s' % cfg)
@@ -178,6 +181,7 @@ def setup_testdata():
     ('user=', 'U', 'database username'),
     ('pass=', 'p', 'database password'),
     ('remote', 'r', 'remote testing (harvesting)'),
+    ('time=', 't', 'time (milliseconds) in which requests should complete')
 ])
 def test(options):
     """Run unit tests"""
@@ -185,11 +189,13 @@ def test(options):
     db_setup = False
     db_conn = None
     cfg_files = []
+    status = 0
 
     url = options.get('url', None)
     suites = options.get('suites', None)
     database = options.get('database', 'SQLite3')
     remote = options.get('remote')
+    timems = options.get('time', None)
 
     if url is None:
         # run against default server
@@ -208,6 +214,9 @@ def test(options):
     if remote:
         cmd = '%s -r' % cmd
 
+    if timems:
+        cmd = '%s -t %s' % (cmd, timems)
+
     # configure/setup database if not default
     if database != 'SQLite3':
         db_setup = True
@@ -249,7 +258,7 @@ def test(options):
                 elif suite == 'apiso':
                     tablename = 'records_apiso'
 
-                config = SafeConfigParser()
+                config = configparser.SafeConfigParser()
                 with open(cfg) as read_data:
                     config.readfp(read_data)
                 config.set('repository', 'database', db_conn)
@@ -269,7 +278,12 @@ def test(options):
             raise Exception('Invalid database specified')
 
     with pushd('tests'):
-        sh(cmd)
+        try:
+            sh(cmd)
+        except BuildFailure as err:
+            status = 1
+        # stop pycsw instance
+        call_task('stop')
 
     if db_setup:  # tearDown
         for cfg in cfg_files:
@@ -279,11 +293,13 @@ def test(options):
             sh('dropdb %s -U %s' % (temp_db, user))
             sh('unset PGPASSWORD')
 
+    sys.exit(status)
+
 
 @task
 def start(options):
     """Start local WSGI server instance"""
-    sh('python csw.wsgi 8000 &')
+    sh('python pycsw/wsgi.py 8000 &')
     time.sleep(10)
 
 
@@ -291,7 +307,7 @@ def start(options):
 def stop():
     """Stop local WSGI server instance"""
 
-    kill_process('python', 'csw.wsgi')
+    kill_process('python', 'pycsw/wsgi.py')
 
 
 @task
@@ -300,7 +316,6 @@ def stop():
 ])
 def reset(options):
     """Return codebase to pristine state"""
-    sh('git checkout tests/suites/cite/data/records.db')
 
     force = options.get('force')
     if force:
@@ -315,7 +330,7 @@ def kill_process(procname, scriptname):
     p = subprocess.Popen(['ps', 'aux'], stdout=subprocess.PIPE)
     out, err = p.communicate()
 
-    for line in out.splitlines():
+    for line in out.decode().splitlines():
         if procname in line and scriptname in line:
             pid = int(line.split()[1])
             info('Stopping %s %s %d' % (procname, scriptname, pid))
diff --git a/pycsw/__init__.py b/pycsw/__init__.py
index d0b66b7..f880e71 100644
--- a/pycsw/__init__.py
+++ b/pycsw/__init__.py
@@ -1,9 +1,9 @@
-# -*- coding: ISO-8859-15 -*-
+# -*- coding: utf-8 -*-
 # =================================================================
 #
 # Authors: Tom Kralidis <tomkralidis at gmail.com>
 #
-# Copyright (c) 2010 Tom Kralidis
+# Copyright (c) 2015 Tom Kralidis
 #
 # Permission is hereby granted, free of charge, to any person
 # obtaining a copy of this software and associated documentation
@@ -28,4 +28,4 @@
 #
 # =================================================================
 
-__version__ = '1.10.4'
+__version__ = '2.0.0-alpha1'
diff --git a/pycsw/config.py b/pycsw/config.py
deleted file mode 100644
index 0300b6c..0000000
--- a/pycsw/config.py
+++ /dev/null
@@ -1,339 +0,0 @@
-# -*- coding: iso-8859-15 -*-
-# =================================================================
-#
-# Authors: Tom Kralidis <tomkralidis at gmail.com>
-#
-# Copyright (c) 2011 Tom Kralidis
-#
-# Permission is hereby granted, free of charge, to any person
-# obtaining a copy of this software and associated documentation
-# files (the "Software"), to deal in the Software without
-# restriction, including without limitation the rights to use,
-# copy, modify, merge, publish, distribute, sublicense, and/or sell
-# copies of the Software, and to permit persons to whom the
-# Software is furnished to do so, subject to the following
-# conditions:
-#
-# The above copyright notice and this permission notice shall be
-# included in all copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
-# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
-# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
-# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-# OTHER DEALINGS IN THE SOFTWARE.
-#
-# =================================================================
-
-import logging
-from lxml import etree
-from pycsw import __version__
-
-LOGGER = logging.getLogger(__name__)
-
-
-class StaticContext(object):
-    """core configuration"""
-    def __init__(self):
-        """initializer"""
-
-        LOGGER.debug('Initializing static context')
-        self.version = __version__
-
-        self.ogc_schemas_base = 'http://schemas.opengis.net'
-
-        self.parser = etree.XMLParser(resolve_entities=False)
-
-        self.languages = {
-            'en': 'english',
-            'fr': 'french',
-            'el': 'greek',
-        }
-
-        self.namespaces = {
-            'atom': 'http://www.w3.org/2005/Atom',
-            'csw': 'http://www.opengis.net/cat/csw/2.0.2',
-            'dc': 'http://purl.org/dc/elements/1.1/',
-            'dct': 'http://purl.org/dc/terms/',
-            'dif': 'http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/',
-            'fgdc': 'http://www.opengis.net/cat/csw/csdgm',
-            'gmd': 'http://www.isotc211.org/2005/gmd',
-            'gml': 'http://www.opengis.net/gml',
-            'ogc': 'http://www.opengis.net/ogc',
-            'os': 'http://a9.com/-/spec/opensearch/1.1/',
-            'ows': 'http://www.opengis.net/ows',
-            'rdf': 'http://www.w3.org/1999/02/22-rdf-syntax-ns#',
-            'sitemap': 'http://www.sitemaps.org/schemas/sitemap/0.9',
-            'soapenv': 'http://www.w3.org/2003/05/soap-envelope',
-            'xlink': 'http://www.w3.org/1999/xlink',
-            'xs': 'http://www.w3.org/2001/XMLSchema',
-            'xsi': 'http://www.w3.org/2001/XMLSchema-instance'
-        }
-
-        self.md_core_model = {
-            'typename': 'pycsw:CoreMetadata',
-            'outputschema': 'http://pycsw.org/metadata',
-            'mappings': {
-                'pycsw:Identifier': 'identifier',
-                # CSW typename (e.g. csw:Record, md:MD_Metadata)
-                'pycsw:Typename': 'typename',
-                # schema namespace, i.e. http://www.isotc211.org/2005/gmd
-                'pycsw:Schema': 'schema',
-                # origin of resource, either 'local', or URL to web service
-                'pycsw:MdSource': 'mdsource',
-                # date of insertion
-                'pycsw:InsertDate': 'insert_date',  # date of insertion
-                # raw XML metadata
-                'pycsw:XML': 'xml',
-                # bag of metadata element and attributes ONLY, no XML tages
-                'pycsw:AnyText': 'anytext',
-                'pycsw:Language': 'language',
-                'pycsw:Title': 'title',
-                'pycsw:Abstract': 'abstract',
-                'pycsw:Keywords': 'keywords',
-                'pycsw:KeywordType': 'keywordstype',
-                'pycsw:Format': 'format',
-                'pycsw:Source': 'source',
-                'pycsw:Date': 'date',
-                'pycsw:Modified': 'date_modified',
-                'pycsw:Type': 'type',
-                # geometry, specified in OGC WKT
-                'pycsw:BoundingBox': 'wkt_geometry',
-                'pycsw:CRS': 'crs',
-                'pycsw:AlternateTitle': 'title_alternate',
-                'pycsw:RevisionDate': 'date_revision',
-                'pycsw:CreationDate': 'date_creation',
-                'pycsw:PublicationDate': 'date_publication',
-                'pycsw:OrganizationName': 'organization',
-                'pycsw:SecurityConstraints': 'securityconstraints',
-                'pycsw:ParentIdentifier': 'parentidentifier',
-                'pycsw:TopicCategory': 'topicategory',
-                'pycsw:ResourceLanguage': 'resourcelanguage',
-                'pycsw:GeographicDescriptionCode': 'geodescode',
-                'pycsw:Denominator': 'denominator',
-                'pycsw:DistanceValue': 'distancevalue',
-                'pycsw:DistanceUOM': 'distanceuom',
-                'pycsw:TempExtent_begin': 'time_begin',
-                'pycsw:TempExtent_end': 'time_end',
-                'pycsw:ServiceType': 'servicetype',
-                'pycsw:ServiceTypeVersion': 'servicetypeversion',
-                'pycsw:Operation': 'operation',
-                'pycsw:CouplingType': 'couplingtype',
-                'pycsw:OperatesOn': 'operateson',
-                'pycsw:OperatesOnIdentifier': 'operatesonidentifier',
-                'pycsw:OperatesOnName': 'operatesoname',
-                'pycsw:Degree': 'degree',
-                'pycsw:AccessConstraints': 'accessconstraints',
-                'pycsw:OtherConstraints': 'otherconstraints',
-                'pycsw:Classification': 'classification',
-                'pycsw:ConditionApplyingToAccessAndUse': 'conditionapplyingtoaccessanduse',
-                'pycsw:Lineage': 'lineage',
-                'pycsw:ResponsiblePartyRole': 'responsiblepartyrole',
-                'pycsw:SpecificationTitle': 'specificationtitle',
-                'pycsw:SpecificationDate': 'specificationdate',
-                'pycsw:SpecificationDateType': 'specificationdatetype',
-                'pycsw:Creator': 'creator',
-                'pycsw:Publisher': 'publisher',
-                'pycsw:Contributor': 'contributor',
-                'pycsw:Relation': 'relation',
-                # links: format "name,description,protocol,url[^,,,[^,,,]]"
-                'pycsw:Links': 'links',
-            }
-        }
-
-        self.model = {
-            'operations': {
-                'GetCapabilities': {
-                    'methods': {
-                        'get': True,
-                        'post': True,
-                    },
-                    'parameters': {
-                        'sections': {
-                            'values': ['ServiceIdentification', 'ServiceProvider',
-                            'OperationsMetadata', 'Filter_Capabilities']
-                        }
-                    }
-                },
-                'DescribeRecord': {
-                    'methods': {
-                        'get': True,
-                        'post': True,
-                    },
-                    'parameters': {
-                        'schemaLanguage': {
-                            'values': ['http://www.w3.org/XML/Schema',
-                                       'http://www.w3.org/TR/xmlschema-1/',
-                                       'http://www.w3.org/2001/XMLSchema']
-                        },
-                        'typeName': {
-                            'values': ['csw:Record']
-                        },
-                        'outputFormat': {
-                            'values': ['application/xml', 'application/json']
-                        }
-                    }
-                },
-                'GetRecords': {
-                    'methods': {
-                        'get': True,
-                        'post': True,
-                    },
-                    'parameters': {
-                        'resultType': {
-                            'values': ['hits', 'results', 'validate']
-                        },
-                        'typeNames': {
-                            'values': ['csw:Record']
-                        },
-                        'outputSchema': {
-                            'values': ['http://www.opengis.net/cat/csw/2.0.2']
-                        },
-                        'outputFormat': {
-                            'values': ['application/xml', 'application/json']
-                        },
-                        'CONSTRAINTLANGUAGE': {
-                            'values': ['FILTER', 'CQL_TEXT']
-                        },
-                        'ElementSetName': {
-                            'values': ['brief', 'summary', 'full']
-                        }
-                    },
-                    'constraints': {
-                    }
-                },
-                'GetRecordById': {
-                    'methods': {
-                        'get': True,
-                        'post': True,
-                    },
-                    'parameters': {
-                        'outputSchema': {
-                            'values': ['http://www.opengis.net/cat/csw/2.0.2']
-                        },
-                        'outputFormat': {
-                            'values': ['application/xml', 'application/json']
-                        },
-                        'ElementSetName': {
-                            'values': ['brief', 'summary', 'full']
-                        }
-                    }
-                },
-                'GetRepositoryItem': {
-                    'methods': {
-                        'get': True,
-                        'post': False,
-                    },
-                    'parameters': {
-                    }
-                }
-            },
-            'parameters': {
-                'version': {
-                    'values': ['2.0.2']
-                },
-                'service': {
-                    'values': ['CSW']
-                }
-            },
-            'constraints': {
-                'MaxRecordDefault': {
-                    'values': ['10']
-                },
-                'PostEncoding': {
-                    'values': ['XML', 'SOAP']
-                },
-                'XPathQueryables': {
-                    'values': ['allowed']
-                }
-            },
-            'typenames': {
-                'csw:Record': {
-                    'outputschema': 'http://www.opengis.net/cat/csw/2.0.2',
-                    'queryables': {
-                        'SupportedDublinCoreQueryables': {
-                            # map Dublin Core queryables to core metadata model
-                            'dc:title':
-                            {'dbcol': self.md_core_model['mappings']['pycsw:Title']},
-                            'dc:creator':
-                            {'dbcol': self.md_core_model['mappings']['pycsw:Creator']},
-                            'dc:subject':
-                            {'dbcol': self.md_core_model['mappings']['pycsw:Keywords']},
-                            'dct:abstract':
-                            {'dbcol': self.md_core_model['mappings']['pycsw:Abstract']},
-                            'dc:publisher':
-                            {'dbcol': self.md_core_model['mappings']['pycsw:Publisher']},
-                            'dc:contributor':
-                            {'dbcol': self.md_core_model['mappings']['pycsw:Contributor']},
-                            'dct:modified':
-                            {'dbcol': self.md_core_model['mappings']['pycsw:Modified']},
-                            'dc:date':
-                            {'dbcol': self.md_core_model['mappings']['pycsw:Date']},
-                            'dc:type':
-                            {'dbcol': self.md_core_model['mappings']['pycsw:Type']},
-                            'dc:format':
-                            {'dbcol': self.md_core_model['mappings']['pycsw:Format']},
-                            'dc:identifier':
-                            {'dbcol': self.md_core_model['mappings']['pycsw:Identifier']},
-                            'dc:source':
-                            {'dbcol': self.md_core_model['mappings']['pycsw:Source']},
-                            'dc:language':
-                            {'dbcol': self.md_core_model['mappings']['pycsw:Language']},
-                            'dc:relation':
-                            {'dbcol': self.md_core_model['mappings']['pycsw:Relation']},
-                            'dc:rights':
-                            {'dbcol':
-                             self.md_core_model['mappings']['pycsw:AccessConstraints']},
-                            # bbox and full text map to internal fixed columns
-                            'ows:BoundingBox':
-                            {'dbcol': self.md_core_model['mappings']['pycsw:BoundingBox']},
-                            'csw:AnyText':
-                            {'dbcol': self.md_core_model['mappings']['pycsw:AnyText']},
-                        }
-                    }
-                }
-            }
-        }
-
-    def gen_domains(self):
-        """Generate parameter domain model"""
-        domain = {}
-        domain['methods'] = {'get': True, 'post': True}
-        domain['parameters'] = {'ParameterName': {'values': []}}
-        for operation in self.model['operations'].keys():
-            for parameter in self.model['operations'][operation]['parameters']:
-                domain['parameters']['ParameterName']['values'].append('%s.%s' %
-                                                        (operation, parameter))
-        return domain
-
-    def refresh_dc(self, mappings):
-        """Refresh Dublin Core mappings"""
-
-        LOGGER.debug('refreshing Dublin Core mappings with %s' % str(mappings))
-
-        defaults = {
-            'dc:title': 'pycsw:Title',
-            'dc:creator': 'pycsw:Creator',
-            'dc:subject': 'pycsw:Keywords',
-            'dct:abstract': 'pycsw:Abstract',
-            'dc:publisher': 'pycsw:Publisher',
-            'dc:contributor': 'pycsw:Contributor',
-            'dct:modified': 'pycsw:Modified',
-            'dc:date': 'pycsw:Date',
-            'dc:type': 'pycsw:Type',
-            'dc:format': 'pycsw:Format',
-            'dc:identifier': 'pycsw:Identifier',
-            'dc:source': 'pycsw:Source',
-            'dc:language': 'pycsw:Language',
-            'dc:relation': 'pycsw:Relation',
-            'dc:rights': 'pycsw:AccessConstraints',
-            'ows:BoundingBox': 'pycsw:BoundingBox',
-            'csw:AnyText': 'pycsw:AnyText',
-        }
-
-        for k, val in defaults.iteritems():
-            self.model['typenames']['csw:Record']['queryables']['SupportedDublinCoreQueryables'][k] = \
-                {'dbcol': mappings['mappings'][val]}
diff --git a/pycsw/plugins/profiles/__init__.py b/pycsw/core/__init__.py
similarity index 95%
copy from pycsw/plugins/profiles/__init__.py
copy to pycsw/core/__init__.py
index f98f82b..08a4c3d 100644
--- a/pycsw/plugins/profiles/__init__.py
+++ b/pycsw/core/__init__.py
@@ -1,9 +1,9 @@
-# -*- coding: ISO-8859-15 -*-
+# -*- coding: utf-8 -*-
 # =================================================================
 #
 # Authors: Tom Kralidis <tomkralidis at gmail.com>
 #
-# Copyright (c) 2011 Tom Kralidis
+# Copyright (c) 2015 Tom Kralidis
 #
 # Permission is hereby granted, free of charge, to any person
 # obtaining a copy of this software and associated documentation
diff --git a/pycsw/admin.py b/pycsw/core/admin.py
similarity index 95%
rename from pycsw/admin.py
rename to pycsw/core/admin.py
index c3422cd..e4aecc7 100644
--- a/pycsw/admin.py
+++ b/pycsw/core/admin.py
@@ -1,11 +1,11 @@
-# -*- coding: ISO-8859-15 -*-
+# -*- coding: utf-8 -*-
 # =================================================================
 #
 # Authors: Tom Kralidis <tomkralidis at gmail.com>
 #          Angelos Tzotsos <tzotsos at gmail.com>
 #
-# Copyright (c) 2012 Tom Kralidis
-# Copyright (c) 2014 Angelos Tzotsos
+# Copyright (c) 2015 Tom Kralidis
+# Copyright (c) 2015 Angelos Tzotsos
 #
 # Permission is hereby granted, free of charge, to any person
 # obtaining a copy of this software and associated documentation
@@ -35,12 +35,13 @@ import os
 import sys
 from glob import glob
 
-from lxml import etree
-from pycsw import metadata, repository, util
+from pycsw.core import metadata, repository, util
+from pycsw.core.etree import etree
 
 LOGGER = logging.getLogger(__name__)
 
 
+
 def setup_db(database, table, home, create_sfsql_tables=True, create_plpythonu_functions=True, postgis_geometry_column='wkb_geometry', extra_columns=[], language='english'):
     """Setup database tables and indexes"""
     from sqlalchemy import Column, create_engine, Integer, MetaData, \
@@ -72,7 +73,7 @@ def setup_db(database, table, home, create_sfsql_tables=True, create_plpythonu_f
             LOGGER.info('PostGIS %s detected: Skipping SFSQL tables creation' % postgis_lib_version)
         except:
             pass
-    
+
     if create_sfsql_tables:
         LOGGER.info('Creating table spatial_ref_sys')
         srs = Table(
@@ -83,10 +84,10 @@ def setup_db(database, table, home, create_sfsql_tables=True, create_plpythonu_f
             Column('srtext', Text)
         )
         srs.create()
-    
+
         i = srs.insert()
         i.execute(srid=4326, auth_name='EPSG', auth_srid=4326, srtext='GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.01745329251994328,AUTHORITY["EPSG","9122"]],AUTHORITY["EPSG","4326"]]')
-    
+
         LOGGER.info('Creating table geometry_columns')
         geom = Table(
             'geometry_columns', mdata,
@@ -100,7 +101,7 @@ def setup_db(database, table, home, create_sfsql_tables=True, create_plpythonu_f
             Column('geometry_format', Text, nullable=False),
         )
         geom.create()
-    
+
         i = geom.insert()
         i.execute(f_table_catalog='public', f_table_schema='public',
                   f_table_name=table, f_geometry_column='wkt_geometry',
@@ -258,7 +259,7 @@ def setup_db(database, table, home, create_sfsql_tables=True, create_plpythonu_f
             from pycsw import util
             return util.get_spatial_overlay_rank(target_geom, query_geom)
             $$ LANGUAGE plpythonu;
-        ''' % pycsw_home 
+        ''' % pycsw_home
             conn.execute(function_get_anytext)
             conn.execute(function_query_spatial)
             conn.execute(function_update_xpath)
@@ -267,13 +268,13 @@ def setup_db(database, table, home, create_sfsql_tables=True, create_plpythonu_f
 
     if dbase.name == 'postgresql':
         LOGGER.info('Creating PostgreSQL Free Text Search (FTS) GIN index')
-	tsvector_fts = "alter table %s add column anytext_tsvector tsvector" % table
-	conn.execute(tsvector_fts)
+        tsvector_fts = "alter table %s add column anytext_tsvector tsvector" % table
+        conn.execute(tsvector_fts)
         index_fts = "create index fts_gin_idx on %s using gin(anytext_tsvector)" % table
         conn.execute(index_fts)
-	# This needs to run if records exist "UPDATE records SET anytext_tsvector = to_tsvector('english', anytext)"
-	trigger_fts = "create trigger ftsupdate before insert or update on %s for each row execute procedure tsvector_update_trigger('anytext_tsvector', 'pg_catalog.%s', 'anytext')" % (table, language)
-	conn.execute(trigger_fts)
+        # This needs to run if records exist "UPDATE records SET anytext_tsvector = to_tsvector('english', anytext)"
+        trigger_fts = "create trigger ftsupdate before insert or update on %s for each row execute procedure tsvector_update_trigger('anytext_tsvector', 'pg_catalog.%s', 'anytext')" % (table, language)
+        conn.execute(trigger_fts)
 
     if dbase.name == 'postgresql' and create_postgis_geometry:
         # create native geometry column within db
@@ -312,7 +313,9 @@ def load_records(context, database, table, xml_dirpath, recursive=False, force_u
 
     file_list = []
 
-    if recursive:
+    if os.path.isfile(xml_dirpath):
+        file_list.append(xml_dirpath)
+    elif recursive:
         for root, dirs, files in os.walk(xml_dirpath):
             for mfile in files:
                 if mfile.endswith('.xml'):
@@ -495,7 +498,8 @@ def post_xml(url, xml, timeout=30):
 
     from owslib.util import http_post
     try:
-        return http_post(url=url, request=open(xml).read(), timeout=timeout)
+        with open(xml) as f:
+            return http_post(url=url, request=f.read(), timeout=timeout)
     except Exception as err:
         raise RuntimeError(err)
 
@@ -569,6 +573,6 @@ def delete_records(context, database, table):
     """Deletes all records from repository"""
 
     LOGGER.info('Deleting all records')
-    
+
     repo = repository.Repository(database, context, table=table)
     repo.delete(constraint={'where': '', 'values': []})
diff --git a/pycsw/core/config.py b/pycsw/core/config.py
new file mode 100644
index 0000000..5207a9a
--- /dev/null
+++ b/pycsw/core/config.py
@@ -0,0 +1,593 @@
+# -*- coding: utf-8 -*-
+# =================================================================
+#
+# Authors: Tom Kralidis <tomkralidis at gmail.com>
+#
+# Copyright (c) 2016 Tom Kralidis
+#
+# Permission is hereby granted, free of charge, to any person
+# obtaining a copy of this software and associated documentation
+# files (the "Software"), to deal in the Software without
+# restriction, including without limitation the rights to use,
+# copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the
+# Software is furnished to do so, subject to the following
+# conditions:
+#
+# The above copyright notice and this permission notice shall be
+# included in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+# OTHER DEALINGS IN THE SOFTWARE.
+#
+# =================================================================
+
+import logging
+from pycsw.core.etree import etree
+from pycsw import __version__
+
+LOGGER = logging.getLogger(__name__)
+
+
+class StaticContext(object):
+    """core configuration"""
+    def __init__(self, prefix='csw30'):
+        """initializer"""
+
+        LOGGER.debug('Initializing static context')
+        self.version = __version__
+
+        self.ogc_schemas_base = 'http://schemas.opengis.net'
+
+        self.parser = etree.XMLParser(resolve_entities=False)
+
+        self.languages = {
+            'en': 'english',
+            'fr': 'french',
+            'el': 'greek',
+        }
+
+        self.response_codes = {
+            'OK': '200 OK',
+            'NotFound': '404 Not Found',
+            'InvalidValue': '400 Invalid property value',
+            'OperationParsingFailed': '400 Bad Request',
+            'OperationProcessingFailed': '403 Server Processing Failed',
+            'OperationNotSupported': '400 Not Implemented',
+            'MissingParameterValue': '400 Bad Request',
+            'InvalidParameterValue': '400 Bad Request',
+            'VersionNegotiationFailed': '400 Bad Request',
+            'InvalidUpdateSequence': '400 Bad Request',
+            'OptionNotSupported': '400 Not Implemented',
+            'NoApplicableCode': '400 Internal Server Error'
+        }
+
+        self.namespaces = {
+            'atom': 'http://www.w3.org/2005/Atom',
+            'csw': 'http://www.opengis.net/cat/csw/2.0.2',
+            'csw30': 'http://www.opengis.net/cat/csw/3.0',
+            'dc': 'http://purl.org/dc/elements/1.1/',
+            'dct': 'http://purl.org/dc/terms/',
+            'dif': 'http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/',
+            'fes20': 'http://www.opengis.net/fes/2.0',
+            'fgdc': 'http://www.opengis.net/cat/csw/csdgm',
+            'gm03': 'http://www.interlis.ch/INTERLIS2.3',
+            'gmd': 'http://www.isotc211.org/2005/gmd',
+            'gml': 'http://www.opengis.net/gml',
+            'ogc': 'http://www.opengis.net/ogc',
+            'os': 'http://a9.com/-/spec/opensearch/1.1/',
+            'ows': 'http://www.opengis.net/ows',
+            'ows11': 'http://www.opengis.net/ows/1.1',
+            'ows20': 'http://www.opengis.net/ows/2.0',
+            'rdf': 'http://www.w3.org/1999/02/22-rdf-syntax-ns#',
+            'sitemap': 'http://www.sitemaps.org/schemas/sitemap/0.9',
+            'soapenv': 'http://www.w3.org/2003/05/soap-envelope',
+            'xlink': 'http://www.w3.org/1999/xlink',
+            'xs': 'http://www.w3.org/2001/XMLSchema',
+            'xsi': 'http://www.w3.org/2001/XMLSchema-instance'
+        }
+
+        self.keep_ns_prefixes = [
+            'csw', 'dc', 'dct', 'gmd', 'gml', 'ows', 'xs'
+        ]
+
+        self.md_core_model = {
+            'typename': 'pycsw:CoreMetadata',
+            'outputschema': 'http://pycsw.org/metadata',
+            'mappings': {
+                'pycsw:Identifier': 'identifier',
+                # CSW typename (e.g. csw:Record, md:MD_Metadata)
+                'pycsw:Typename': 'typename',
+                # schema namespace, i.e. http://www.isotc211.org/2005/gmd
+                'pycsw:Schema': 'schema',
+                # origin of resource, either 'local', or URL to web service
+                'pycsw:MdSource': 'mdsource',
+                # date of insertion
+                'pycsw:InsertDate': 'insert_date',  # date of insertion
+                # raw XML metadata
+                'pycsw:XML': 'xml',
+                # bag of metadata element and attributes ONLY, no XML tages
+                'pycsw:AnyText': 'anytext',
+                'pycsw:Language': 'language',
+                'pycsw:Title': 'title',
+                'pycsw:Abstract': 'abstract',
+                'pycsw:Keywords': 'keywords',
+                'pycsw:KeywordType': 'keywordstype',
+                'pycsw:Format': 'format',
+                'pycsw:Source': 'source',
+                'pycsw:Date': 'date',
+                'pycsw:Modified': 'date_modified',
+                'pycsw:Type': 'type',
+                # geometry, specified in OGC WKT
+                'pycsw:BoundingBox': 'wkt_geometry',
+                'pycsw:CRS': 'crs',
+                'pycsw:AlternateTitle': 'title_alternate',
+                'pycsw:RevisionDate': 'date_revision',
+                'pycsw:CreationDate': 'date_creation',
+                'pycsw:PublicationDate': 'date_publication',
+                'pycsw:OrganizationName': 'organization',
+                'pycsw:SecurityConstraints': 'securityconstraints',
+                'pycsw:ParentIdentifier': 'parentidentifier',
+                'pycsw:TopicCategory': 'topicategory',
+                'pycsw:ResourceLanguage': 'resourcelanguage',
+                'pycsw:GeographicDescriptionCode': 'geodescode',
+                'pycsw:Denominator': 'denominator',
+                'pycsw:DistanceValue': 'distancevalue',
+                'pycsw:DistanceUOM': 'distanceuom',
+                'pycsw:TempExtent_begin': 'time_begin',
+                'pycsw:TempExtent_end': 'time_end',
+                'pycsw:ServiceType': 'servicetype',
+                'pycsw:ServiceTypeVersion': 'servicetypeversion',
+                'pycsw:Operation': 'operation',
+                'pycsw:CouplingType': 'couplingtype',
+                'pycsw:OperatesOn': 'operateson',
+                'pycsw:OperatesOnIdentifier': 'operatesonidentifier',
+                'pycsw:OperatesOnName': 'operatesoname',
+                'pycsw:Degree': 'degree',
+                'pycsw:AccessConstraints': 'accessconstraints',
+                'pycsw:OtherConstraints': 'otherconstraints',
+                'pycsw:Classification': 'classification',
+                'pycsw:ConditionApplyingToAccessAndUse': 'conditionapplyingtoaccessanduse',
+                'pycsw:Lineage': 'lineage',
+                'pycsw:ResponsiblePartyRole': 'responsiblepartyrole',
+                'pycsw:SpecificationTitle': 'specificationtitle',
+                'pycsw:SpecificationDate': 'specificationdate',
+                'pycsw:SpecificationDateType': 'specificationdatetype',
+                'pycsw:Creator': 'creator',
+                'pycsw:Publisher': 'publisher',
+                'pycsw:Contributor': 'contributor',
+                'pycsw:Relation': 'relation',
+                # links: format "name,description,protocol,url[^,,,[^,,,]]"
+                'pycsw:Links': 'links',
+            }
+        }
+
+        self.model = None
+
+        self.models = {
+            'csw': {
+                'operations_order': [
+                    'GetCapabilities', 'DescribeRecord', 'GetDomain',
+                    'GetRecords', 'GetRecordById', 'GetRepositoryItem'
+                ],
+                'operations': {
+                    'GetCapabilities': {
+                        'methods': {
+                            'get': True,
+                            'post': True,
+                        },
+                        'parameters': {
+                            'sections': {
+                                'values': ['ServiceIdentification', 'ServiceProvider',
+                                'OperationsMetadata', 'Filter_Capabilities']
+                            }
+                        }
+                    },
+                    'DescribeRecord': {
+                        'methods': {
+                            'get': True,
+                            'post': True,
+                        },
+                        'parameters': {
+                            'schemaLanguage': {
+                                'values': ['http://www.w3.org/XML/Schema',
+                                           'http://www.w3.org/TR/xmlschema-1/',
+                                           'http://www.w3.org/2001/XMLSchema']
+                            },
+                            'typeName': {
+                                'values': ['csw:Record']
+                            },
+                            'outputFormat': {
+                                'values': ['application/xml', 'application/json']
+                            }
+                        }
+                    },
+                    'GetRecords': {
+                        'methods': {
+                            'get': True,
+                            'post': True,
+                        },
+                        'parameters': {
+                            'resultType': {
+                                'values': ['hits', 'results', 'validate']
+                            },
+                            'typeNames': {
+                                'values': ['csw:Record']
+                            },
+                            'outputSchema': {
+                                'values': ['http://www.opengis.net/cat/csw/2.0.2']
+                            },
+                            'outputFormat': {
+                                'values': ['application/xml', 'application/json']
+                            },
+                            'CONSTRAINTLANGUAGE': {
+                                'values': ['FILTER', 'CQL_TEXT']
+                            },
+                            'ElementSetName': {
+                                'values': ['brief', 'summary', 'full']
+                            }
+                        },
+                        'constraints': {
+                        }
+                    },
+                    'GetRecordById': {
+                        'methods': {
+                            'get': True,
+                            'post': True,
+                        },
+                        'parameters': {
+                            'outputSchema': {
+                                'values': ['http://www.opengis.net/cat/csw/2.0.2']
+                            },
+                            'outputFormat': {
+                                'values': ['application/xml', 'application/json']
+                            },
+                            'ElementSetName': {
+                                'values': ['brief', 'summary', 'full']
+                            }
+                        }
+                    },
+                    'GetRepositoryItem': {
+                        'methods': {
+                            'get': True,
+                            'post': False,
+                        },
+                        'parameters': {
+                        }
+                    }
+                },
+                'parameters': {
+                    'version': {
+                        'values': ['2.0.2', '3.0.0']
+                    },
+                    'service': {
+                        'values': ['CSW']
+                    }
+                },
+                'constraints': {
+                    'MaxRecordDefault': {
+                        'values': ['10']
+                    },
+                    'PostEncoding': {
+                        'values': ['XML', 'SOAP']
+                    },
+                    'XPathQueryables': {
+                        'values': ['allowed']
+                    }
+                },
+                'typenames': {
+                    'csw:Record': {
+                        'outputschema': 'http://www.opengis.net/cat/csw/2.0.2',
+                        'queryables': {
+                            'SupportedDublinCoreQueryables': {
+                                # map Dublin Core queryables to core metadata model
+                                'dc:title':
+                                {'dbcol': self.md_core_model['mappings']['pycsw:Title']},
+                                'dc:creator':
+                                {'dbcol': self.md_core_model['mappings']['pycsw:Creator']},
+                                'dc:subject':
+                                {'dbcol': self.md_core_model['mappings']['pycsw:Keywords']},
+                                'dct:abstract':
+                                {'dbcol': self.md_core_model['mappings']['pycsw:Abstract']},
+                                'dc:publisher':
+                                {'dbcol': self.md_core_model['mappings']['pycsw:Publisher']},
+                                'dc:contributor':
+                                {'dbcol': self.md_core_model['mappings']['pycsw:Contributor']},
+                                'dct:modified':
+                                {'dbcol': self.md_core_model['mappings']['pycsw:Modified']},
+                                'dc:date':
+                                {'dbcol': self.md_core_model['mappings']['pycsw:Date']},
+                                'dc:type':
+                                {'dbcol': self.md_core_model['mappings']['pycsw:Type']},
+                                'dc:format':
+                                {'dbcol': self.md_core_model['mappings']['pycsw:Format']},
+                                'dc:identifier':
+                                {'dbcol': self.md_core_model['mappings']['pycsw:Identifier']},
+                                'dc:source':
+                                {'dbcol': self.md_core_model['mappings']['pycsw:Source']},
+                                'dc:language':
+                                {'dbcol': self.md_core_model['mappings']['pycsw:Language']},
+                                'dc:relation':
+                                {'dbcol': self.md_core_model['mappings']['pycsw:Relation']},
+                                'dc:rights':
+                                {'dbcol':
+                                 self.md_core_model['mappings']['pycsw:AccessConstraints']},
+                                # bbox and full text map to internal fixed columns
+                                'ows:BoundingBox':
+                                {'dbcol': self.md_core_model['mappings']['pycsw:BoundingBox']},
+                                'csw:AnyText':
+                                {'dbcol': self.md_core_model['mappings']['pycsw:AnyText']},
+                            }
+                        }
+                    }
+                }
+            },
+            'csw30': {
+                'operations_order': [
+                    'GetCapabilities', 'GetDomain', 'GetRecords',
+                    'GetRecordById', 'GetRepositoryItem'
+                ],
+                'operations': {
+                    'GetCapabilities': {
+                        'methods': {
+                            'get': True,
+                            'post': True,
+                        },
+                        'parameters': {
+                            'acceptVersions': {
+                                'values': ['2.0.2', '3.0.0']
+                            },
+                            'acceptFormats': {
+                                'values': ['text/xml', 'application/xml']
+                            },
+                            'sections': {
+                                'values': ['ServiceIdentification', 'ServiceProvider',
+                                'OperationsMetadata', 'Filter_Capabilities', 'All']
+                            }
+                        }
+                    },
+                    'GetRecords': {
+                        'methods': {
+                            'get': True,
+                            'post': True,
+                        },
+                        'parameters': {
+                            'typeNames': {
+                                'values': ['csw:Record']
+                            },
+                            'outputSchema': {
+                                'values': ['http://www.opengis.net/cat/csw/3.0']
+                            },
+                            'outputFormat': {
+                                'values': ['application/xml', 'application/json', 'application/atom+xml']
+                            },
+                            'CONSTRAINTLANGUAGE': {
+                                'values': ['FILTER', 'CQL_TEXT']
+                            },
+                            'ElementSetName': {
+                                'values': ['brief', 'summary', 'full']
+                            }
+                        },
+                        'constraints': {
+                        }
+                    },
+                    'GetRecordById': {
+                        'methods': {
+                            'get': True,
+                            'post': True,
+                        },
+                        'parameters': {
+                            'outputSchema': {
+                                'values': ['http://www.opengis.net/cat/csw/3.0']
+                            },
+                            'outputFormat': {
+                                'values': ['application/xml', 'application/json', 'application/atom+xml']
+                            },
+                            'ElementSetName': {
+                                'values': ['brief', 'summary', 'full']
+                            }
+                        }
+                    },
+                    'GetRepositoryItem': {
+                        'methods': {
+                            'get': True,
+                            'post': False,
+                        },
+                        'parameters': {
+                        }
+                    }
+                },
+                'parameters': {
+                    'version': {
+                        'values': ['2.0.2', '3.0.0']
+                    },
+                    'service': {
+                        'values': ['CSW']
+                    }
+                },
+                'constraints': {
+                    'MaxRecordDefault': {
+                        'values': ['10']
+                    },
+                    'PostEncoding': {
+                        'values': ['XML', 'SOAP']
+                    },
+                    'XPathQueryables': {
+                        'values': ['allowed']
+                    },
+                    'http://www.opengis.net/spec/csw/3.0/conf/OpenSearch': {
+                        'values': ['TRUE']
+                    },
+                    'http://www.opengis.net/spec/csw/3.0/conf/GetCapabilities-XML': {
+                        'values': ['TRUE']
+                    },
+                    'http://www.opengis.net/spec/csw/3.0/conf/GetRecordById-XML': {
+                        'values': ['TRUE']
+                    },
+                    'http://www.opengis.net/spec/csw/3.0/conf/GetRecords-Basic-XML': {
+                        'values': ['TRUE']
+                    },
+                    'http://www.opengis.net/spec/csw/3.0/conf/GetRecords-Distributed-XML': {
+                        'values': ['TRUE']
+                    },
+                    'http://www.opengis.net/spec/csw/3.0/conf/GetRecords-Distributed-KVP': {
+                        'values': ['TRUE']
+                    },
+                    'http://www.opengis.net/spec/csw/3.0/conf/GetRecords-Async-XML': {
+                        'values': ['TRUE']
+                    },
+                    'http://www.opengis.net/spec/csw/3.0/conf/GetRecords-Async-KVP': {
+                        'values': ['TRUE']
+                    },
+                    'http://www.opengis.net/spec/csw/3.0/conf/GetDomain-XML': {
+                        'values': ['TRUE']
+                    },
+                    'http://www.opengis.net/spec/csw/3.0/conf/GetDomain-KVP': {
+                        'values': ['TRUE']
+                    },
+                    'http://www.opengis.net/spec/csw/3.0/conf/Transaction': {
+                        'values': ['TRUE']
+                    },
+                    'http://www.opengis.net/spec/csw/3.0/conf/Harvest-Basic-XML': {
+                        'values': ['TRUE']
+                    },
+                    'http://www.opengis.net/spec/csw/3.0/conf/Harvest-Basic-KVP': {
+                        'values': ['TRUE']
+                    },
+                    'http://www.opengis.net/spec/csw/3.0/conf/Harvest-Async-XML': {
+                        'values': ['TRUE']
+                    },
+                    'http://www.opengis.net/spec/csw/3.0/conf/Harvest-Async-KVP': {
+                        'values': ['TRUE']
+                    },
+                    'http://www.opengis.net/spec/csw/3.0/conf/Harvest-Periodic-XML': {
+                        'values': ['TRUE']
+                    },
+                    'http://www.opengis.net/spec/csw/3.0/conf/Harvest-Periodic-KVP': {
+                        'values': ['TRUE']
+                    },
+                    'http://www.opengis.net/spec/csw/3.0/conf/Filter-CQL': {
+                        'values': ['TRUE']
+                    },
+                    'http://www.opengis.net/spec/csw/3.0/conf/Filter-FES-XML': {
+                        'values': ['TRUE']
+                    },
+                    'http://www.opengis.net/spec/csw/3.0/conf/Filter-FES-KVP-Advanced': {
+                        'values': ['TRUE']
+                    },
+                    'http://www.opengis.net/spec/csw/3.0/conf/SupportedGMLVersions': {
+                        'values': ['http://www.opengis.net/gml']
+                    },
+                    'http://www.opengis.net/spec/csw/3.0/conf/DefaultSortingAlgorithm': {
+                        'values': ['TRUE']
+                    },
+                    'http://www.opengis.net/spec/csw/3.0/conf/CoreQueryables': {
+                        'values': ['TRUE']
+                    },
+                    'http://www.opengis.net/spec/csw/3.0/conf/CoreSortables': {
+                        'values': ['TRUE']
+                    }
+                },
+                'typenames': {
+                    'csw:Record': {
+                        'outputschema': 'http://www.opengis.net/cat/csw/3.0',
+                        'queryables': {
+                            'SupportedDublinCoreQueryables': {
+                                # map Dublin Core queryables to core metadata model
+                                'dc:title':
+                                {'dbcol': self.md_core_model['mappings']['pycsw:Title']},
+                                'dc:creator':
+                                {'dbcol': self.md_core_model['mappings']['pycsw:Creator']},
+                                'dc:subject':
+                                {'dbcol': self.md_core_model['mappings']['pycsw:Keywords']},
+                                'dct:abstract':
+                                {'dbcol': self.md_core_model['mappings']['pycsw:Abstract']},
+                                'dc:publisher':
+                                {'dbcol': self.md_core_model['mappings']['pycsw:Publisher']},
+                                'dc:contributor':
+                                {'dbcol': self.md_core_model['mappings']['pycsw:Contributor']},
+                                'dct:modified':
+                                {'dbcol': self.md_core_model['mappings']['pycsw:Modified']},
+                                'dc:date':
+                                {'dbcol': self.md_core_model['mappings']['pycsw:Date']},
+                                'dc:type':
+                                {'dbcol': self.md_core_model['mappings']['pycsw:Type']},
+                                'dc:format':
+                                {'dbcol': self.md_core_model['mappings']['pycsw:Format']},
+                                'dc:identifier':
+                                {'dbcol': self.md_core_model['mappings']['pycsw:Identifier']},
+                                'dc:source':
+                                {'dbcol': self.md_core_model['mappings']['pycsw:Source']},
+                                'dc:language':
+                                {'dbcol': self.md_core_model['mappings']['pycsw:Language']},
+                                'dc:relation':
+                                {'dbcol': self.md_core_model['mappings']['pycsw:Relation']},
+                                'dc:rights':
+                                {'dbcol':
+                                 self.md_core_model['mappings']['pycsw:AccessConstraints']},
+                                # bbox and full text map to internal fixed columns
+                                'ows:BoundingBox':
+                                {'dbcol': self.md_core_model['mappings']['pycsw:BoundingBox']},
+                                'csw:AnyText':
+                                {'dbcol': self.md_core_model['mappings']['pycsw:AnyText']},
+                            }
+                        }
+                    }
+                }
+            }
+        }
+        self.set_model(prefix)
+
+    def set_model(self, prefix):
+        """sets model given request context"""
+
+        self.model = self.models[prefix]
+
+    def gen_domains(self):
+        """Generate parameter domain model"""
+        domain = {}
+        domain['methods'] = {'get': True, 'post': True}
+        domain['parameters'] = {'ParameterName': {'values': []}}
+        for operation in self.model['operations'].keys():
+            for parameter in self.model['operations'][operation]['parameters']:
+                domain['parameters']['ParameterName']['values'].append('%s.%s' %
+                                                        (operation, parameter))
+        return domain
+
+    def refresh_dc(self, mappings):
+        """Refresh Dublin Core mappings"""
+
+        LOGGER.debug('refreshing Dublin Core mappings with %s' % str(mappings))
+
+        defaults = {
+            'dc:title': 'pycsw:Title',
+            'dc:creator': 'pycsw:Creator',
+            'dc:subject': 'pycsw:Keywords',
+            'dct:abstract': 'pycsw:Abstract',
+            'dc:publisher': 'pycsw:Publisher',
+            'dc:contributor': 'pycsw:Contributor',
+            'dct:modified': 'pycsw:Modified',
+            'dc:date': 'pycsw:Date',
+            'dc:type': 'pycsw:Type',
+            'dc:format': 'pycsw:Format',
+            'dc:identifier': 'pycsw:Identifier',
+            'dc:source': 'pycsw:Source',
+            'dc:language': 'pycsw:Language',
+            'dc:relation': 'pycsw:Relation',
+            'dc:rights': 'pycsw:AccessConstraints',
+            'ows:BoundingBox': 'pycsw:BoundingBox',
+            'csw:AnyText': 'pycsw:AnyText',
+        }
+
+        for k, val in defaults.items():
+            for model, params in self.models.items():
+                queryables = params['typenames']['csw:Record']['queryables']
+                queryables['SupportedDublinCoreQueryables'][k] = {
+                    'dbcol': mappings['mappings'][val]
+                }
diff --git a/pycsw/plugins/profiles/__init__.py b/pycsw/core/etree.py
similarity index 93%
copy from pycsw/plugins/profiles/__init__.py
copy to pycsw/core/etree.py
index f98f82b..491a80b 100644
--- a/pycsw/plugins/profiles/__init__.py
+++ b/pycsw/core/etree.py
@@ -1,9 +1,9 @@
-# -*- coding: ISO-8859-15 -*-
+# -*- coding: utf-8 -*-
 # =================================================================
 #
 # Authors: Tom Kralidis <tomkralidis at gmail.com>
 #
-# Copyright (c) 2011 Tom Kralidis
+# Copyright (c) 2015 Tom Kralidis
 #
 # Permission is hereby granted, free of charge, to any person
 # obtaining a copy of this software and associated documentation
@@ -27,3 +27,5 @@
 # OTHER DEALINGS IN THE SOFTWARE.
 #
 # =================================================================
+
+from lxml import etree
diff --git a/pycsw/plugins/profiles/__init__.py b/pycsw/core/formats/__init__.py
similarity index 95%
copy from pycsw/plugins/profiles/__init__.py
copy to pycsw/core/formats/__init__.py
index f98f82b..08a4c3d 100644
--- a/pycsw/plugins/profiles/__init__.py
+++ b/pycsw/core/formats/__init__.py
@@ -1,9 +1,9 @@
-# -*- coding: ISO-8859-15 -*-
+# -*- coding: utf-8 -*-
 # =================================================================
 #
 # Authors: Tom Kralidis <tomkralidis at gmail.com>
 #
-# Copyright (c) 2011 Tom Kralidis
+# Copyright (c) 2015 Tom Kralidis
 #
 # Permission is hereby granted, free of charge, to any person
 # obtaining a copy of this software and associated documentation
diff --git a/pycsw/formats/fmt_json.py b/pycsw/core/formats/fmt_json.py
similarity index 75%
rename from pycsw/formats/fmt_json.py
rename to pycsw/core/formats/fmt_json.py
index 71e5ac5..ded6ac6 100644
--- a/pycsw/formats/fmt_json.py
+++ b/pycsw/core/formats/fmt_json.py
@@ -1,9 +1,9 @@
-# -*- coding: ISO-8859-15 -*-
+# -*- coding: utf-8 -*-
 # =================================================================
 #
 # Authors: Tom Kralidis <tomkralidis at gmail.com>
 #
-# Copyright (c) 2012 Tom Kralidis
+# Copyright (c) 2015 Tom Kralidis
 #
 # Permission is hereby granted, free of charge, to any person
 # obtaining a copy of this software and associated documentation
@@ -29,11 +29,16 @@
 # =================================================================
 
 import json
-from pycsw.util import exml2dict
+from pycsw.core.util import xml2dict
 
 
-def exml2json(response, namespaces, pretty_print=False):
-    """Convert an lxml object to JSON"""
+def xml2json(xml_string, namespaces, pretty_print=False):
+    """Convert an xml string to JSON"""
+
+    separators = (',', ': ')
+
     if pretty_print:
-        return json.dumps(exml2dict(response, namespaces), indent=4)
-    return json.dumps(exml2dict(response, namespaces))
+        return json.dumps(xml2dict(xml_string, namespaces),
+                          indent=4, separators=separators)
+
+    return json.dumps(xml2dict(xml_string, namespaces), separators=separators)
diff --git a/pycsw/log.py b/pycsw/core/log.py
similarity index 98%
rename from pycsw/log.py
rename to pycsw/core/log.py
index fada401..2f32e6f 100644
--- a/pycsw/log.py
+++ b/pycsw/core/log.py
@@ -1,9 +1,9 @@
-# -*- coding: iso-8859-15 -*-
+# -*- coding: utf-8 -*-
 # =================================================================
 #
 # Authors: Tom Kralidis <tomkralidis at gmail.com>
 #
-# Copyright (c) 2011 Tom Kralidis
+# Copyright (c) 2015 Tom Kralidis
 #
 # Permission is hereby granted, free of charge, to any person
 # obtaining a copy of this software and associated documentation
diff --git a/pycsw/metadata.py b/pycsw/core/metadata.py
similarity index 80%
rename from pycsw/metadata.py
rename to pycsw/core/metadata.py
index 8153e6f..6c0d030 100644
--- a/pycsw/metadata.py
+++ b/pycsw/core/metadata.py
@@ -1,9 +1,10 @@
-# -*- coding: ISO-8859-15 -*-
+# -*- coding: utf-8 -*-
 # =================================================================
 #
 # Authors: Tom Kralidis <tomkralidis at gmail.com>
 #
-# Copyright (c) 2011 Tom Kralidis
+# Copyright (c) 2015 Tom Kralidis
+# Copyright (c) 2016 James F. Dickens
 #
 # Permission is hereby granted, free of charge, to any person
 # obtaining a copy of this software and associated documentation
@@ -30,11 +31,12 @@
 
 import logging
 import uuid
-from urlparse import urlparse
-from lxml import etree
+from six.moves import range
+from six.moves.urllib.parse import urlparse
 from owslib.util import build_get_url
-from pycsw import util
-from geolinks.links import sniff_link
+from geolinks import sniff_link
+from pycsw.core import util
+from pycsw.core.etree import etree
 
 LOGGER = logging.getLogger(__name__)
 
@@ -44,7 +46,7 @@ def parse_record(context, record, repos=None,
     ''' parse metadata '''
 
     if identifier is None:
-        identifier = uuid.uuid4().get_urn()
+        identifier = uuid.uuid4().urn
 
     # parse web services
     if (mtype == 'http://www.opengis.net/cat/csw/2.0.2' and
@@ -73,7 +75,11 @@ def parse_record(context, record, repos=None,
     elif mtype == 'http://www.opengis.net/wms':  # WMS
         LOGGER.debug('WMS detected, fetching via OWSLib')
         return _parse_wms(context, repos, record, identifier)
-     
+
+    elif mtype == 'http://www.opengis.net/wmts/1.0':  # WMTS
+        LOGGER.debug('WMTS 1.0.0 detected, fetching via OWSLib')
+        return _parse_wmts(context, repos, record, identifier)
+
     elif mtype == 'http://www.opengis.net/wps/1.0.0':  # WPS
         LOGGER.debug('WPS detected, fetching via OWSLib')
         return [_parse_wps(context, repos, record, identifier)]
@@ -127,6 +133,8 @@ def _parse_metadata(context, repos, record):
         return [_parse_iso(context, repos, exml)]
     elif root == 'metadata':  # FGDC
         return [_parse_fgdc(context, repos, exml)]
+    elif root == '{%s}TRANSFER' % context.namespaces['gm03']:  # GM03
+        return [_parse_gm03(context, repos, exml)]
     elif root == '{%s}Record' % context.namespaces['csw']:  # Dublin Core CSW
         return [_parse_dc(context, repos, exml)]
     elif root == '{%s}RDF' % context.namespaces['rdf']:  # Dublin Core RDF
@@ -219,11 +227,18 @@ def _parse_csw(context, repos, record, identifier, pagesize=10):
                            maxrecords=pagesize, outputschema=csw_outputschema, esn='full')
         except Exception as err:  # this is a CSW, but server rejects query
             raise RuntimeError(md.response)
-        for k, v in md.records.iteritems():
-            if csw_typenames == 'gmd:MD_Metadata':
-                recobjs.append(_parse_iso(context, repos, etree.fromstring(v.xml, context.parser)))
-            else:
-                recobjs.append(_parse_dc(context, repos, etree.fromstring(v.xml, context.parser)))
+        for k, v in md.records.items():
+            # try to parse metadata
+            try:
+                LOGGER.debug('Parsing metadata record: %s', v.xml)
+                if csw_typenames == 'gmd:MD_Metadata':
+                    recobjs.append(_parse_iso(context, repos,
+                                              etree.fromstring(v.xml, context.parser)))
+                else:
+                    recobjs.append(_parse_dc(context, repos,
+                                             etree.fromstring(v.xml, context.parser)))
+            except Exception as err:  # parsing failed for some reason
+                LOGGER.warning('Metadata parsing failed %s', err)
 
     return recobjs
 
@@ -237,10 +252,10 @@ def _parse_waf(context, repos, record, identifier):
 
     try:
         parser = etree.HTMLParser()
-        tree = etree.fromstring(content, parser=parser)
+        tree = etree.fromstring(content, parser)
     except Exception as err:
         raise Exception('Could not parse WAF: %s' % str(err))
-        
+
     up = urlparse(record)
     links = []
 
@@ -326,8 +341,8 @@ def _parse_wms(context, repos, record, identifier):
     _set(context, serviceobj, 'pycsw:Links', '^'.join(links))
     _set(context, serviceobj, 'pycsw:XML', caps2iso(serviceobj, md, context))
 
-    recobjs.append(serviceobj) 
-         
+    recobjs.append(serviceobj)
+
     # generate record foreach layer
 
     LOGGER.debug('Harvesting %d WMS layers' % len(md.contents))
@@ -404,6 +419,126 @@ def _parse_wms(context, repos, record, identifier):
 
     return recobjs
 
+def _parse_wmts(context, repos, record, identifier):
+
+    from owslib.wmts import WebMapTileService
+
+    recobjs = []
+    serviceobj = repos.dataset()
+
+    md = WebMapTileService(record)
+    # generate record of service instance
+    _set(context, serviceobj, 'pycsw:Identifier', identifier)
+    _set(context, serviceobj, 'pycsw:Typename', 'csw:Record')
+    _set(context, serviceobj, 'pycsw:Schema', 'http://www.opengis.net/wmts/1.0')
+    _set(context, serviceobj, 'pycsw:MdSource', record)
+    _set(context, serviceobj, 'pycsw:InsertDate', util.get_today_and_now())
+    _set(context, serviceobj, 'pycsw:AnyText', util.get_anytext(md.getServiceXML()))
+    _set(context, serviceobj, 'pycsw:Type', 'service')
+    _set(context, serviceobj, 'pycsw:Title', md.identification.title)
+    _set(context, serviceobj, 'pycsw:Abstract', md.identification.abstract)
+    _set(context, serviceobj, 'pycsw:Keywords', ','.join(md.identification.keywords))
+    _set(context, serviceobj, 'pycsw:Creator', md.provider.contact.name)
+    _set(context, serviceobj, 'pycsw:Publisher', md.provider.name)
+    _set(context, serviceobj, 'pycsw:Contributor', md.provider.contact.name)
+    _set(context, serviceobj, 'pycsw:OrganizationName', md.provider.contact.name)
+    _set(context, serviceobj, 'pycsw:AccessConstraints', md.identification.accessconstraints)
+    _set(context, serviceobj, 'pycsw:OtherConstraints', md.identification.fees)
+    _set(context, serviceobj, 'pycsw:Source', record)
+    _set(context, serviceobj, 'pycsw:Format', md.identification.type)
+
+    for c in md.contents:
+        if md.contents[c].parent is None:
+            bbox = md.contents[c].boundingBoxWGS84
+            tmp = '%s,%s,%s,%s' % (bbox[0], bbox[1], bbox[2], bbox[3])
+            _set(context, serviceobj, 'pycsw:BoundingBox', util.bbox2wktpolygon(tmp))
+            break
+    _set(context, serviceobj, 'pycsw:CRS', 'urn:ogc:def:crs:EPSG:6.11:4326')
+    _set(context, serviceobj, 'pycsw:DistanceUOM', 'degrees')
+    _set(context, serviceobj, 'pycsw:ServiceType', 'OGC:WMTS')
+    _set(context, serviceobj, 'pycsw:ServiceTypeVersion', md.identification.version)
+    _set(context, serviceobj, 'pycsw:Operation', ','.join([d.name for d in md.operations]))
+    _set(context, serviceobj, 'pycsw:OperatesOn', ','.join(list(md.contents)))
+    _set(context, serviceobj, 'pycsw:CouplingType', 'tight')
+
+    links = [
+        '%s,OGC-WMTS Web Map Service,OGC:WMTS,%s' % (identifier, md.url),
+    ]
+
+    _set(context, serviceobj, 'pycsw:Links', '^'.join(links))
+    _set(context, serviceobj, 'pycsw:XML', caps2iso(serviceobj, md, context))
+
+    recobjs.append(serviceobj)
+
+    # generate record for each layer
+
+    LOGGER.debug('Harvesting %d WMTS layers' % len(md.contents))
+
+    for layer in md.contents:
+        recobj = repos.dataset()
+        keywords = ''
+        identifier2 = '%s-%s' % (identifier, md.contents[layer].name)
+        _set(context, recobj, 'pycsw:Identifier', identifier2)
+        _set(context, recobj, 'pycsw:Typename', 'csw:Record')
+        _set(context, recobj, 'pycsw:Schema', 'http://www.opengis.net/wmts/1.0')
+        _set(context, recobj, 'pycsw:MdSource', record)
+        _set(context, recobj, 'pycsw:InsertDate', util.get_today_and_now())
+        _set(context, recobj, 'pycsw:Type', 'dataset')
+        _set(context, recobj, 'pycsw:ParentIdentifier', identifier)
+        if md.contents[layer].title:
+             _set(context, recobj, 'pycsw:Title', md.contents[layer].title)
+        else:
+            _set(context, recobj, 'pycsw:Title', "")
+        if md.contents[layer].abstract:
+            _set(context, recobj, 'pycsw:Abstract', md.contents[layer].abstract)
+        else:
+            _set(context, recobj, 'pycsw:Abstract', "")
+        if hasattr(md.contents[layer], 'keywords'):  # safeguard against older OWSLib installs
+            keywords = ','.join(md.contents[layer].keywords)
+        _set(context, recobj, 'pycsw:Keywords', keywords)
+
+        _set(context, recobj, 'pycsw:AnyText',
+             util.get_anytext([md.contents[layer].title,
+                              md.contents[layer].abstract,
+                             ','.join(keywords)
+                             ]))
+
+        bbox = md.contents[layer].boundingBoxWGS84
+
+        if bbox is not None:
+            tmp = '%s,%s,%s,%s' % (bbox[0], bbox[1], bbox[2], bbox[3])
+            _set(context, recobj, 'pycsw:BoundingBox', util.bbox2wktpolygon(tmp))
+            _set(context, recobj, 'pycsw:CRS', 'urn:ogc:def:crs:EPSG:6.11:4326')
+            _set(context, recobj, 'pycsw:DistanceUOM', 'degrees')
+        else:
+            bbox = md.contents[layer].boundingBox
+            if bbox:
+                tmp = '%s,%s,%s,%s' % (bbox[0], bbox[1], bbox[2], bbox[3])
+                _set(context, recobj, 'pycsw:BoundingBox', util.bbox2wktpolygon(tmp))
+                _set(context, recobj, 'pycsw:CRS', 'urn:ogc:def:crs:EPSG:6.11:%s' % \
+                bbox[-1].split(':')[1])
+
+
+        params = {
+            'service': 'WMTS',
+            'version': '1.0.0',
+            'request': 'GetTile',
+            'layer': md.contents[layer].name,
+        }
+
+        links = [
+           '%s,OGC-Web Map Tile Service,OGC:WMTS,%s' % (md.contents[layer].name, md.url),
+            '%s,Web image thumbnail (URL),WWW:LINK-1.0-http--image-thumbnail,%s' % (md.contents[layer].name, build_get_url(md.url, params))
+        ]
+
+        _set(context, recobj, 'pycsw:Links', '^'.join(links))
+        _set(context, recobj, 'pycsw:XML', caps2iso(recobj, md, context))
+
+        recobjs.append(recobj)
+
+    return recobjs
+
+
 def _parse_wfs(context, repos, record, identifier):
 
     from owslib.wfs import WebFeatureService
@@ -772,7 +907,7 @@ def _parse_fgdc(context, repos, exml):
     if md.idinfo.datasetid is not None:  # we need an identifier
         _set(context, recobj, 'pycsw:Identifier', md.idinfo.datasetid)
     else:  # generate one ourselves
-        _set(context, recobj, 'pycsw:Identifier', uuid.uuid1().get_urn())
+        _set(context, recobj, 'pycsw:Identifier', uuid.uuid1().urn)
 
     _set(context, recobj, 'pycsw:Typename', 'fgdc:metadata')
     _set(context, recobj, 'pycsw:Schema', context.namespaces['fgdc'])
@@ -844,6 +979,111 @@ def _parse_fgdc(context, repos, exml):
 
     return recobj
 
+def _parse_gm03(context, repos, exml):
+
+    def get_value_by_language(pt_group, language, pt_type='text'):
+        for ptg in pt_group:
+            if ptg.language == language:
+                if pt_type == 'url':
+                    val = ptg.plain_url
+                else:  # 'text'
+                    val = ptg.plain_text
+                return val
+
+    from owslib.gm03 import GM03
+
+    recobj = repos.dataset()
+    links = []
+
+    md = GM03(exml)
+
+    if hasattr(md.data, 'core'):
+        data = md.data.core
+    elif hasattr(md.data, 'comprehensive'):
+        data = md.data.comprehensive
+
+    language = data.metadata.language
+
+    _set(context, recobj, 'pycsw:Identifier', data.metadata.file_identifier)
+    _set(context, recobj, 'pycsw:Typename', 'gm03:TRANSFER')
+    _set(context, recobj, 'pycsw:Schema', context.namespaces['gm03'])
+    _set(context, recobj, 'pycsw:MdSource', 'local')
+    _set(context, recobj, 'pycsw:InsertDate', util.get_today_and_now())
+    _set(context, recobj, 'pycsw:XML', md.xml)
+    _set(context, recobj, 'pycsw:AnyText', util.get_anytext(exml))
+    _set(context, recobj, 'pycsw:Language', data.metadata.language)
+    _set(context, recobj, 'pycsw:Type', data.metadata.hierarchy_level[0])
+    _set(context, recobj, 'pycsw:Date', data.metadata.date_stamp)
+
+    for dt in data.date:
+        if dt.date_type == 'modified':
+            _set(context, recobj, 'pycsw:Modified', data.date.date)
+        elif dt.date_type == 'creation':
+            _set(context, recobj, 'pycsw:CreationDate', data.date.date)
+        elif dt.date_type == 'publication':
+            _set(context, recobj, 'pycsw:PublicationDate', data.date.date)
+        elif dt.date_type == 'revision':
+            _set(context, recobj, 'pycsw:RevisionDate', data.date.date)
+
+    if hasattr(data, 'metadata_point_of_contact'):
+        _set(context, recobj, 'pycsw:ResponsiblePartyRole', data.metadata_point_of_contact.role)
+
+    _set(context, recobj, 'pycsw:Source', data.metadata.dataset_uri)
+    _set(context, recobj, 'pycsw:CRS','urn:ogc:def:crs:EPSG:6.11:4326')
+
+    if hasattr(data, 'citation'):
+        _set(context, recobj, 'pycsw:Title', get_value_by_language(data.citation.title.pt_group, language))
+
+    if hasattr(data, 'data_identification'):
+        _set(context, recobj, 'pycsw:Abstract', get_value_by_language(data.data_identification.abstract.pt_group, language))
+        _set(context, recobj, 'pycsw:TopicCategory', data.data_identification.topic_category)
+        _set(context, recobj, 'pycsw:ResourceLanguage', data.data_identification.language)
+
+    if hasattr(data, 'format'):
+        _set(context, recobj, 'pycsw:Format', data.format.name)
+
+    # bbox
+    if hasattr(data, 'geographic_bounding_box'):
+        try:
+            tmp = '%s,%s,%s,%s' % (data.geographic_bounding_box.west_bound_longitude,
+                                   data.geographic_bounding_box.south_bound_latitude,
+                                   data.geographic_bounding_box.east_bound_longitude,
+                                   data.geographic_bounding_box.north_bound_latitude)
+            _set(context, recobj, 'pycsw:BoundingBox', util.bbox2wktpolygon(tmp))
+        except:  # coordinates are corrupted, do not include
+            _set(context, recobj, 'pycsw:BoundingBox', None)
+    else:
+        _set(context, recobj, 'pycsw:BoundingBox', None)
+
+    # temporal extent
+    if hasattr(data, 'temporal_extent'):
+        if data.temporal_extent.extent['begin'] is not None and data.temporal_extent.extent['end'] is not None:
+            _set(context, recobj, 'pycsw:TempExtent_begin', data.temporal_extent.extent['begin'])
+            _set(context, recobj, 'pycsw:TempExtent_end', data.temporal_extent.extent['end'])
+
+    # online linkages
+    name = description = protocol = ''
+
+    if hasattr(data.online_resource, 'name'):
+        name = get_value_by_language(data.online_resource.name.pt_group, language)
+    if hasattr(data.online_resource, 'description'):
+        description = get_value_by_language(data.online_resource.description.pt_group, language)
+    linkage = get_value_by_language(data.online_resource.linkage.pt_group, language, 'url')
+
+    tmp = '%s,"%s",%s,%s' % (name, description, protocol, linkage)
+    links.append(tmp)
+
+    if len(links) > 0:
+        _set(context, recobj, 'pycsw:Links', '^'.join(links))
+
+    keywords = []
+    for kw in data.keywords:
+        keywords.append(get_value_by_language(kw.keyword.pt_group, language))
+        _set(context, recobj, 'pycsw:Keywords', ','.join(keywords))
+
+    # contacts
+    return recobj
+
 def _parse_iso(context, repos, exml):
 
     from owslib.iso import MD_Metadata
@@ -886,7 +1126,7 @@ def _parse_iso(context, repos, exml):
 
         if len(md.identification.resourcelanguage) > 0:
             _set(context, recobj, 'pycsw:ResourceLanguage', md.identification.resourcelanguage[0])
- 
+
         if hasattr(md.identification, 'bbox'):
             bbox = md.identification.bbox
         else:
@@ -911,16 +1151,16 @@ def _parse_iso(context, repos, exml):
             all_orgs = set([item.organization for item in md.identification.contributor if hasattr(item, 'organization') and item.organization is not None])
             _set(context, recobj, 'pycsw:Contributor', ';'.join(all_orgs))
 
-        if (hasattr(md.identification, 'contact') and 
+        if (hasattr(md.identification, 'contact') and
             len(md.identification.contact) > 0):
             all_orgs = set([item.organization for item in md.identification.contact if hasattr(item, 'organization') and item.organization is not None])
             _set(context, recobj, 'pycsw:OrganizationName', ';'.join(all_orgs))
 
         if len(md.identification.securityconstraints) > 0:
-            _set(context, recobj, 'pycsw:SecurityConstraints', 
+            _set(context, recobj, 'pycsw:SecurityConstraints',
             md.identification.securityconstraints[0])
         if len(md.identification.accessconstraints) > 0:
-            _set(context, recobj, 'pycsw:AccessConstraints', 
+            _set(context, recobj, 'pycsw:AccessConstraints',
             md.identification.accessconstraints[0])
         if len(md.identification.otherconstraints) > 0:
             _set(context, recobj, 'pycsw:OtherConstraints', md.identification.otherconstraints[0])
@@ -958,7 +1198,7 @@ def _parse_iso(context, repos, exml):
         _set(context, recobj, 'pycsw:ServiceTypeVersion', md.serviceidentification.version)
 
         _set(context, recobj, 'pycsw:CouplingType', md.serviceidentification.couplingtype)
-   
+
     service_types = []
     for smd in md.identificationinfo:
         if smd.identtype == 'service' and smd.type is not None:
@@ -966,14 +1206,14 @@ def _parse_iso(context, repos, exml):
 
     _set(context, recobj, 'pycsw:ServiceType', ','.join(service_types))
 
-        #if len(md.serviceidentification.operateson) > 0: 
-        #    _set(context, recobj, 'pycsw:operateson = VARCHAR(32), 
-        #_set(context, recobj, 'pycsw:operation VARCHAR(32), 
-        #_set(context, recobj, 'pycsw:operatesonidentifier VARCHAR(32), 
-        #_set(context, recobj, 'pycsw:operatesoname VARCHAR(32), 
+        #if len(md.serviceidentification.operateson) > 0:
+        #    _set(context, recobj, 'pycsw:operateson = VARCHAR(32),
+        #_set(context, recobj, 'pycsw:operation VARCHAR(32),
+        #_set(context, recobj, 'pycsw:operatesonidentifier VARCHAR(32),
+        #_set(context, recobj, 'pycsw:operatesoname VARCHAR(32),
 
 
-    if hasattr(md.identification, 'dataquality'):     
+    if hasattr(md.identification, 'dataquality'):
         _set(context, recobj, 'pycsw:Degree', md.dataquality.conformancedegree)
         _set(context, recobj, 'pycsw:Lineage', md.dataquality.lineage)
         _set(context, recobj, 'pycsw:SpecificationTitle', md.dataquality.specificationtitle)
@@ -1109,6 +1349,6 @@ def caps2iso(record, caps, context):
     apiso_obj = APISO(context.model, context.namespaces, context)
     apiso_obj.ogc_schemas_base = 'http://schemas.opengis.net'
     apiso_obj.url = context.url
-    queryables = dict(apiso_obj.repository['queryables']['SupportedISOQueryables'].items() + apiso_obj.repository['queryables']['SupportedISOQueryables'].items())
+    queryables = dict(apiso_obj.repository['queryables']['SupportedISOQueryables'].items())
     iso_xml = apiso_obj.write_record(record, 'full', 'http://www.isotc211.org/2005/gmd', queryables, caps)
     return etree.tostring(iso_xml)
diff --git a/pycsw/repository.py b/pycsw/core/repository.py
similarity index 99%
rename from pycsw/repository.py
rename to pycsw/core/repository.py
index 9cb6415..aba9369 100644
--- a/pycsw/repository.py
+++ b/pycsw/core/repository.py
@@ -1,10 +1,11 @@
-# -*- coding: iso-8859-15 -*-
+# -*- coding: utf-8 -*-
 # =================================================================
 #
 # Authors: Tom Kralidis <tomkralidis at gmail.com>
 #          Angelos Tzotsos <tzotsos at gmail.com>
 #
-# Copyright (c) 2010 Tom Kralidis
+# Copyright (c) 2015 Tom Kralidis
+# Copyright (c) 2015 Angelos Tzotsos
 #
 # Permission is hereby granted, free of charge, to any person
 # obtaining a copy of this software and associated documentation
@@ -35,7 +36,7 @@ from sqlalchemy import create_engine, asc, desc, func, __version__, select
 from sqlalchemy.sql import text
 from sqlalchemy.ext.declarative import declarative_base
 from sqlalchemy.orm import create_session
-from pycsw import util
+from pycsw.core import util
 
 LOGGER = logging.getLogger(__name__)
 
@@ -175,7 +176,7 @@ class Repository(object):
                 self.queryables[qname] = {}
 
                 for qkey, qvalue in \
-                self.context.model['typenames'][tname]['queryables'][qname].iteritems():
+                self.context.model['typenames'][tname]['queryables'][qname].items():
                     self.queryables[qname][qkey] = qvalue
 
         # flatten all queryables
@@ -194,6 +195,7 @@ class Repository(object):
 
     def query_ids(self, ids):
         ''' Query by list of identifiers '''
+
         column = getattr(self.dataset, \
         self.context.md_core_model['mappings']['pycsw:Identifier'])
 
diff --git a/bin/pycsw-pylint.sh b/pycsw/core/schemas/catalog.xml
old mode 100755
new mode 100644
similarity index 58%
copy from bin/pycsw-pylint.sh
copy to pycsw/core/schemas/catalog.xml
index 43e262c..c8f494c
--- a/bin/pycsw-pylint.sh
+++ b/pycsw/core/schemas/catalog.xml
@@ -1,9 +1,10 @@
-#!/bin/sh
+<?xml version="1.0"?>
+<!--
 # =================================================================
 #
 # Authors: Tom Kralidis <tomkralidis at gmail.com>
 #
-# Copyright (c) 2011 Tom Kralidis
+# Copyright (c) 2015 Tom Kralidis
 #
 # Permission is hereby granted, free of charge, to any person
 # obtaining a copy of this software and associated documentation
@@ -27,8 +28,13 @@
 # OTHER DEALINGS IN THE SOFTWARE.
 #
 # =================================================================
-
-# run pylint without warnings about docstrings on first line
-# and suppress reporting
-
-pylint -r n -d C0111 $1
+-->
+<!DOCTYPE catalog PUBLIC "-//OASIS//DTD Entity Resolution XML Catalog V1.0//EN" "http://www.oasis-open.org/committees/entity/release/1.0/catalog.dtd">
+<catalog xmlns="urn:oasis:names:tc:entity:xmlns:xml:catalog">
+  <rewriteSystem systemIdStartString="http://schemas.opengis.net/iso/" rewritePrefix="../../plugins/profiles/apiso/schemas/ogc/iso/"/>
+  <rewriteURI systemIdStartString="http://schemas.opengis.net/iso/" rewritePrefix="../../plugins/profiles/apiso/schemas/ogc/iso/"/>
+  <rewriteSystem systemIdStartString="http://schemas.opengis.net/" rewritePrefix="ogc/"/>
+  <rewriteURI systemIdStartString="http://schemas.opengis.net/" rewritePrefix="ogc/"/>
+  <rewriteSystem systemIdStartString="http://www.w3.org/" rewritePrefix="w3c/"/>
+  <rewriteURI uriStartString="http://www.w3.org/" rewritePrefix="w3c/"/>
+</catalog>
diff --git a/pycsw/schemas/ogc/OGC-SOFTWARE-NOTICE.txt b/pycsw/core/schemas/ogc/OGC-SOFTWARE-NOTICE.txt
similarity index 100%
rename from pycsw/schemas/ogc/OGC-SOFTWARE-NOTICE.txt
rename to pycsw/core/schemas/ogc/OGC-SOFTWARE-NOTICE.txt
diff --git a/pycsw/schemas/ogc/README.txt b/pycsw/core/schemas/ogc/README.txt
similarity index 100%
rename from pycsw/schemas/ogc/README.txt
rename to pycsw/core/schemas/ogc/README.txt
diff --git a/pycsw/schemas/ogc/csw/2.0.2/CSW-discovery.xsd b/pycsw/core/schemas/ogc/csw/2.0.2/CSW-discovery.xsd
similarity index 100%
rename from pycsw/schemas/ogc/csw/2.0.2/CSW-discovery.xsd
rename to pycsw/core/schemas/ogc/csw/2.0.2/CSW-discovery.xsd
diff --git a/pycsw/schemas/ogc/csw/2.0.2/CSW-publication.xsd b/pycsw/core/schemas/ogc/csw/2.0.2/CSW-publication.xsd
similarity index 100%
rename from pycsw/schemas/ogc/csw/2.0.2/CSW-publication.xsd
rename to pycsw/core/schemas/ogc/csw/2.0.2/CSW-publication.xsd
diff --git a/pycsw/schemas/ogc/csw/2.0.2/rec-dcmes.xsd b/pycsw/core/schemas/ogc/csw/2.0.2/rec-dcmes.xsd
similarity index 100%
rename from pycsw/schemas/ogc/csw/2.0.2/rec-dcmes.xsd
rename to pycsw/core/schemas/ogc/csw/2.0.2/rec-dcmes.xsd
diff --git a/pycsw/schemas/ogc/csw/2.0.2/rec-dcterms.xsd b/pycsw/core/schemas/ogc/csw/2.0.2/rec-dcterms.xsd
similarity index 100%
copy from pycsw/schemas/ogc/csw/2.0.2/rec-dcterms.xsd
copy to pycsw/core/schemas/ogc/csw/2.0.2/rec-dcterms.xsd
diff --git a/pycsw/schemas/ogc/csw/2.0.2/record.xsd b/pycsw/core/schemas/ogc/csw/2.0.2/record.xsd
similarity index 100%
rename from pycsw/schemas/ogc/csw/2.0.2/record.xsd
rename to pycsw/core/schemas/ogc/csw/2.0.2/record.xsd
diff --git a/pycsw/core/schemas/ogc/csw/3.0/README.txt b/pycsw/core/schemas/ogc/csw/3.0/README.txt
new file mode 100644
index 0000000..6d80d9c
--- /dev/null
+++ b/pycsw/core/schemas/ogc/csw/3.0/README.txt
@@ -0,0 +1,25 @@
+# 2015-02-13
+
+The unofficial CSW 3.0 schema can be tested from here.
+
+http://test.schemas.opengis.net/csw/3.0/
+
+I did make one change to the examples/Capabilities.xml
+
+Thanks,
+
+kevin
+
+####################################################################
+--- csw3_0_0-beta-20150123-pv/csw/3.0/examples/Capabilities.xml
++++ csw3_0_0-beta-20150123-pv-s1/csw/3.0/examples/Capabilities.xml
+@@ -15,7 +15,7 @@
+    xmlns:xlink="http://www.w3.org/1999/xlink"
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xsi:schemaLocation="http://www.opengis.net/cat/csw/3.0
+-                       http://www.opengis.net/csw/3.0/cswAll.xsd
++                       http://schemas.opengis.net/csw/3.0/cswAll.xsd
+                        http://www.opengis.net/gml/3.2
+                        http://schemas.opengis.net/gml/3.2.1/gml.xsd
+                        http://www.w3.org/1999/xlink
+
diff --git a/pycsw/core/schemas/ogc/csw/3.0/cswAll.xsd b/pycsw/core/schemas/ogc/csw/3.0/cswAll.xsd
new file mode 100644
index 0000000..2af2e0c
--- /dev/null
+++ b/pycsw/core/schemas/ogc/csw/3.0/cswAll.xsd
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xsd:schema
+   targetNamespace="http://www.opengis.net/cat/csw/3.0"
+   xmlns:csw30="http://www.opengis.net/cat/csw/3.0"
+   xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+   elementFormDefault="qualified"
+   version="3.0" id="cswAll">
+   <xsd:annotation>
+      <xsd:appinfo>cswAll.xsd 2012-06-04</xsd:appinfo>
+      <xsd:documentation>
+         This XML Schema Document includes and imports, directly or
+         indirectly, all the XML Schemas defined by the Catalogue Service
+         Specification.
+      
+         CSW is an OGC Standard.
+
+         Copyright (c) 2012 Open Geospatial Consortium, Inc.
+         All Rights Reserved.
+         To obtain additional rights see: http://www.opengeospatial.org/legal/.
+      </xsd:documentation>
+   </xsd:annotation>
+   <!-- =================================================================== -->
+   <!-- includes and imports                                                -->
+   <!-- =================================================================== -->
+   <xsd:include schemaLocation="cswCommon.xsd"/>
+   <xsd:include schemaLocation="cswGetCapabilities.xsd"/>
+   <xsd:include schemaLocation="cswGetDomain.xsd"/>
+   <xsd:include schemaLocation="cswGetRecords.xsd"/>
+   <xsd:include schemaLocation="cswGetRecordById.xsd"/>
+   <xsd:include schemaLocation="cswTransaction.xsd"/>
+   <xsd:include schemaLocation="cswHarvest.xsd"/>
+   <xsd:include schemaLocation="cswUnHarvest.xsd"/>
+</xsd:schema>
diff --git a/pycsw/core/schemas/ogc/csw/3.0/cswCommon.xsd b/pycsw/core/schemas/ogc/csw/3.0/cswCommon.xsd
new file mode 100644
index 0000000..d318e6f
--- /dev/null
+++ b/pycsw/core/schemas/ogc/csw/3.0/cswCommon.xsd
@@ -0,0 +1,71 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xsd:schema
+   targetNamespace="http://www.opengis.net/cat/csw/3.0"
+   xmlns:csw30="http://www.opengis.net/cat/csw/3.0"
+   xmlns:fes="http://www.opengis.net/fes/2.0"
+   xmlns:ows="http://www.opengis.net/ows/2.0"
+   xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+   elementFormDefault="qualified"
+   version="3.0"
+   id="cswCommon">
+   <xsd:annotation>
+      <xsd:appinfo>
+         <dc:identifier xmlns:dc="http://purl.org/dc/elements/1.1/">http://schemas.opengis.net/csw/3.0/cswCommons.xsd</dc:identifier>
+      </xsd:appinfo>
+      <xsd:documentation xml:lang="en">
+         This schema defines commen elements used in the CSW schemas.
+      </xsd:documentation>
+   </xsd:annotation>
+   <xsd:include schemaLocation="record.xsd"/>
+   <xsd:import namespace="http://www.opengis.net/ows/2.0"
+        schemaLocation="../../ows/2.0/owsAll.xsd"/>
+   <xsd:import namespace="http://www.opengis.net/fes/2.0"
+        schemaLocation="../../filter/2.0/filterAll.xsd"/>
+   <!-- ==================================================================== -->
+   <!-- REQUEST BASE TYPE                                                  -->
+   <!-- ==================================================================== -->
+   <xsd:complexType name="RequestBaseType" abstract="true" id="RequestBaseType">
+      <xsd:annotation>
+         <xsd:documentation>
+            Base type for all request messages except GetCapabilities.
+            The attributes identify the relevant service type and version.
+         </xsd:documentation>
+      </xsd:annotation>
+      <xsd:attribute name="service" type="ows:ServiceType"
+                     use="optional" default="CSW"/>
+      <xsd:attribute name="version" type="ows:VersionType"
+                     use="optional" default="3.0.0"/>
+   </xsd:complexType>
+   <!-- ==================================================================== -->
+   <!-- ACKNOWLEDGEMENT                                                    -->
+   <!-- ==================================================================== -->
+   <xsd:element name="Acknowledgement"
+                type="csw30:AcknowledgementType" id="Acknowledgement"/>
+   <xsd:complexType name="AcknowledgementType" id="AcknowledgementType">
+      <xsd:annotation>
+         <xsd:documentation xml:lang="en">
+            This is a general acknowledgement response message for all requests 
+            that may be processed in an asynchronous manner.
+            EchoedRequest - Echoes the submitted request message
+            RequestId     - identifier for polling purposes (if no response 
+                            handler is available, or the URL scheme is
+                            unsupported)
+         </xsd:documentation>
+      </xsd:annotation>
+      <xsd:sequence>
+         <xsd:element name="EchoedRequest" type="csw30:EchoedRequestType"/>
+         <xsd:element name="RequestId" type="xsd:anyURI" minOccurs="0"/>
+      </xsd:sequence>
+      <xsd:attribute name="timeStamp" type="xsd:dateTime" use="required"/>
+   </xsd:complexType>
+   <xsd:complexType name="EchoedRequestType" id="EchoedRequestType">
+      <xsd:annotation>
+         <xsd:documentation xml:lang="en">
+            Includes a copy of the request message body.
+         </xsd:documentation>
+      </xsd:annotation>
+      <xsd:sequence>
+         <xsd:any namespace="##any" processContents="lax"/>
+      </xsd:sequence>
+   </xsd:complexType>
+</xsd:schema>
diff --git a/pycsw/core/schemas/ogc/csw/3.0/cswGetCapabilities.xsd b/pycsw/core/schemas/ogc/csw/3.0/cswGetCapabilities.xsd
new file mode 100644
index 0000000..bf654b3
--- /dev/null
+++ b/pycsw/core/schemas/ogc/csw/3.0/cswGetCapabilities.xsd
@@ -0,0 +1,80 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xsd:schema
+   targetNamespace="http://www.opengis.net/cat/csw/3.0"
+   xmlns:csw30="http://www.opengis.net/cat/csw/3.0"
+   xmlns:fes="http://www.opengis.net/fes/2.0"
+   xmlns:ows="http://www.opengis.net/ows/2.0"
+   xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+   elementFormDefault="qualified"
+   version="3.0"
+   id="cswGetCapabilities">
+   <xsd:annotation>
+      <xsd:appinfo>
+         <dc:identifier xmlns:dc="http://purl.org/dc/elements/1.1/">http://schemas.opengis.net/csw/3.0/cswGetCapabilities.xsd</dc:identifier>
+      </xsd:appinfo>
+      <xsd:documentation xml:lang="en">
+         This schema defines the request and response messages
+         for the CSW 3.0 GetCapabilities operation.
+      </xsd:documentation>
+   </xsd:annotation>
+   <xsd:include schemaLocation="cswCommon.xsd"/>
+   <xsd:import namespace="http://www.opengis.net/ows/2.0"
+      schemaLocation="../../ows/2.0/owsAll.xsd"/>
+   <xsd:import namespace="http://www.opengis.net/fes/2.0"
+      schemaLocation="../../filter/2.0/filterAll.xsd"/>
+   <!-- =================================================================== -->
+   <!-- REQUEST                                                             -->
+   <!-- =================================================================== -->
+   <xsd:element name="GetCapabilities"
+                type="csw30:GetCapabilitiesType" id="GetCapabilities"/>
+   <xsd:complexType name="GetCapabilitiesType" id="GetCapabilitiesType">
+      <xsd:annotation>
+         <xsd:documentation>
+            Request for a description of service capabilities. See
+            OGC 06-121r9 for more information.
+         </xsd:documentation>
+      </xsd:annotation>
+      <xsd:complexContent>
+         <xsd:extension base="ows:GetCapabilitiesType">
+            <xsd:attribute name="service" type="ows:ServiceType"
+                           use="optional" default="CSW">
+               <xsd:annotation>
+                  <xsd:documentation>
+                     OGC service type identifier (CSW).
+                  </xsd:documentation>
+               </xsd:annotation>
+            </xsd:attribute>
+         </xsd:extension>
+      </xsd:complexContent>
+   </xsd:complexType>
+   <!-- =================================================================== -->
+   <!-- RESPONSE                                                            -->
+   <!-- =================================================================== -->
+   <xsd:element name="Capabilities"
+                type="csw30:CapabilitiesType" id="Capabilities"/>
+   <xsd:complexType name="CapabilitiesType" id="CapabilitiesType">
+      <xsd:annotation>
+         <xsd:documentation>
+            This type extends ows:CapabilitiesBaseType defined in OGC 06-121r9
+            to include information about supported OGC filter components. A
+            profile may extend this type to describe additional capabilities.
+         </xsd:documentation>
+      </xsd:annotation>
+      <xsd:complexContent>
+         <xsd:extension base="ows:CapabilitiesBaseType">
+            <xsd:sequence>
+               <xsd:annotation>
+                  <xsd:documentation>
+                     If sections parameter not specified, then
+                     Filter_Capabilities is mandatory. On full
+                     getCapabilities request, then all capabilities
+                     should be present. Document this in the specification,
+                     use annotation on minOccurs to make this point.
+                  </xsd:documentation>
+               </xsd:annotation>
+               <xsd:element ref="fes:Filter_Capabilities" minOccurs="0"/>
+            </xsd:sequence>
+         </xsd:extension>
+      </xsd:complexContent>
+   </xsd:complexType>
+</xsd:schema>
diff --git a/pycsw/core/schemas/ogc/csw/3.0/cswGetDomain.xsd b/pycsw/core/schemas/ogc/csw/3.0/cswGetDomain.xsd
new file mode 100644
index 0000000..3d434f3
--- /dev/null
+++ b/pycsw/core/schemas/ogc/csw/3.0/cswGetDomain.xsd
@@ -0,0 +1,146 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xsd:schema
+   targetNamespace="http://www.opengis.net/cat/csw/3.0"
+   xmlns:csw30="http://www.opengis.net/cat/csw/3.0"
+   xmlns:gml="http://www.opengis.net/gml/3.2"
+   xmlns:fes="http://www.opengis.net/fes/2.0"
+   xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+   elementFormDefault="qualified"
+   version="3.0"
+   id="cswGetDomain">
+   <xsd:annotation>
+      <xsd:appinfo>
+         <dc:identifier xmlns:dc="http://purl.org/dc/elements/1.1/">http://schemas.opengis.net/csw/3.0/cswGetDomain.xsd</dc:identifier>
+      </xsd:appinfo>
+      <xsd:documentation xml:lang="en">
+         This schema defines the request and response messages for the CSW 3.0
+         GetDomain operation.
+      </xsd:documentation>
+   </xsd:annotation>
+   <xsd:include schemaLocation="cswCommon.xsd"/>
+   <xsd:import namespace="http://www.opengis.net/gml/3.2"
+      schemaLocation="../../gml/3.2.1/gml.xsd"/>
+   <xsd:import namespace="http://www.opengis.net/fes/2.0"
+      schemaLocation="../../filter/2.0/filterAll.xsd"/>
+   <!-- =================================================================== -->
+   <!-- REQUEST                                                             -->
+   <!-- =================================================================== -->
+   <xsd:element name="GetDomain" type="csw30:GetDomainType" id="GetDomain"/>
+   <xsd:complexType name="GetDomainType" id="GetDomainType">
+      <xsd:complexContent>
+         <xsd:extension base="csw30:RequestBaseType">
+            <xsd:sequence maxOccurs="unbounded">
+               <xsd:choice>
+                  <xsd:sequence>
+                     <xsd:element name="ValueReference">
+                        <xsd:complexType>
+                           <xsd:simpleContent>
+                              <xsd:extension base="xsd:string">
+                                 <xsd:attribute name="resultType"
+                                                type="csw30:ResultTypeType"
+                                                use="optional"
+                                                default="available"/>
+                              </xsd:extension>
+                           </xsd:simpleContent>
+                        </xsd:complexType>
+                     </xsd:element>
+                     <xsd:element ref="fes:Filter" minOccurs="0"/>
+                  </xsd:sequence>
+                  <xsd:element name="ParameterName" type="xsd:string"/>
+               </xsd:choice>
+            </xsd:sequence>
+         </xsd:extension>
+      </xsd:complexContent>
+   </xsd:complexType>
+   <xsd:simpleType name="ResultTypeType">
+      <xsd:restriction base="xsd:string">
+         <xsd:enumeration value="possible">
+            <xsd:annotation>
+               <xsd:documentation>
+                  Returns the set of supported possible values
+                  for the specified data component.
+               </xsd:documentation>
+            </xsd:annotation>
+         </xsd:enumeration>
+         <xsd:enumeration value="available">
+            <xsd:annotation>
+               <xsd:documentation>
+                  Returns the set of available values for the
+                  specified data component.  This is typically
+                  a subset of the list of possible values.
+               </xsd:documentation>
+            </xsd:annotation>
+         </xsd:enumeration>
+      </xsd:restriction>
+   </xsd:simpleType>
+   <!-- =================================================================== -->
+   <!-- RESPONSE                                                            -->
+   <!-- =================================================================== -->
+   <xsd:element name="GetDomainResponse"
+                type="csw30:GetDomainResponseType" id="GetDomainResponse"/>
+   <xsd:complexType name="GetDomainResponseType" id="GetDomainResponseType">
+      <xsd:annotation>
+         <xsd:documentation xml:lang="en">
+            Returns the actual values for some property. In general this is
+            a subset of the value domain (that is, set of permissible values),
+            although in some cases these may be the same.
+         </xsd:documentation>
+      </xsd:annotation>
+      <xsd:sequence>
+         <xsd:element name="DomainValues"
+                      type="csw30:DomainValuesType" maxOccurs="unbounded"/>
+      </xsd:sequence>
+   </xsd:complexType>
+   <xsd:complexType name="DomainValuesType" id="DomainValuesType">
+      <xsd:sequence>
+         <xsd:choice>
+            <xsd:element name="ValueReference" type="xsd:string"/>
+            <xsd:element name="ParameterName" type="xsd:anyURI"/>
+         </xsd:choice>
+         <xsd:choice minOccurs="0">
+            <xsd:element name="ListOfValues"
+                         type="csw30:ListOfValuesType"/>
+            <xsd:element name="ConceptualScheme"
+                         type="csw30:ConceptualSchemeType"
+                         maxOccurs="unbounded"/>
+            <xsd:element name="RangeOfValues"
+                         type="csw30:RangeOfValuesType"/>
+         </xsd:choice>
+      </xsd:sequence>
+      <xsd:attribute name="type" type="xsd:QName" use="required"/>
+      <xsd:attribute name="resultType"
+                     type="csw30:ResultTypeType" use="required"/>
+        
+   </xsd:complexType>
+   <xsd:complexType name="ListOfValuesType" id="ListOfValuesType">
+      <xsd:sequence>
+         <xsd:element name="Value" maxOccurs="unbounded">
+            <xsd:complexType>
+               <xsd:complexContent>
+                  <xsd:extension base="xsd:anyType">
+                     <xsd:attribute name="isDefault" type="xsd:boolean"
+                                    use="optional" default="false"/>
+                     <xsd:attribute name="count" type="xsd:nonNegativeInteger"
+                                    use="optional"/>
+                     <xsd:attribute name="uom" type="gml:UomIdentifier"
+                                    use="optional"/>
+                  </xsd:extension>
+               </xsd:complexContent>
+            </xsd:complexType>
+         </xsd:element>
+      </xsd:sequence>
+   </xsd:complexType>
+   <xsd:complexType name="ConceptualSchemeType" id="ConceptualSchemeType">
+      <xsd:sequence>
+         <xsd:element name="Name" type="xsd:string"/>
+         <xsd:element name="Document" type="xsd:anyURI"/>
+         <xsd:element name="Authority" type="xsd:anyURI"/>
+      </xsd:sequence>
+   </xsd:complexType>
+   <xsd:complexType name="RangeOfValuesType" id="RangeOfValuesType">
+      <xsd:sequence>
+         <xsd:element name="MinValue" type="xsd:anyType" minOccurs="0"/>
+         <xsd:element name="MaxValue" type="xsd:anyType" minOccurs="0"/>
+      </xsd:sequence>
+   </xsd:complexType>
+</xsd:schema>
diff --git a/pycsw/core/schemas/ogc/csw/3.0/cswGetRecordById.xsd b/pycsw/core/schemas/ogc/csw/3.0/cswGetRecordById.xsd
new file mode 100644
index 0000000..b79cd38
--- /dev/null
+++ b/pycsw/core/schemas/ogc/csw/3.0/cswGetRecordById.xsd
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xsd:schema
+   targetNamespace="http://www.opengis.net/cat/csw/3.0"
+   xmlns:csw30="http://www.opengis.net/cat/csw/3.0"
+   xmlns:fes="http://www.opengis.net/fes/2.0"
+   xmlns:ows="http://www.opengis.net/ows/2.0"
+   xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+   elementFormDefault="qualified"
+   version="3.0"
+   id="cswGetRecordById">
+   <xsd:annotation>
+      <xsd:appinfo>
+         <dc:identifier xmlns:dc="http://purl.org/dc/elements/1.1/">http://schemas.opengis.net/csw/3.0/cswGetRecordsById.xsd</dc:identifier>
+      </xsd:appinfo>
+      <xsd:documentation xml:lang="en">
+         This schema defines the request messages for the CSW 3.0
+         GetRecordById  operation.
+      </xsd:documentation>
+   </xsd:annotation>
+   <xsd:include schemaLocation="cswCommon.xsd"/>
+   <xsd:include schemaLocation="cswGetRecords.xsd"/>
+   <xsd:import namespace="http://www.opengis.net/ows/2.0"
+               schemaLocation="../../ows/2.0/owsAll.xsd"/>
+   <!-- =================================================================== -->
+   <!-- REQUEST                                                             -->
+   <!-- =================================================================== -->
+   <xsd:element name="GetRecordById"
+                type="csw30:GetRecordByIdType" id="GetRecordById"/>
+   <xsd:complexType name="GetRecordByIdType" id="GetRecordByIdType">
+      <xsd:annotation>
+         <xsd:documentation xml:lang="en">
+            Convenience operation to retrieve default record representations 
+            by identifier.
+            Id - object identifier (a URI) that provides a reference to a 
+                 catalogue item (or a result set if the catalogue supports 
+                 persistent result sets).
+            ElementSetName - one of "brief, "summary", or "full"
+         </xsd:documentation>
+      </xsd:annotation>
+      <xsd:complexContent>
+         <xsd:extension base="csw30:RequestBaseType">
+            <xsd:sequence>
+               <xsd:element name="Id" type="xsd:anyURI"/>
+               <xsd:element ref="csw30:ElementSetName" minOccurs="0"/>
+            </xsd:sequence>
+            <xsd:attribute name="outputFormat" type="xsd:string"
+                           use="optional" default="application/xml"/>
+            <xsd:attribute name="outputSchema" type="xsd:anyURI"
+                           use="optional"/>
+         </xsd:extension>
+      </xsd:complexContent>
+   </xsd:complexType>
+   <!-- =================================================================== -->
+   <!-- RESPONSE                                                            -->
+   <!-- The response depends on the values of the outputFormat and output   -->
+   <!-- schema parameters.                                                  -->
+   <!-- =================================================================== -->
+</xsd:schema>
diff --git a/pycsw/core/schemas/ogc/csw/3.0/cswGetRecords.xsd b/pycsw/core/schemas/ogc/csw/3.0/cswGetRecords.xsd
new file mode 100644
index 0000000..c001e4d
--- /dev/null
+++ b/pycsw/core/schemas/ogc/csw/3.0/cswGetRecords.xsd
@@ -0,0 +1,391 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xsd:schema
+   targetNamespace="http://www.opengis.net/cat/csw/3.0"
+   xmlns:csw30="http://www.opengis.net/cat/csw/3.0"
+   xmlns:fes="http://www.opengis.net/fes/2.0"
+   xmlns:ows="http://www.opengis.net/ows/2.0"
+   xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+   elementFormDefault="qualified"
+   version="3.0"
+   id="cswGetRecords">
+   <xsd:annotation>
+      <xsd:appinfo>
+         <dc:identifier xmlns:dc="http://purl.org/dc/elements/1.1/">http://schemas.opengis.net/csw/3.0/cswGetRecords.xsd</dc:identifier>
+      </xsd:appinfo>
+      <xsd:documentation xml:lang="en">
+         This schema defines the request and response messages for the CSW 3.0
+         GetRecords operation.
+      </xsd:documentation>
+   </xsd:annotation>
+   <xsd:include schemaLocation="cswCommon.xsd"/>
+   <xsd:import namespace="http://www.opengis.net/ows/2.0"
+      schemaLocation="../../ows/2.0/owsAll.xsd"/>
+   <xsd:import namespace="http://www.opengis.net/fes/2.0"
+      schemaLocation="../../filter/2.0/filterAll.xsd"/>
+   <!-- =================================================================== -->
+   <!-- REQUEST                                                             -->
+   <!-- =================================================================== -->
+   <xsd:element name="GetRecords" type="csw30:GetRecordsType" id="GetRecords"/>
+   <xsd:complexType name="GetRecordsType" id="GetRecordsType">
+      <xsd:annotation>
+         <xsd:documentation xml:lang="en">
+            The principal means of searching the catalogue. The matching
+            catalogue entries may be included with the response. The client
+            may assign a requestId (absolute URI). A distributed search is
+            performed if the DistributedSearch element is present and the
+            catalogue is a member of a federation. Profiles may allow
+            alternative query expressions.
+         </xsd:documentation>
+      </xsd:annotation>
+      <xsd:complexContent>
+         <xsd:extension base="csw30:RequestBaseType">
+            <xsd:sequence>
+               <xsd:element name="DistributedSearch"
+                  type="csw30:DistributedSearchType" minOccurs="0"/>
+               <xsd:element name="ResponseHandler" type="xsd:anyURI"
+                  minOccurs="0" maxOccurs="unbounded"/>
+               <xsd:choice>
+                  <xsd:element ref="csw30:AbstractQuery"/>
+                  <xsd:any namespace="##other" processContents="strict"/>
+               </xsd:choice>
+            </xsd:sequence>
+            <xsd:attribute name="requestId" type="xsd:anyURI" use="optional">
+               <xsd:annotation>
+                  <xsd:documentation xml:lang="en">
+                     requestId becomes mandatory in the case of a distributed
+                     search. Must be a unique Id (i.e. a UUID).
+                  </xsd:documentation>
+               </xsd:annotation>
+            </xsd:attribute>
+            <xsd:attributeGroup ref="csw30:BasicRetrievalOptions"/>
+         </xsd:extension>
+      </xsd:complexContent>
+   </xsd:complexType>
+   <xsd:attributeGroup name="BasicRetrievalOptions" id="BasicRetrievalOptions">
+      <xsd:annotation>
+         <xsd:documentation xml:lang="en">
+            Various attributes that specify basic retrieval options:
+            outputFormat   - the media type of the response message
+            outputSchema   - the preferred schema for records in the result set
+            startPosition  - requests a slice of the result set, starting
+                             at this position
+            maxRecords     - the maximum number of records to return. No
+                             records are  returned if maxRecords=0.
+         </xsd:documentation>
+      </xsd:annotation>
+      <xsd:attribute name="outputFormat" type="xsd:string"
+                     use="optional" default="application/xml"/>
+      <xsd:attribute name="outputSchema" type="xsd:anyURI" use="optional"/>
+      <xsd:attribute name="startPosition" type="xsd:positiveInteger"
+                     use="optional" default="1"/>
+      <xsd:attribute name="maxRecords" type="csw30:MaxRecordsType"
+                     use="optional" default="10"/>
+   </xsd:attributeGroup>
+   <xsd:simpleType name="MaxRecordsType">
+      <xsd:union memberTypes="xsd:nonNegativeInteger csw30:UnlimitedStringType"/>
+   </xsd:simpleType>
+   <xsd:simpleType name="UnlimitedStringType">
+      <xsd:restriction base="xsd:string">
+         <xsd:enumeration value="unlimited"/>
+      </xsd:restriction>
+   </xsd:simpleType>
+   <xsd:complexType name="DistributedSearchType" id="DistributedSearchType">
+      <xsd:annotation>
+         <xsd:documentation xml:lang="en">
+            Governs the behaviour of a distributed search.
+            hopCount     - the maximum number of message hops before
+                           the search is terminated. Each catalogue node 
+                           decrements this value when the request is received, 
+                           and must not forward the request if hopCount=0.
+         </xsd:documentation>
+      </xsd:annotation>
+      <xsd:sequence>
+         <xsd:element name="federatedCatalogues"
+                      type="csw30:FederatedCatalogueType"
+                      minOccurs="0" maxOccurs="unbounded">
+            <xsd:annotation>
+               <xsd:documentation xml:lang="en">
+                  To restrict the number of catalogues of a federation which
+                  should be searched upon an optional list of those catalogues
+                  can be provided within the federatedCatatalogues parameter.
+               </xsd:documentation>
+            </xsd:annotation>
+         </xsd:element>
+      </xsd:sequence>
+      <xsd:attribute name="hopCount" type="xsd:positiveInteger"
+                     use="optional" default="2"/>
+      <xsd:attribute name="clientId" type="xsd:anyURI" use="required">
+         <xsd:annotation>
+            <xsd:documentation>
+               An Id which uniquely identifies the requestor.
+            </xsd:documentation>
+         </xsd:annotation>
+      </xsd:attribute>
+      <xsd:attribute name="distributedSearchId"
+                     type="xsd:anyURI" use="required">
+         <xsd:annotation>
+            <xsd:documentation>
+               Id which uniquely identifies a complete client initiated
+               distributed search sequence/session.
+            </xsd:documentation>
+         </xsd:annotation>
+      </xsd:attribute>
+      <xsd:attribute name="distributedSearchIdTimout" type="xsd:unsignedLong"
+                     use="optional" default="600">
+         <xsd:annotation>
+            <xsd:documentation>
+               Defines how long (sec) the distributedSearchId should be valid,
+               meaning how long a server involved in distributed search should
+               minimally store information related to the distributedSearchId.
+            </xsd:documentation>
+         </xsd:annotation>
+      </xsd:attribute>
+   </xsd:complexType>
+   <xsd:complexType name="FederatedCatalogueType" id="FederatedCatalogueType">
+      <xsd:attribute name="catalogueURL" type="xsd:anyURI" use="required"/>
+      <xsd:attribute name="timeout" type="xsd:unsignedLong" use="optional">
+         <xsd:annotation>
+            <xsd:documentation>
+               For every catalogue in this list an optional timeout definition
+               (in msec) can be provided.
+            </xsd:documentation>
+         </xsd:annotation>
+      </xsd:attribute>
+   </xsd:complexType>
+   <xsd:element name="AbstractQuery" type="csw30:AbstractQueryType"
+                abstract="true" id="AbstractQuery"/>
+   <xsd:complexType name="AbstractQueryType" abstract="true"
+                    id="AbstractQueryType"/>
+   <xsd:element name="Query" type="csw30:QueryType"
+                substitutionGroup="csw30:AbstractQuery" id="Query"/>
+   <xsd:complexType name="QueryType" id="QueryType">
+      <xsd:annotation>
+         <xsd:documentation xml:lang="en">
+            Specifies a query to execute against instances of one or
+            more object types. A set of ElementName elements may be included 
+            to specify an adhoc view of the csw30:Record instances in the
+            result set. Otherwise, use ElementSetName to specify a predefined
+            view.  The Constraint element contains a query filter expressed
+            in a supported query language. A sorting criterion that specifies
+            a property to sort by may be included.
+
+            typeNames - a list of object types to query.
+         </xsd:documentation>
+      </xsd:annotation>
+      <xsd:complexContent>
+         <xsd:extension base="csw30:AbstractQueryType">
+            <xsd:sequence>
+               <xsd:choice>
+                  <xsd:element ref="csw30:ElementSetName"/>
+                  <xsd:element name="ElementName" type="xsd:string"
+                               maxOccurs="unbounded"/>
+               </xsd:choice>
+               <xsd:element ref="csw30:Constraint" minOccurs="0"/>
+               <xsd:element ref="fes:SortBy" minOccurs="0"/>
+            </xsd:sequence>
+            <xsd:attribute name="typeNames" type="csw30:TypeNameListType"
+                           use="required"/>
+         </xsd:extension>
+      </xsd:complexContent>
+   </xsd:complexType>
+   <xsd:simpleType name="TypeNameListType" id="TypeNameListType">
+      <xsd:annotation>
+         <xsd:documentation xml:lang="en">
+            The exact syntax is defined in an application profile. If querying 
+            against the common record properties, only a single type may be 
+            specified (Record).
+         </xsd:documentation>
+      </xsd:annotation>
+      <xsd:list itemType="xsd:QName"/>
+   </xsd:simpleType>
+   <xsd:element name="Constraint"
+                type="csw30:QueryConstraintType" id="Constraint"/>
+   <xsd:complexType name="QueryConstraintType" id="QueryConstraintType">
+      <xsd:annotation>
+         <xsd:documentation xml:lang="en">
+            A search constraint that adheres to one of the following syntaxes:
+            Filter   - OGC filter expression
+            CqlText  - OGC CQL predicate
+         </xsd:documentation>
+      </xsd:annotation>
+      <xsd:choice>
+         <xsd:element ref="fes:Filter"/>
+         <xsd:element name="CqlText" type="xsd:string"/>
+      </xsd:choice>
+      <xsd:attribute name="version" type="xsd:string" use="required">
+         <xsd:annotation>
+            <xsd:documentation>Query language version</xsd:documentation>
+         </xsd:annotation>
+      </xsd:attribute>
+   </xsd:complexType>
+   <xsd:element name="ElementSetName"
+                type="csw30:ElementSetNameType" id="ElementSetName"/>
+   <xsd:complexType name="ElementSetNameType" id="ElementSetNameType">
+      <xsd:simpleContent>
+         <xsd:extension base="csw30:ElementSetType">
+            <xsd:attribute name="typeNames"
+                           type="csw30:TypeNameListType" use="optional"/>
+         </xsd:extension>
+      </xsd:simpleContent>
+   </xsd:complexType>
+   <xsd:simpleType name="RequiredElementSetNamesType"
+                   id="RequiredElementSetNamesType">
+      <xsd:annotation>
+         <xsd:documentation>
+             Named subsets of catalogue object properties; these
+             views are mapped to a specific information model and
+             are defined in an application profile.
+         </xsd:documentation>
+      </xsd:annotation>
+      <xsd:restriction base="xsd:string">
+         <xsd:enumeration value="brief"/>
+         <xsd:enumeration value="summary"/>
+         <xsd:enumeration value="full"/>
+      </xsd:restriction>
+   </xsd:simpleType>
+   <xsd:simpleType name="ElementSetType">
+      <xsd:union memberTypes="xsd:string csw30:RequiredElementSetNamesType"/>
+   </xsd:simpleType>
+   <!-- =================================================================== -->
+   <!-- RESPONSE                                                            -->
+   <!-- =================================================================== -->
+   <xsd:element name="GetRecordsResponse"
+                type="csw30:GetRecordsResponseType" id="GetRecordsResponse"/>
+   <xsd:complexType name="GetRecordsResponseType">
+      <xsd:annotation>
+         <xsd:documentation xml:lang="en">
+            The response message for a GetRecords request. Some or all of the 
+            matching records may be included as children of the SearchResults 
+            element. The RequestId is only included if the client specified it.
+         </xsd:documentation>
+      </xsd:annotation>
+      <xsd:sequence>
+         <xsd:element name="RequestId" type="xsd:anyURI" minOccurs="0"/>
+         <xsd:element name="SearchStatus" type="csw30:RequestStatusType"/>
+         <xsd:element name="SearchResults" type="csw30:SearchResultsType"/>
+      </xsd:sequence>
+      <xsd:attribute name="version" type="xsd:string" use="optional"/>
+   </xsd:complexType>
+   <xsd:complexType name="RequestStatusType" id="RequestStatusType">
+      <xsd:annotation>
+         <xsd:documentation>
+            This element provides information about the status of the
+            search request.
+
+            status    - status of the search
+            timestamp - the date and time when the result set was modified 
+                        (ISO 8601 format: YYYY-MM-DDThh:mm:ss[+|-]hh:mm).
+         </xsd:documentation>
+      </xsd:annotation>
+      <xsd:attribute name="timestamp" type="xsd:dateTime" use="optional"/>
+   </xsd:complexType>
+   <xsd:simpleType name="ResultsStatusType" id="ResultsStatusType">
+      <xsd:annotation>
+         <xsd:documentation>
+            status of the items included in the resultset: 
+	    complete (all items found are included),
+            subset (subset of items found are included, but no further
+                    items in the requested range startPosition/maxRecords
+                    are available), 
+            processing (subset of items found are included, but server
+                        further processing to get the outstanding items
+                        in the requested range startPosition/maxRecords), 
+            none (no items are included).
+         </xsd:documentation>
+      </xsd:annotation>
+      <xsd:restriction base="xsd:string">
+         <xsd:enumeration value="subset"/>
+         <xsd:enumeration value="complete"/>
+         <xsd:enumeration value="processing"/>
+         <xsd:enumeration value="none"/>
+      </xsd:restriction>
+   </xsd:simpleType>
+   <xsd:complexType name="SearchResultsType" id="SearchResultsType">
+      <xsd:annotation>
+         <xsd:documentation>
+            Includes representations of result set members if maxRecords > 0.
+            The items must conform to one of the csw30:Record views or a 
+            profile-specific representation. 
+         
+            resultSetId             - id of the result set (a URI).
+            elementSet              - The element set that has been returned
+                                      (e.g., "brief", "summary", "full")
+            recordSchema            - schema reference for included records(URI)
+            numberOfRecordsMatched  - number of records matched by the query
+            numberOfRecordsReturned - number of records returned to client
+            nextRecord              - position of next record in the result set
+                                      (0 if no records remain).
+            expires                 - the time instant when the result set
+                                      expires and is discarded (ISO8601 format)
+            elapsedTime             - runtime information of the search
+                                      within the federated catalogue
+         </xsd:documentation>
+      </xsd:annotation>
+      <xsd:sequence>
+         <xsd:choice>
+            <xsd:element ref="csw30:AbstractRecord"
+                         minOccurs="0" maxOccurs="unbounded"/>
+            <xsd:any namespace="##other" processContents="strict"
+                     minOccurs="0" maxOccurs="unbounded"/>
+         </xsd:choice>
+         <xsd:element ref="csw30:FederatedSearchResultBase"
+                      minOccurs="0" maxOccurs="unbounded"/>
+      </xsd:sequence>
+      <xsd:attribute name="resultSetId"
+                     type="xsd:anyURI" use="optional"/>
+      <xsd:attribute name="elementSet"
+                     type="csw30:ElementSetType" use="optional"/>
+      <xsd:attribute name="recordSchema"
+                     type="xsd:anyURI" use="optional"/>
+      <xsd:attribute name="numberOfRecordsMatched"
+                     type="xsd:nonNegativeInteger" use="required"/>
+      <xsd:attribute name="numberOfRecordsReturned"
+                     type="xsd:nonNegativeInteger" use="required"/>
+      <xsd:attribute name="nextRecord"
+                     type="xsd:nonNegativeInteger" use="optional"/>
+      <xsd:attribute name="expires" type="xsd:dateTime" use="optional"/>
+      <xsd:attribute name="elapsedTime" type="xsd:unsignedLong" use="optional"/>
+      <xsd:attribute name="status" type="csw30:ResultsStatusType"
+                     use="optional" default="subset"/>
+   </xsd:complexType>
+   <xsd:element name="FederatedSearchResultBase"
+                type="csw30:FederatedSearchResultBaseType"
+                abstract="true" id="FederatedSearchResultBase"/>
+   <xsd:complexType name="FederatedSearchResultBaseType"
+                    abstract="true" id="FederatedSearchResultBaseType">
+      <xsd:attribute name="catalogueURL" type="xsd:anyURI" use="required">
+         <xsd:annotation>
+            <xsd:documentation>
+               The URL-prefix of the getCapabilities HTTP-GET operation
+               of the catalogue.
+            </xsd:documentation>
+         </xsd:annotation>
+      </xsd:attribute>
+   </xsd:complexType>
+   <xsd:element name="FederatedSearchResult"
+                type="csw30:FederatedSearchResultType"
+                substitutionGroup="csw30:FederatedSearchResultBase"
+                id="FederatedSearchResult"/>
+   <xsd:complexType name="FederatedSearchResultType"
+                    id="FederatedSearchResultType">
+      <xsd:complexContent>
+         <xsd:extension base="csw30:FederatedSearchResultBaseType">
+            <xsd:sequence>
+               <xsd:element name="searchResult" type="csw30:SearchResultsType"/>
+            </xsd:sequence>
+         </xsd:extension>
+      </xsd:complexContent>
+   </xsd:complexType>
+   <xsd:element name="FederatedException" type="csw30:FederatedExceptionType"
+                substitutionGroup="csw30:FederatedSearchResultBase"
+                id="FederatedException"/>
+   <xsd:complexType name="FederatedExceptionType" id="FederatedExceptionType">
+      <xsd:complexContent>
+         <xsd:extension base="csw30:FederatedSearchResultBaseType">
+            <xsd:sequence>
+               <xsd:element ref="ows:ExceptionReport" maxOccurs="unbounded"/>
+            </xsd:sequence>
+         </xsd:extension>
+      </xsd:complexContent>
+   </xsd:complexType>
+</xsd:schema>
diff --git a/pycsw/core/schemas/ogc/csw/3.0/cswHarvest.xsd b/pycsw/core/schemas/ogc/csw/3.0/cswHarvest.xsd
new file mode 100644
index 0000000..d4fb171
--- /dev/null
+++ b/pycsw/core/schemas/ogc/csw/3.0/cswHarvest.xsd
@@ -0,0 +1,95 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xsd:schema
+   targetNamespace="http://www.opengis.net/cat/csw/3.0"
+   xmlns:csw30="http://www.opengis.net/cat/csw/3.0"
+   xmlns:fes="http://www.opengis.net/fes/2.0"
+   xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+   elementFormDefault="qualified"
+   version="3.0"
+   id="cswHarvest">
+   <xsd:annotation>
+      <xsd:appinfo>
+         <dc:identifier xmlns:dc="http://purl.org/dc/elements/1.1/">http://schemas.opengis.net/csw/3.0/cswHarvest.xsd</dc:identifier>
+      </xsd:appinfo>
+      <xsd:documentation xml:lang="en">
+         This schema defines the request and response messages for the 
+         Harvest operation.
+      </xsd:documentation>
+   </xsd:annotation>
+   <xsd:include schemaLocation="cswCommon.xsd"/>
+   <xsd:include schemaLocation="cswTransaction.xsd"/>
+   <xsd:import namespace="http://www.opengis.net/fes/2.0"
+        schemaLocation="../../filter/2.0/filterAll.xsd"/>
+   <!-- =================================================================== -->
+   <!-- REQUEST                                                             -->
+   <!-- =================================================================== -->
+   <xsd:element name="Harvest" type="csw30:HarvestType" id="Harvest"/>
+   <xsd:complexType name="HarvestType">
+      <xsd:annotation>
+         <xsd:documentation xml:lang="en">
+            Requests that the catalogue attempt to harvest a resource from some 
+            network location identified by the source URL.
+   
+            Source          - a URL from which the resource is retrieved
+            ResourceType    - normally a URI that specifies the type of the
+                              resource being harvested
+            ResourceFormat  - a media type indicating the format of the 
+                              resource being harvested.  The default is 
+                              "application/xml".
+            ResponseHandler - a reference to some endpoint to which the 
+                              response shall be forwarded when the
+                              harvest operation has been completed
+            HarvestInterval - an interval expressed using the ISO 8601 syntax; 
+                              it specifies the interval between harvest 
+                              attempts (e.g., P6M indicates an interval of 
+                              six months).
+         </xsd:documentation>
+      </xsd:annotation>
+      <xsd:complexContent>
+         <xsd:extension base="csw30:RequestBaseType">
+            <xsd:sequence>
+               <xsd:element name="Source" type="xsd:anyURI"/>
+               <xsd:element name="ResourceType" type="xsd:string"/>
+               <xsd:element name="ResourceFormat" type="xsd:string"
+                            default="application/xml" minOccurs="0"/>
+               <xsd:element name="HarvestInterval" type="xsd:duration"
+                            minOccurs="0"/>
+               <xsd:element name="ResponseHandler" type="xsd:anyURI"
+                            minOccurs="0" maxOccurs="unbounded"/>
+            </xsd:sequence>
+         </xsd:extension>
+      </xsd:complexContent>
+   </xsd:complexType>
+   <!-- =================================================================== -->
+   <!-- RESPONSE                                                            -->
+   <!-- =================================================================== -->
+   <xsd:element name="HarvestResponse" type="csw30:HarvestResponseType"
+      id="HarvestResponse">
+      <xsd:annotation>
+         <xsd:documentation xml:lang="en">
+            The content of the response varies depending on the presence of the 
+            ResponseHandler element. If present, then the catalogue should 
+            verify the request and respond immediately with an
+            csw30:Acknowledgement element in the response. The catalogue must
+            then attempt to harvest the resource at some later time and send
+            the response message to the location specified by the value of the
+            ResponseHandler element using the indicated protocol (e.g. ftp,
+            mailto, http).
+         
+            If the ResponseHandler element is absent, then the catalogue 
+            must attempt to harvest the resource immediately and include a 
+            TransactionResponse element in the response.
+
+            In any case, if the harvest attempt is successful the response 
+            shall include summary representations of the newly created 
+            catalogue item(s).
+         </xsd:documentation>
+      </xsd:annotation>
+   </xsd:element>
+   <xsd:complexType name="HarvestResponseType" id="HarvestResponseType">
+      <xsd:choice>
+         <xsd:element ref="csw30:Acknowledgement"/>
+         <xsd:element ref="csw30:TransactionResponse"/>
+      </xsd:choice>
+   </xsd:complexType>
+</xsd:schema>
diff --git a/pycsw/core/schemas/ogc/csw/3.0/cswTransaction.xsd b/pycsw/core/schemas/ogc/csw/3.0/cswTransaction.xsd
new file mode 100644
index 0000000..04874ad
--- /dev/null
+++ b/pycsw/core/schemas/ogc/csw/3.0/cswTransaction.xsd
@@ -0,0 +1,187 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xsd:schema
+   targetNamespace="http://www.opengis.net/cat/csw/3.0"
+   xmlns:csw30="http://www.opengis.net/cat/csw/3.0"
+   xmlns:fes="http://www.opengis.net/fes/2.0"
+   xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+   elementFormDefault="qualified"
+   version="3.0"
+   id="cswTransaction">
+   <xsd:annotation>
+      <xsd:appinfo>
+         <dc:identifier xmlns:dc="http://purl.org/dc/elements/1.1/">http://schemas.opengis.net/csw/3.0/cswTransaction.xsd</dc:identifier>
+      </xsd:appinfo>
+      <xsd:documentation xml:lang="en">
+         This schema defines the request and response messages for the
+         Transaction operation.
+      </xsd:documentation>
+   </xsd:annotation>
+   <xsd:include schemaLocation="cswCommon.xsd"/>
+   <xsd:include schemaLocation="cswGetRecords.xsd"/>
+   <xsd:import namespace="http://www.opengis.net/fes/2.0"
+        schemaLocation="../../filter/2.0/filterAll.xsd"/>
+   <!-- =================================================================== -->
+   <!-- REQUEST                                                             -->
+   <!-- =================================================================== -->
+   <xsd:element name="Transaction"
+                type="csw30:TransactionType" id="Transaction"/>
+   <xsd:complexType name="TransactionType" id="TransactionType">
+      <xsd:annotation>
+         <xsd:documentation xml:lang="en">
+            Users may insert, update, or delete catalogue entries. If the 
+            verboseResponse attribute has the value "true", then one or more 
+            csw30:InsertResult elements must be included in the response.
+         </xsd:documentation>
+      </xsd:annotation>
+      <xsd:complexContent>
+         <xsd:extension base="csw30:RequestBaseType">
+            <xsd:sequence>
+               <xsd:choice maxOccurs="unbounded">
+                  <xsd:element name="Insert" type="csw30:InsertType"/>
+                  <xsd:element name="Update" type="csw30:UpdateType"/>
+                  <xsd:element name="Delete" type="csw30:DeleteType"/>
+               </xsd:choice>
+            </xsd:sequence>
+            <xsd:attribute name="verboseResponse" type="xsd:boolean"
+                           use="optional" default="false"/>
+            <xsd:attribute name="requestId" type="xsd:anyURI" use="optional"/>
+         </xsd:extension>
+      </xsd:complexContent>
+   </xsd:complexType>
+   <xsd:complexType name="InsertType" id="InsertType">
+      <xsd:annotation>
+         <xsd:documentation xml:lang="en">
+            Submits one or more records to the catalogue. The representation
+            is defined by the application profile. The handle attribute
+            may be included to specify a local identifier for the action 
+            (it must be unique within the context of the transaction).
+         </xsd:documentation>
+      </xsd:annotation>
+      <xsd:sequence>
+         <xsd:any namespace="##other" processContents="strict"
+                  maxOccurs="unbounded"/>
+      </xsd:sequence>
+      <xsd:attribute name="typeName" type="xsd:QName" use="optional"/>
+      <xsd:attribute name="handle" type="xsd:ID" use="optional"/>
+   </xsd:complexType>
+   <xsd:complexType name="UpdateType" id="UpdateType">
+      <xsd:annotation>
+         <xsd:documentation xml:lang="en">
+            Update statements may replace an entire record or only update part 
+            of a record:
+            1) To replace an existing record, include a new instance of the 
+               record;
+            2) To update selected properties of an existing record, include
+               a set of RecordProperty elements. The scope of the update
+               statement  is determined by the Constraint element.
+               The 'handle' is a local identifier for the action.
+         </xsd:documentation>
+      </xsd:annotation>
+      <xsd:sequence>
+         <xsd:choice>
+            <xsd:any namespace="##other" processContents="strict"/>
+            <xsd:sequence>
+               <xsd:element ref="csw30:RecordProperty" maxOccurs="unbounded"/>
+               <xsd:element ref="csw30:Constraint"/>
+            </xsd:sequence>
+         </xsd:choice>
+      </xsd:sequence>
+      <xsd:attribute name="typeName" type="xsd:QName" use="optional"/>
+      <xsd:attribute name="handle" type="xsd:ID" use="optional"/>
+   </xsd:complexType>
+   <xsd:complexType name="DeleteType" id="DeleteType">
+      <xsd:annotation>
+         <xsd:documentation xml:lang="en">
+            Deletes one or more catalogue items that satisfy some set of 
+            conditions.
+         </xsd:documentation>
+      </xsd:annotation>
+      <xsd:sequence>
+         <xsd:element ref="csw30:Constraint"/>
+      </xsd:sequence>
+      <xsd:attribute name="typeName" type="xsd:QName" use="optional"/>
+      <xsd:attribute name="handle" type="xsd:ID" use="optional"/>
+   </xsd:complexType>
+   <xsd:element name="RecordProperty" type="csw30:RecordPropertyType">
+      <xsd:annotation>
+         <xsd:documentation>
+            The RecordProperty element is used to specify the new
+            value of a record property in an update statement.
+         </xsd:documentation>
+      </xsd:annotation>
+   </xsd:element>
+   <xsd:complexType name="RecordPropertyType">
+      <xsd:sequence>
+         <xsd:element name="Name" type="xsd:string">
+            <xsd:annotation>
+               <xsd:documentation>
+                  The Name element contains the name of a property
+                  to be updated.  The name may be a path expression.
+               </xsd:documentation>
+            </xsd:annotation>
+         </xsd:element>
+         <xsd:element name="Value" type="xsd:anyType" minOccurs="0">
+            <xsd:annotation>
+               <xsd:documentation>
+                  The Value element contains the replacement value for the
+                  named property.
+               </xsd:documentation>
+            </xsd:annotation>
+         </xsd:element>
+      </xsd:sequence>
+   </xsd:complexType>
+   <!-- =================================================================== -->
+   <!-- RESPONSE                                                            -->
+   <!-- =================================================================== -->
+   <xsd:element name="TransactionResponse"
+                type="csw30:TransactionResponseType" id="TransactionResponse"/>
+   <xsd:complexType name="TransactionResponseType">
+      <xsd:annotation>
+         <xsd:documentation xml:lang="en">
+            The response for a transaction request that was successfully
+            completed. If the transaction failed for any reason, a service 
+            exception report indicating a TransactionFailure is returned
+            instead.
+         </xsd:documentation>
+      </xsd:annotation>
+      <xsd:sequence>
+         <xsd:element name="TransactionSummary"
+                      type="csw30:TransactionSummaryType"/>
+         <xsd:element name="InsertResult" type="csw30:InsertResultType"
+                      minOccurs="0" maxOccurs="unbounded"/>
+      </xsd:sequence>
+      <xsd:attribute name="version" type="xsd:string" use="optional"/>
+   </xsd:complexType>
+   <xsd:complexType name="TransactionSummaryType" id="TransactionSummaryType">
+      <xsd:annotation>
+         <xsd:documentation xml:lang="en">
+            Reports the total number of catalogue items modified by a
+            transaction request (i.e, inserted, updated, deleted).
+            If the client did not specify a requestId, the server may
+            assign one (a URI value).
+         </xsd:documentation>
+      </xsd:annotation>
+      <xsd:sequence>
+         <xsd:element name="totalInserted" type="xsd:nonNegativeInteger"
+                      minOccurs="0"/>
+         <xsd:element name="totalUpdated" type="xsd:nonNegativeInteger"
+                      minOccurs="0"/>
+         <xsd:element name="totalDeleted" type="xsd:nonNegativeInteger"
+                      minOccurs="0"/>
+      </xsd:sequence>
+      <xsd:attribute name="requestId" type="xsd:anyURI" use="optional"/>
+   </xsd:complexType>
+   <xsd:complexType name="InsertResultType" id="InsertResultType">
+      <xsd:annotation>
+         <xsd:documentation xml:lang="en">
+            Returns a "brief" view of any newly created catalogue records.
+            The handle attribute may reference a particular statement in
+            the corresponding transaction request.
+         </xsd:documentation>
+      </xsd:annotation>
+      <xsd:sequence>
+         <xsd:element ref="csw30:BriefRecord" maxOccurs="unbounded"/>
+      </xsd:sequence>
+      <xsd:attribute name="handleRef" type="xsd:anyURI" use="optional"/>
+   </xsd:complexType>
+</xsd:schema>
diff --git a/pycsw/core/schemas/ogc/csw/3.0/cswUnHarvest.xsd b/pycsw/core/schemas/ogc/csw/3.0/cswUnHarvest.xsd
new file mode 100644
index 0000000..1d8ca13
--- /dev/null
+++ b/pycsw/core/schemas/ogc/csw/3.0/cswUnHarvest.xsd
@@ -0,0 +1,77 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xsd:schema
+   targetNamespace="http://www.opengis.net/cat/csw/3.0"
+   xmlns:csw30="http://www.opengis.net/cat/csw/3.0"
+   xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+   elementFormDefault="qualified"
+   version="3.0"
+   id="cswUnHarvest">
+   <xsd:annotation>
+      <xsd:appinfo>
+         <dc:identifier xmlns:dc="http://purl.org/dc/elements/1.1/">http://schemas.opengis.net/csw/3.0/cswUnHarvest.xsd</dc:identifier>
+      </xsd:appinfo>
+      <xsd:documentation xml:lang="en">
+         This schema defines the request and response messages for the
+         UnHarvest operation.
+      </xsd:documentation>
+   </xsd:annotation>
+   <xsd:include schemaLocation="cswCommon.xsd"/>
+   <!-- =================================================================== -->
+   <!-- REQUEST                                                             -->
+   <!-- =================================================================== -->
+   <xsd:element name="Source" type="csw30:SourceType" id="SourceType"/>
+   <xsd:complexType name="SourceType">
+      <xsd:simpleContent>
+         <xsd:extension base="xsd:anyURI">
+            <xsd:attribute name="resourceType"
+                           type="xsd:anyURI" use="required"/>
+         </xsd:extension>
+      </xsd:simpleContent>
+   </xsd:complexType>
+   <xsd:element name="UnHarvest" type="csw30:UnHarvestType" id="UnHarvest"/>
+   <xsd:complexType name="UnHarvestType">
+      <xsd:annotation>
+         <xsd:documentation xml:lang="en">
+            Requests that the CSW unharvest a resource from the catalogue.
+            The resource to unharvest is identified by its source URL
+            (which must match exactly) and its resource type.
+
+            Source          - URL of the resourse to unharvest (must
+                              match exactly; including case)
+            ResourceType    - normally a URI that specifies the type of
+                              the resource being unharvested.
+            ResponseHandler - a reference to some endpoint to which the 
+                              response shall be forwarded when the
+                              unharvest operation has been completed
+         </xsd:documentation>
+      </xsd:annotation>
+      <xsd:complexContent>
+         <xsd:extension base="csw30:RequestBaseType">
+            <xsd:sequence>
+               <xsd:element ref="csw30:Source" maxOccurs="unbounded"/>
+               <xsd:element name="ResponseHandler" type="xsd:anyURI"
+                            minOccurs="0" maxOccurs="unbounded"/>
+            </xsd:sequence>
+            <xsd:attribute name="outputFormat" type="xsd:string"
+                           default="text/xml"/>
+         </xsd:extension>
+      </xsd:complexContent>
+   </xsd:complexType>
+   <!-- =================================================================== -->
+   <!-- RESPONSE                                                            -->
+   <!-- =================================================================== -->
+   <xsd:element name="UnHarvestResponse" type="csw30:UnHarvestResponseType"
+      id="UnHarvestResponse">
+      <xsd:annotation>
+         <xsd:documentation xml:lang="en">
+            The response to an UnHarvest request is simply a list of
+            csw30:Source elements echoing what has been unharvested.
+         </xsd:documentation>
+      </xsd:annotation>
+   </xsd:element>
+   <xsd:complexType name="UnHarvestResponseType" id="UnHarvestResponseType">
+      <xsd:sequence>
+         <xsd:element ref="csw30:Source" maxOccurs="unbounded"/>
+      </xsd:sequence>
+   </xsd:complexType>
+</xsd:schema>
diff --git a/pycsw/core/schemas/ogc/csw/3.0/rec-dcmes.xsd b/pycsw/core/schemas/ogc/csw/3.0/rec-dcmes.xsd
new file mode 100644
index 0000000..7eeef0d
--- /dev/null
+++ b/pycsw/core/schemas/ogc/csw/3.0/rec-dcmes.xsd
@@ -0,0 +1,245 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xs:schema
+   targetNamespace="http://purl.org/dc/elements/1.1/"
+   xmlns:xs="http://www.w3.org/2001/XMLSchema"
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   elementFormDefault="qualified"
+   attributeFormDefault="unqualified"
+   version="3.0"
+   id="rec-dcmes">
+   <xs:annotation>
+      <xs:documentation source="http://dublincore.org/documents/dces/"
+         xml:lang="en">
+         This schema declares XML elements for the 15 Dublin Core elements in 
+         the "http://purl.org/dc/elements/1.1/" namespace.
+      </xs:documentation>
+   </xs:annotation>
+   <xs:complexType name="SimpleLiteral" mixed="true">
+      <xs:annotation>
+         <xs:documentation xml:lang="en">
+            This is the default type for all of the DC elements. It defines a 
+            complexType SimpleLiteral which permits mixed content but disallows 
+            child elements by use of minOcccurs/maxOccurs. However, this
+            complexType  does permit the derivation of other types which
+            would permit child elements. The scheme attribute may be used
+            as a qualifier to reference  an encoding scheme that describes
+            the value domain for a given property.
+         </xs:documentation>
+      </xs:annotation>
+      <xs:complexContent mixed="true">
+         <xs:restriction base="xs:anyType">
+            <xs:sequence>
+               <xs:any processContents="lax" minOccurs="0" maxOccurs="0"/>
+            </xs:sequence>
+            <xs:attribute name="scheme" type="xs:anyURI" use="optional"/>
+         </xs:restriction>
+      </xs:complexContent>
+   </xs:complexType>
+   <xs:element name="DC-element" type="dc:SimpleLiteral" abstract="true"/>
+   <xs:element name="title" type="dc:SimpleLiteral"
+      substitutionGroup="dc:DC-element">
+      <xs:annotation>
+         <xs:documentation xml:lang="en">
+            A name given to the resource. Typically, Title will be a name by 
+            which the resource is formally known.
+         </xs:documentation>
+      </xs:annotation>
+   </xs:element>
+   <xs:element name="creator" type="dc:SimpleLiteral"
+      substitutionGroup="dc:DC-element">
+      <xs:annotation>
+         <xs:documentation xml:lang="en">
+            An entity primarily responsible for making the content of
+            the resource. Examples of Creator include a person, an
+            organization, or a service. Typically, the name of a Creator
+            should be used to indicate the entity.
+         </xs:documentation>
+      </xs:annotation>
+   </xs:element>
+   <xs:element name="subject" type="dc:SimpleLiteral"
+      substitutionGroup="dc:DC-element">
+      <xs:annotation>
+         <xs:documentation xml:lang="en">
+            A topic of the content of the resource. Typically, Subject will be 
+            expressed as keywords, key phrases, or classification codes that 
+            describe a topic of the resource. Recommended best practice is to 
+            select a value from a controlled vocabulary or formal
+            classification  scheme.
+         </xs:documentation>
+      </xs:annotation>
+   </xs:element>
+   <xs:element name="description" type="dc:SimpleLiteral"
+      substitutionGroup="dc:DC-element">
+      <xs:annotation>
+         <xs:documentation xml:lang="en">
+            An account of the content of the resource. Examples of Description 
+            include, but are not limited to, an abstract, table of contents, 
+            reference to a graphical representation of content, or free-text 
+            account of the content.
+         </xs:documentation>
+      </xs:annotation>
+   </xs:element>
+   <xs:element name="publisher" type="dc:SimpleLiteral"
+      substitutionGroup="dc:DC-element">
+      <xs:annotation>
+         <xs:documentation xml:lang="en">
+            An entity responsible for making the resource available.
+            Examples of Publisher include a person, an organization,
+            or a service. Typically, the name of a Publisher should
+            be used to indicate the entity.
+         </xs:documentation>
+      </xs:annotation>
+   </xs:element>
+   <xs:element name="contributor" type="dc:SimpleLiteral"
+      substitutionGroup="dc:DC-element">
+      <xs:annotation>
+         <xs:documentation xml:lang="en">
+            An entity responsible for making contributions to the content of 
+            the resource. Examples of Contributor include a person, an
+            organization,  or a service. Typically, the name of a Contributor
+            should be used to  indicate the entity.
+         </xs:documentation>
+      </xs:annotation>
+   </xs:element>
+   <xs:element name="date" type="dc:SimpleLiteral"
+      substitutionGroup="dc:DC-element">
+      <xs:annotation>
+         <xs:documentation xml:lang="en">
+            A date of an event in the lifecycle of the resource. Typically,
+            Date will be associated with the creation or availability of
+            the resource.  Recommended best practice for encoding the date
+            value is defined in a profile of ISO 8601 and includes (among
+            others) dates of the form YYYY-MM-DD.
+         </xs:documentation>
+      </xs:annotation>
+   </xs:element>
+   <xs:element name="type" type="dc:SimpleLiteral"
+      substitutionGroup="dc:DC-element">
+      <xs:annotation>
+         <xs:documentation xml:lang="en">
+            The nature or genre of the content of the resource. Type includes 
+            terms describing general categories, functions, genres, or
+            aggregation levels for content. Recommended best practice is to
+            select a value from a controlled vocabulary (for example, the
+            DCMI Type Vocabulary). To describe the physical or digital
+            manifestation of the resource, use the Format element.
+         </xs:documentation>
+      </xs:annotation>
+   </xs:element>
+   <xs:element name="format" type="dc:SimpleLiteral"
+      substitutionGroup="dc:DC-element">
+      <xs:annotation>
+         <xs:documentation xml:lang="en">
+            The physical or digital manifestation of the resource. Typically, 
+            Format will include the media-type or dimensions of the resource. 
+            Format may be used to identify the software, hardware, or other 
+            equipment needed to display or operate the resource. Examples of 
+            dimensions include size and duration. Recommended best practice
+            is to select a value from a controlled vocabulary (for example,
+            the list of Internet Media Types defining computer media formats).
+         </xs:documentation>
+      </xs:annotation>
+   </xs:element>
+   <xs:element name="identifier" type="dc:SimpleLiteral"
+      substitutionGroup="dc:DC-element">
+      <xs:annotation>
+         <xs:documentation xml:lang="en">
+            An unambiguous reference to the resource within a given context. 
+            Recommended best practice is to identify the resource by means of a 
+            string or number conforming to a formal identification system.
+            Formal identification systems include but are not limited to the
+            Uniform Resource Identifier (URI) (including the Uniform Resource
+            Locator (URL)), the Digital Object Identifier (DOI), and the
+            International Standard Book Number (ISBN).
+         </xs:documentation>
+      </xs:annotation>
+   </xs:element>
+   <xs:element name="source" type="dc:SimpleLiteral"
+      substitutionGroup="dc:DC-element">
+      <xs:annotation>
+         <xs:documentation xml:lang="en">
+            A Reference to a resource from which the present resource is
+            derived. The present resource may be derived from the Source
+            resource in whole or in part. Recommended best practice is
+            to identify the referenced resource by means of a string or
+            number conforming to a formal identification system.
+         </xs:documentation>
+      </xs:annotation>
+   </xs:element>
+   <xs:element name="language" type="dc:SimpleLiteral"
+      substitutionGroup="dc:DC-element">
+      <xs:annotation>
+         <xs:documentation xml:lang="en">
+            A language of the intellectual content of the resource. Recommended 
+            best practice is to use RFC 3066, which, in conjunction with ISO
+            639, defines two- and three-letter primary language tags with
+            optional subtags. Examples include "en" or "eng" for English,
+            "akk" for Akkadian, and "en-GB" for English used in the United
+            Kingdom.
+         </xs:documentation>
+      </xs:annotation>
+   </xs:element>
+   <xs:element name="relation" type="dc:SimpleLiteral"
+      substitutionGroup="dc:DC-element">
+      <xs:annotation>
+         <xs:documentation xml:lang="en">A reference to a related resource. Recommended best practice is to 
+      identify the referenced resource by means of a string or number 
+      conforming to a formal identification system.</xs:documentation>
+      </xs:annotation>
+   </xs:element>
+   <xs:element name="coverage" type="dc:SimpleLiteral"
+      substitutionGroup="dc:DC-element">
+      <xs:annotation>
+         <xs:documentation xml:lang="en">
+            The extent or scope of the content of the resource. Typically, 
+            Coverage will include spatial location (a place name or geographic 
+            coordinates), temporal period (a period label, date, or date
+            range), or jurisdiction (such as a named administrative entity).
+            Recommended best practice is to select a value from a controlled
+            vocabulary (for example, the Thesaurus of Geographic Names [TGN])
+            and to use, where appropriate, named places or time periods in
+            preference to numeric identifiers such as sets of coordinates
+            or date ranges.
+         </xs:documentation>
+      </xs:annotation>
+   </xs:element>
+   <xs:element name="rights" type="dc:SimpleLiteral"
+      substitutionGroup="dc:DC-element">
+      <xs:annotation>
+         <xs:documentation xml:lang="en">
+            Information about rights held in and over the resource. Typically, 
+            Rights will contain a rights management statement for the resource, 
+            or reference a service providing such information. Rights
+            information often encompasses Intellectual Property Rights (IPR),
+            Copyright, and various Property Rights. If the Rights element is
+            absent, no assumptions may be made about any rights held in or
+            over the resource.
+         </xs:documentation>
+      </xs:annotation>
+   </xs:element>
+   <xs:group name="DC-element-set">
+      <xs:annotation>
+         <xs:documentation xml:lang="en">
+            This group is included as a convenience for schema authors who need 
+            to refer to all the elements in the
+            "http://purl.org/dc/elements/1.1/" namespace.
+         </xs:documentation>
+      </xs:annotation>
+      <xs:sequence>
+         <xs:choice minOccurs="0" maxOccurs="unbounded">
+            <xs:element ref="dc:DC-element"/>
+         </xs:choice>
+      </xs:sequence>
+   </xs:group>
+   <xs:complexType name="elementContainer">
+      <xs:annotation>
+         <xs:documentation xml:lang="en">
+            This type definition is included as a convenience for schema
+            authors who need a container element for all of the DC elements.
+         </xs:documentation>
+      </xs:annotation>
+      <xs:choice>
+         <xs:group ref="dc:DC-element-set"/>
+      </xs:choice>
+   </xs:complexType>
+</xs:schema>
diff --git a/pycsw/schemas/ogc/csw/2.0.2/rec-dcterms.xsd b/pycsw/core/schemas/ogc/csw/3.0/rec-dcterms.xsd
similarity index 78%
rename from pycsw/schemas/ogc/csw/2.0.2/rec-dcterms.xsd
rename to pycsw/core/schemas/ogc/csw/3.0/rec-dcterms.xsd
index 57d15d8..ff0f607 100644
--- a/pycsw/schemas/ogc/csw/2.0.2/rec-dcterms.xsd
+++ b/pycsw/core/schemas/ogc/csw/3.0/rec-dcterms.xsd
@@ -1,15 +1,18 @@
-<?xml version="1.0" encoding="ISO-8859-1"?>
-<xs:schema id="dcmi-terms" targetNamespace="http://purl.org/dc/terms/"
-   xmlns:xs="http://www.w3.org/2001/XMLSchema"
+<?xml version="1.0" encoding="UTF-8"?>
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:dct="http://purl.org/dc/terms/"
-   xmlns:dc="http://purl.org/dc/elements/1.1/" elementFormDefault="qualified"
-   attributeFormDefault="unqualified" version="2.0.2 2010-01-22">
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   targetNamespace="http://purl.org/dc/terms/" elementFormDefault="qualified"
+   attributeFormDefault="unqualified" version="3.0" id="dcmi-terms">
    <xs:annotation>
-      <xs:documentation xml:lang="en"
-         source="http://dublincore.org/documents/dcmi-terms/">This schema declares additional DCMI elements and element refinements 
-    in the "http://purl.org/dc/terms/" namespace.</xs:documentation>
+      <xs:documentation source="http://dublincore.org/documents/dcmi-terms/"
+         xml:lang="en">
+         This schema declares additional DCMI elements and element
+         refinements in the "http://purl.org/dc/terms/" namespace.
+      </xs:documentation>
    </xs:annotation>
-   <xs:import namespace="http://purl.org/dc/elements/1.1/" schemaLocation="rec-dcmes.xsd"/>
+   <xs:import namespace="http://purl.org/dc/elements/1.1/"
+      schemaLocation="rec-dcmes.xsd"/>
    <xs:element name="abstract" type="dc:SimpleLiteral"
       substitutionGroup="dc:description"/>
    <xs:element name="accessRights" type="dc:SimpleLiteral"
@@ -52,7 +55,8 @@
       substitutionGroup="dc:relation"/>
    <xs:element name="isRequiredBy" type="dc:SimpleLiteral"
       substitutionGroup="dc:relation"/>
-   <xs:element name="issued" type="dc:SimpleLiteral" substitutionGroup="dc:date"/>
+   <xs:element name="issued" type="dc:SimpleLiteral"
+      substitutionGroup="dc:date"/>
    <xs:element name="isVersionOf" type="dc:SimpleLiteral"
       substitutionGroup="dc:relation"/>
    <xs:element name="license" type="dc:SimpleLiteral"
@@ -79,11 +83,14 @@
       substitutionGroup="dc:description"/>
    <xs:element name="temporal" type="dc:SimpleLiteral"
       substitutionGroup="dc:coverage"/>
-   <xs:element name="valid" type="dc:SimpleLiteral" substitutionGroup="dc:date"/>
+   <xs:element name="valid" type="dc:SimpleLiteral"
+      substitutionGroup="dc:date"/>
    <xs:group name="DCMI-terms">
       <xs:annotation>
-         <xs:documentation xml:lang="en">This group is included as a convenience for schema authors who need 
-      to refer to the complete set of DCMI metadata terms.</xs:documentation>
+         <xs:documentation xml:lang="en">
+            This group is included as a convenience for schema authors
+            who need  to refer to the complete set of DCMI metadata terms.
+         </xs:documentation>
       </xs:annotation>
       <xs:sequence>
          <xs:choice minOccurs="0" maxOccurs="unbounded">
diff --git a/pycsw/core/schemas/ogc/csw/3.0/record.xsd b/pycsw/core/schemas/ogc/csw/3.0/record.xsd
new file mode 100644
index 0000000..5572d29
--- /dev/null
+++ b/pycsw/core/schemas/ogc/csw/3.0/record.xsd
@@ -0,0 +1,170 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xsd:schema
+   targetNamespace="http://www.opengis.net/cat/csw/3.0"
+   xmlns:csw30="http://www.opengis.net/cat/csw/3.0"
+   xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:dct="http://purl.org/dc/terms/"
+   xmlns:ows="http://www.opengis.net/ows/2.0"
+   elementFormDefault="qualified"
+   version="3.0"
+   id="record">
+   <xsd:annotation>
+      <xsd:appinfo>
+         <dc:identifier xmlns:dc="http://purl.org/dc/elements/1.1/">http://schemas.opengis.net/csw/3.0/record.xsd</dc:identifier>
+      </xsd:appinfo>
+      <xsd:documentation xml:lang="en">
+         This schema defines the basic record types that must be supported
+         by all CSW implementations. These correspond to full, summary, and
+         brief views based on DCMI metadata terms.
+      </xsd:documentation>
+   </xsd:annotation>
+   <xsd:import namespace="http://purl.org/dc/terms/"
+      schemaLocation="rec-dcterms.xsd"/>
+   <xsd:import namespace="http://purl.org/dc/elements/1.1/"
+      schemaLocation="rec-dcmes.xsd"/>
+   <xsd:import namespace="http://www.opengis.net/ows/2.0"
+      schemaLocation="../../ows/2.0/owsAll.xsd"/>
+   <xsd:element name="AbstractRecord" type="csw30:AbstractRecordType"
+      abstract="true" id="AbstractRecord"/>
+   <xsd:complexType name="AbstractRecordType" abstract="true"
+                    id="AbstractRecordType">
+      <xsd:attribute name="deleted" type="xsd:boolean"
+                     use="optional" default="false"/>
+   </xsd:complexType>
+   <xsd:element name="DCMIRecord" type="csw30:DCMIRecordType"
+                substitutionGroup="csw30:AbstractRecord"/>
+   <xsd:complexType name="DCMIRecordType">
+      <xsd:annotation>
+         <xsd:documentation xml:lang="en">
+            This type encapsulates all of the standard DCMI metadata terms,
+            including the Dublin Core refinements; these terms may be mapped
+            to the profile-specific information model.
+         </xsd:documentation>
+      </xsd:annotation>
+      <xsd:complexContent>
+         <xsd:extension base="csw30:AbstractRecordType">
+            <xsd:sequence>
+               <xsd:group ref="dct:DCMI-terms"/>
+            </xsd:sequence>
+         </xsd:extension>
+      </xsd:complexContent>
+   </xsd:complexType>
+   <xsd:complexType name="TemporalExtentType">
+      <xsd:annotation>
+         <xsd:documentation xml:lang="en">
+             A type for specifying the temporal extent of the data
+             item that a metadata record describes.  Omitting
+             begin/end implies infinity in that direction.  The
+             attribute "inclusive" can be used indicate whether
+             the boundary value in included in extent or not.
+         </xsd:documentation>
+      </xsd:annotation>
+      <xsd:sequence>
+         <xsd:element name="begin" minOccurs="0">
+            <xsd:complexType>
+               <xsd:simpleContent>
+                  <xsd:extension base="xsd:dateTime">
+                     <xsd:attribute name="inclusive"
+                                    type="xsd:boolean" default="true"/>
+                  </xsd:extension>
+               </xsd:simpleContent>
+            </xsd:complexType>
+         </xsd:element>
+         <xsd:element name="end" minOccurs="0">
+            <xsd:complexType>
+               <xsd:simpleContent>
+                  <xsd:extension base="xsd:dateTime">
+                     <xsd:attribute name="inclusive"
+                                    type="xsd:boolean" default="true"/>
+                  </xsd:extension>
+               </xsd:simpleContent>
+            </xsd:complexType>
+         </xsd:element>
+      </xsd:sequence>
+   </xsd:complexType>
+   <xsd:element name="BriefRecord" type="csw30:BriefRecordType"
+                substitutionGroup="csw30:AbstractRecord"/>
+   <xsd:complexType name="BriefRecordType" final="#all">
+      <xsd:annotation>
+         <xsd:documentation xml:lang="en">
+            This type defines a brief representation of the common record
+            format.  It extends AbstractRecordType to include only the
+            dc:identifier and dc:type properties.
+         </xsd:documentation>
+      </xsd:annotation>
+      <xsd:complexContent>
+         <xsd:extension base="csw30:AbstractRecordType">
+            <xsd:sequence>
+               <xsd:element ref="dc:identifier" maxOccurs="unbounded"/>
+               <xsd:element ref="dc:title" maxOccurs="unbounded"/>
+               <xsd:element ref="dc:type" minOccurs="0"/>
+               <xsd:element ref="ows:BoundingBox"
+                            minOccurs="0" maxOccurs="unbounded"/>
+            </xsd:sequence>
+         </xsd:extension>
+      </xsd:complexContent>
+   </xsd:complexType>
+   <xsd:element name="SummaryRecord" type="csw30:SummaryRecordType"
+                substitutionGroup="csw30:AbstractRecord"/>
+   <xsd:complexType name="SummaryRecordType" final="#all">
+      <xsd:annotation>
+         <xsd:documentation xml:lang="en">
+            This type defines a summary representation of the common record
+            format.  It extends AbstractRecordType to include the core
+            properties.
+         </xsd:documentation>
+      </xsd:annotation>
+      <xsd:complexContent>
+         <xsd:extension base="csw30:AbstractRecordType">
+            <xsd:sequence>
+               <xsd:element ref="dc:identifier" maxOccurs="unbounded"/>
+               <xsd:element ref="dc:title" maxOccurs="unbounded"/>
+               <xsd:element ref="dc:type" minOccurs="0"/>
+               <xsd:element ref="dc:subject"
+                            minOccurs="0" maxOccurs="unbounded"/>
+               <xsd:element ref="dc:format"
+                            minOccurs="0" maxOccurs="unbounded"/>
+               <xsd:element ref="dc:relation"
+                            minOccurs="0" maxOccurs="unbounded"/>
+               <xsd:element ref="dct:modified"
+                            minOccurs="0" maxOccurs="unbounded"/>
+               <xsd:element ref="dct:abstract"
+                            minOccurs="0" maxOccurs="unbounded"/>
+               <xsd:element ref="dct:spatial"
+                            minOccurs="0" maxOccurs="unbounded"/>
+               <xsd:element ref="ows:BoundingBox"
+                            minOccurs="0" maxOccurs="unbounded"/>
+               <xsd:element name="TemporalExtent"
+                            type="csw30:TemporalExtentType"
+                            minOccurs="0" maxOccurs="unbounded"/>
+            </xsd:sequence>
+         </xsd:extension>
+      </xsd:complexContent>
+   </xsd:complexType>
+   <xsd:element name="Record" type="csw30:RecordType"
+                substitutionGroup="csw30:AbstractRecord"/>
+   <xsd:complexType name="RecordType" final="#all">
+      <xsd:annotation>
+         <xsd:documentation xml:lang="en">
+            This type extends DCMIRecordType to add ows:BoundingBox;
+            it may be used to specify a spatial envelope for the
+            catalogued resource.
+         </xsd:documentation>
+      </xsd:annotation>
+      <xsd:complexContent>
+         <xsd:extension base="csw30:DCMIRecordType">
+            <xsd:sequence>
+               <xsd:element name="AnyText" type="csw30:EmptyType"
+                            minOccurs="0" maxOccurs="unbounded"/>
+               <xsd:element ref="ows:BoundingBox"
+                            minOccurs="0" maxOccurs="unbounded"/>
+               <xsd:element name="TemporalExtent"
+                            type="csw30:TemporalExtentType"
+                            minOccurs="0" maxOccurs="unbounded"/>
+            </xsd:sequence>
+         </xsd:extension>
+      </xsd:complexContent>
+   </xsd:complexType>
+   <xsd:complexType name="EmptyType"/>
+</xsd:schema>
diff --git a/pycsw/schemas/ogc/filter/1.1.0/expr.xsd b/pycsw/core/schemas/ogc/filter/1.1.0/expr.xsd
similarity index 100%
rename from pycsw/schemas/ogc/filter/1.1.0/expr.xsd
rename to pycsw/core/schemas/ogc/filter/1.1.0/expr.xsd
diff --git a/pycsw/schemas/ogc/filter/1.1.0/filter.xsd b/pycsw/core/schemas/ogc/filter/1.1.0/filter.xsd
similarity index 100%
rename from pycsw/schemas/ogc/filter/1.1.0/filter.xsd
rename to pycsw/core/schemas/ogc/filter/1.1.0/filter.xsd
diff --git a/pycsw/schemas/ogc/filter/1.1.0/filterCapabilities.xsd b/pycsw/core/schemas/ogc/filter/1.1.0/filterCapabilities.xsd
similarity index 100%
rename from pycsw/schemas/ogc/filter/1.1.0/filterCapabilities.xsd
rename to pycsw/core/schemas/ogc/filter/1.1.0/filterCapabilities.xsd
diff --git a/pycsw/schemas/ogc/filter/1.1.0/sort.xsd b/pycsw/core/schemas/ogc/filter/1.1.0/sort.xsd
similarity index 100%
copy from pycsw/schemas/ogc/filter/1.1.0/sort.xsd
copy to pycsw/core/schemas/ogc/filter/1.1.0/sort.xsd
diff --git a/pycsw/core/schemas/ogc/filter/2.0/expr.xsd b/pycsw/core/schemas/ogc/filter/2.0/expr.xsd
new file mode 100644
index 0000000..8513a20
--- /dev/null
+++ b/pycsw/core/schemas/ogc/filter/2.0/expr.xsd
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xsd:schema
+   targetNamespace="http://www.opengis.net/fes/2.0"
+   xmlns:fes="http://www.opengis.net/fes/2.0"
+   xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+   elementFormDefault="qualified"
+   version="2.0.2">
+
+   <xsd:annotation>
+      <xsd:documentation>
+         Filter Encoding is an OGC Standard.
+         Copyright (c) 2010, 2014 Open Geospatial Consortium.
+         To obtain additional rights of use, visit http://www.opengeospatial.org/legal/ .
+      </xsd:documentation>
+   </xsd:annotation>
+   
+   <xsd:include schemaLocation="filterAll.xsd"/>
+   
+   <xsd:element name="expression" abstract="true"/>
+
+   <xsd:element name="ValueReference" type="xsd:string"
+                substitutionGroup="fes:expression"/>
+
+   <xsd:element name="Function" type="fes:FunctionType"
+                substitutionGroup="fes:expression"/>
+   <xsd:complexType name="FunctionType">
+      <xsd:sequence>
+         <xsd:element ref="fes:expression"
+                      minOccurs="0" maxOccurs="unbounded"/>
+      </xsd:sequence>
+      <xsd:attribute name="name" type="xsd:string" use="required"/>
+   </xsd:complexType> 
+
+   <xsd:element name="Literal" type="fes:LiteralType"
+                substitutionGroup="fes:expression"/>
+   <xsd:complexType name="LiteralType" mixed="true">
+      <xsd:sequence>
+         <xsd:any minOccurs="0"/>
+      </xsd:sequence>
+      <xsd:attribute name="type" type="xsd:QName"/>
+   </xsd:complexType>
+
+</xsd:schema>
+
diff --git a/pycsw/core/schemas/ogc/filter/2.0/filter.xsd b/pycsw/core/schemas/ogc/filter/2.0/filter.xsd
new file mode 100644
index 0000000..1a5dac8
--- /dev/null
+++ b/pycsw/core/schemas/ogc/filter/2.0/filter.xsd
@@ -0,0 +1,395 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xsd:schema
+   targetNamespace="http://www.opengis.net/fes/2.0"
+   xmlns:fes="http://www.opengis.net/fes/2.0"
+   xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+   elementFormDefault="qualified"
+   version="2.0.2">
+
+   <xsd:annotation>
+      <xsd:documentation>
+         Filter Encoding is an OGC Standard.
+         Copyright (c) 2010, 2014 Open Geospatial Consortium.
+         To obtain additional rights of use, visit http://www.opengeospatial.org/legal/ .
+      </xsd:documentation>
+   </xsd:annotation>
+   
+   <xsd:include schemaLocation="filterAll.xsd"/>
+   <xsd:include schemaLocation="expr.xsd"/>
+   <xsd:include schemaLocation="query.xsd"/>
+   <xsd:include schemaLocation="filterCapabilities.xsd"/>
+
+   <xsd:element name="Filter"
+                type="fes:FilterType"
+                substitutionGroup="fes:AbstractSelectionClause"/>
+   <xsd:complexType name="FilterType">
+      <xsd:complexContent>
+         <xsd:extension base="fes:AbstractSelectionClauseType">
+            <xsd:sequence>
+               <xsd:group ref="fes:FilterPredicates"/>
+            </xsd:sequence>
+         </xsd:extension>
+      </xsd:complexContent>
+   </xsd:complexType>
+
+   <!-- =================================================================== -->
+   <!-- FILTER PREDICATES                                                   -->
+   <!-- =================================================================== -->
+   <xsd:group name="FilterPredicates">
+     <xsd:choice>
+         <xsd:element ref="fes:comparisonOps"/>
+         <xsd:element ref="fes:spatialOps"/>
+         <xsd:element ref="fes:temporalOps"/>
+         <xsd:element ref="fes:logicOps"/>
+         <xsd:element ref="fes:extensionOps"/>
+         <xsd:element ref="fes:Function"/> 
+         <xsd:element ref="fes:_Id" maxOccurs="unbounded"/>
+      </xsd:choice>
+   </xsd:group>
+
+   <!-- =================================================================== -->
+   <!-- COMPARISON OPERATORS                                                -->
+   <!-- =================================================================== -->
+   <xsd:element name="comparisonOps"
+                type="fes:ComparisonOpsType"
+                abstract="true"/>
+   <xsd:complexType name="ComparisonOpsType" abstract="true"/>
+   <xsd:element name="PropertyIsEqualTo"
+                type="fes:BinaryComparisonOpType"
+                substitutionGroup="fes:comparisonOps"/>
+   <xsd:element name="PropertyIsNotEqualTo"
+                type="fes:BinaryComparisonOpType"
+                substitutionGroup="fes:comparisonOps"/>
+   <xsd:element name="PropertyIsLessThan"
+                type="fes:BinaryComparisonOpType"
+                substitutionGroup="fes:comparisonOps"/>
+   <xsd:element name="PropertyIsGreaterThan"
+                type="fes:BinaryComparisonOpType"
+                substitutionGroup="fes:comparisonOps"/>
+   <xsd:element name="PropertyIsLessThanOrEqualTo"
+                type="fes:BinaryComparisonOpType"
+                substitutionGroup="fes:comparisonOps"/>
+   <xsd:element name="PropertyIsGreaterThanOrEqualTo"
+                type="fes:BinaryComparisonOpType"
+                substitutionGroup="fes:comparisonOps"/>
+   <xsd:element name="PropertyIsLike"
+                type="fes:PropertyIsLikeType"
+                substitutionGroup="fes:comparisonOps"/>
+   <xsd:element name="PropertyIsNull"
+                type="fes:PropertyIsNullType"
+                substitutionGroup="fes:comparisonOps"/>
+   <xsd:element name="PropertyIsNil"
+                type="fes:PropertyIsNilType"
+                substitutionGroup="fes:comparisonOps"/>
+   <xsd:element name="PropertyIsBetween"
+                type="fes:PropertyIsBetweenType"
+                substitutionGroup="fes:comparisonOps"/>
+
+   <!-- =================================================================== -->
+   <!-- SPATIAL OPERATORS                                                   -->
+   <!-- =================================================================== -->
+   <xsd:element name="spatialOps" type="fes:SpatialOpsType" abstract="true"/>
+   <xsd:complexType name="SpatialOpsType" abstract="true"/>
+   <xsd:element name="Equals"
+                type="fes:BinarySpatialOpType"
+                substitutionGroup="fes:spatialOps"/>
+   <xsd:element name="Disjoint"
+                type="fes:BinarySpatialOpType"
+                substitutionGroup="fes:spatialOps"/>
+   <xsd:element name="Touches"
+                type="fes:BinarySpatialOpType"
+                substitutionGroup="fes:spatialOps"/>
+   <xsd:element name="Within"
+                type="fes:BinarySpatialOpType"
+                substitutionGroup="fes:spatialOps"/>
+   <xsd:element name="Overlaps"
+                type="fes:BinarySpatialOpType"
+                substitutionGroup="fes:spatialOps"/>
+   <xsd:element name="Crosses"
+                type="fes:BinarySpatialOpType"
+                substitutionGroup="fes:spatialOps"/>
+   <xsd:element name="Intersects"
+                type="fes:BinarySpatialOpType"
+                substitutionGroup="fes:spatialOps"/>
+   <xsd:element name="Contains"
+                type="fes:BinarySpatialOpType"
+                substitutionGroup="fes:spatialOps"/>
+   <xsd:element name="DWithin"
+                type="fes:DistanceBufferType"
+                substitutionGroup="fes:spatialOps"/>
+   <xsd:element name="Beyond"
+                type="fes:DistanceBufferType"
+                substitutionGroup="fes:spatialOps"/>
+   <xsd:element name="BBOX"
+                type="fes:BBOXType"
+                substitutionGroup="fes:spatialOps"/>
+
+   <!-- =================================================================== -->
+   <!-- TEMPORAL OPERATORS                                                  -->
+   <!-- =================================================================== -->
+   <xsd:element name="temporalOps" type="fes:TemporalOpsType" abstract="true"/>
+   <xsd:complexType name="TemporalOpsType" abstract="true"/>
+   <xsd:element name="After"
+                type="fes:BinaryTemporalOpType"
+                substitutionGroup="fes:temporalOps"/>
+   <xsd:element name="Before"
+                type="fes:BinaryTemporalOpType"
+                substitutionGroup="fes:temporalOps"/>
+   <xsd:element name="Begins"
+                type="fes:BinaryTemporalOpType"
+                substitutionGroup="fes:temporalOps"/>
+   <xsd:element name="BegunBy"
+                type="fes:BinaryTemporalOpType"
+                substitutionGroup="fes:temporalOps"/>
+   <xsd:element name="TContains"
+                type="fes:BinaryTemporalOpType"
+                substitutionGroup="fes:temporalOps"/>
+   <xsd:element name="During"
+                type="fes:BinaryTemporalOpType"
+                substitutionGroup="fes:temporalOps"/>
+   <xsd:element name="EndedBy"
+                type="fes:BinaryTemporalOpType"
+                substitutionGroup="fes:temporalOps"/>
+   <xsd:element name="Ends"
+                type="fes:BinaryTemporalOpType"
+                substitutionGroup="fes:temporalOps"/>
+   <xsd:element name="TEquals"
+                type="fes:BinaryTemporalOpType"
+                substitutionGroup="fes:temporalOps"/>
+   <xsd:element name="Meets"
+                type="fes:BinaryTemporalOpType"
+                substitutionGroup="fes:temporalOps"/>
+   <xsd:element name="MetBy"
+                type="fes:BinaryTemporalOpType"
+                substitutionGroup="fes:temporalOps"/>
+   <xsd:element name="TOverlaps"
+                type="fes:BinaryTemporalOpType"
+                substitutionGroup="fes:temporalOps"/>
+   <xsd:element name="OverlappedBy"
+                type="fes:BinaryTemporalOpType"
+                substitutionGroup="fes:temporalOps"/>
+   <xsd:element name="AnyInteracts"
+                type="fes:BinaryTemporalOpType"
+                substitutionGroup="fes:temporalOps"/>
+
+   <!-- =================================================================== -->
+   <!-- LOGICAL OPERATORS                                                   -->
+   <!-- =================================================================== -->
+   <xsd:element name="logicOps" type="fes:LogicOpsType" abstract="true"/>
+   <xsd:complexType name="LogicOpsType" abstract="true"/>
+   <xsd:element name="And"
+                type="fes:BinaryLogicOpType"
+                substitutionGroup="fes:logicOps"/>
+   <xsd:element name="Or"
+                type="fes:BinaryLogicOpType"
+                substitutionGroup="fes:logicOps"/>
+   <xsd:element name="Not"
+                type="fes:UnaryLogicOpType"
+                substitutionGroup="fes:logicOps"/>
+
+   <!-- =================================================================== -->
+   <!-- EXTENSION OPERATORS                                                 -->
+   <!-- =================================================================== -->
+   <xsd:element name="extensionOps"
+                type="fes:ExtensionOpsType"
+                abstract="true"/>
+   <xsd:complexType name="ExtensionOpsType" abstract="true"/>
+
+   <!-- =================================================================== -->
+   <!-- OBJECT/RECORDS IDENTIFIERS                                          -->
+   <!-- =================================================================== -->
+   <xsd:element name="_Id" type="fes:AbstractIdType" abstract="true"/>
+   <xsd:complexType name="AbstractIdType" abstract="true"/>
+
+   <!-- =================================================================== -->
+   <!-- CONCRETE OBJECT IDENTIFIERS                                         -->
+   <!-- =================================================================== -->
+   <xsd:element name="ResourceId"
+                type="fes:ResourceIdType"
+                substitutionGroup="fes:_Id"/>
+   <xsd:complexType name="ResourceIdType">
+      <xsd:complexContent>
+         <xsd:extension base="fes:AbstractIdType">
+            <xsd:attribute name="rid" type="xsd:string" use="required"/>
+            <xsd:attribute name="previousRid" type="xsd:string"/>
+            <xsd:attribute name="version" type="fes:VersionType"/>
+            <xsd:attribute name="startDate" type="xsd:dateTime"/>
+            <xsd:attribute name="endDate" type="xsd:dateTime"/>
+         </xsd:extension>
+      </xsd:complexContent>
+   </xsd:complexType>
+   <xsd:simpleType name="VersionType">
+      <xsd:union memberTypes="fes:VersionActionTokens
+                              xsd:positiveInteger
+                              xsd:dateTime">
+      </xsd:union>
+   </xsd:simpleType>
+   <xsd:simpleType name="VersionActionTokens">
+      <xsd:restriction base="xsd:string">
+         <xsd:enumeration value="FIRST"/>
+         <xsd:enumeration value="LAST"/>
+         <xsd:enumeration value="PREVIOUS"/>
+         <xsd:enumeration value="NEXT"/>
+         <xsd:enumeration value="ALL"/>
+      </xsd:restriction>
+   </xsd:simpleType>
+
+   <!-- =================================================================== -->
+   <!-- TYPE DECLARATIONS                                                   -->
+   <!-- =================================================================== -->
+   <xsd:complexType name="BinaryComparisonOpType">
+      <xsd:complexContent>
+         <xsd:extension base="fes:ComparisonOpsType">
+            <xsd:sequence>
+               <xsd:element ref="fes:expression" minOccurs="2" maxOccurs="2"/>
+            </xsd:sequence>
+            <xsd:attribute name="matchCase" type="xsd:boolean"
+                           use="optional" default="true"/>
+            <xsd:attribute name="matchAction" type="fes:MatchActionType"
+                           use="optional" default="Any"/>
+         </xsd:extension>
+      </xsd:complexContent>
+   </xsd:complexType>
+   <xsd:simpleType name="MatchActionType">
+      <xsd:restriction base="xsd:string">
+         <xsd:enumeration value="All"/>
+         <xsd:enumeration value="Any"/>
+         <xsd:enumeration value="One"/>
+      </xsd:restriction>
+   </xsd:simpleType>
+   <xsd:complexType name="PropertyIsLikeType">
+      <xsd:complexContent>
+         <xsd:extension base="fes:ComparisonOpsType">
+            <xsd:sequence>
+               <xsd:element ref="fes:expression" minOccurs="2" maxOccurs="2"/>
+            </xsd:sequence>
+            <xsd:attribute name="wildCard" type="xsd:string" use="required"/>
+            <xsd:attribute name="singleChar" type="xsd:string" use="required"/>
+            <xsd:attribute name="escapeChar" type="xsd:string" use="required"/>
+         </xsd:extension>
+      </xsd:complexContent>
+   </xsd:complexType>
+   <xsd:complexType name="PropertyIsNullType">
+      <xsd:complexContent>
+         <xsd:extension base="fes:ComparisonOpsType">
+            <xsd:sequence>
+               <xsd:element ref="fes:expression"/>
+            </xsd:sequence>
+         </xsd:extension>
+      </xsd:complexContent>
+   </xsd:complexType>
+   <xsd:complexType name="PropertyIsNilType">
+      <xsd:complexContent>
+         <xsd:extension base="fes:ComparisonOpsType">
+            <xsd:sequence>
+               <xsd:element ref="fes:expression"/>
+            </xsd:sequence>
+            <xsd:attribute name="nilReason" type="xsd:string"/>
+         </xsd:extension>
+      </xsd:complexContent>
+   </xsd:complexType>
+   <xsd:complexType name="PropertyIsBetweenType">
+      <xsd:complexContent>
+         <xsd:extension base="fes:ComparisonOpsType">
+            <xsd:sequence>
+               <xsd:element ref="fes:expression"/>
+               <xsd:element name="LowerBoundary" type="fes:LowerBoundaryType"/>
+               <xsd:element name="UpperBoundary" type="fes:UpperBoundaryType"/>
+            </xsd:sequence>
+         </xsd:extension>
+      </xsd:complexContent>
+   </xsd:complexType>
+   <xsd:complexType name="LowerBoundaryType">
+      <xsd:choice>
+         <xsd:element ref="fes:expression"/>
+      </xsd:choice>
+   </xsd:complexType>
+   <xsd:complexType name="UpperBoundaryType">
+      <xsd:sequence>
+         <xsd:element ref="fes:expression"/>
+      </xsd:sequence>
+   </xsd:complexType>
+   <xsd:complexType name="BinarySpatialOpType">
+      <xsd:complexContent>
+         <xsd:extension base="fes:SpatialOpsType">
+            <xsd:choice maxOccurs="2">
+               <xsd:element ref="fes:expression"/>
+               <xsd:any namespace="##other"/>
+            </xsd:choice>
+         </xsd:extension>
+      </xsd:complexContent>
+   </xsd:complexType>
+   <xsd:complexType name="BinaryTemporalOpType">
+      <xsd:complexContent>
+         <xsd:extension base="fes:TemporalOpsType">
+            <xsd:choice maxOccurs="2">
+               <xsd:element ref="fes:expression"/>
+               <xsd:any namespace="##other"/>
+            </xsd:choice>
+         </xsd:extension>
+      </xsd:complexContent>
+   </xsd:complexType>
+   <xsd:complexType name="BBOXType">
+      <xsd:complexContent>
+         <xsd:extension base="fes:SpatialOpsType">
+            <xsd:choice maxOccurs="2">
+               <xsd:element ref="fes:expression"/>
+               <xsd:any namespace="##other"/>
+            </xsd:choice>
+         </xsd:extension>
+      </xsd:complexContent>
+   </xsd:complexType>
+   <xsd:complexType name="DistanceBufferType">
+      <xsd:complexContent>
+         <xsd:extension base="fes:SpatialOpsType">
+            <xsd:sequence>
+               <xsd:choice maxOccurs="2">
+                  <xsd:element ref="fes:expression"/>
+                  <xsd:any namespace="##other"/>
+               </xsd:choice>
+               <xsd:element name="Distance" type="fes:MeasureType"/>
+            </xsd:sequence>
+         </xsd:extension>
+      </xsd:complexContent>
+   </xsd:complexType>
+   <xsd:complexType name="BinaryLogicOpType">
+      <xsd:complexContent>
+         <xsd:extension base="fes:LogicOpsType">
+            <xsd:choice minOccurs="2" maxOccurs="unbounded">
+               <xsd:group ref="fes:FilterPredicates"/>
+            </xsd:choice>
+         </xsd:extension>
+      </xsd:complexContent>
+   </xsd:complexType>
+   <xsd:complexType name="UnaryLogicOpType">
+      <xsd:complexContent>
+         <xsd:extension base="fes:LogicOpsType">
+            <xsd:sequence>
+               <xsd:choice>
+                  <xsd:group ref="fes:FilterPredicates"/>
+               </xsd:choice>
+            </xsd:sequence>
+         </xsd:extension>
+      </xsd:complexContent>
+   </xsd:complexType>
+   <xsd:complexType name="MeasureType">
+      <xsd:simpleContent>
+         <xsd:extension base="xsd:double">
+            <xsd:attribute name="uom" type="fes:UomIdentifier" use="required"/>
+         </xsd:extension>
+      </xsd:simpleContent>
+   </xsd:complexType>
+   <xsd:simpleType name="UomIdentifier">
+      <xsd:union memberTypes="fes:UomSymbol fes:UomURI"/>
+   </xsd:simpleType>
+   <xsd:simpleType name="UomSymbol">
+      <xsd:restriction base="xsd:string">
+         <xsd:pattern value="[^: \n\r\t]+"/>
+      </xsd:restriction>
+   </xsd:simpleType>
+   <xsd:simpleType name="UomURI">
+      <xsd:restriction base="xsd:anyURI">
+         <xsd:pattern value="([a-zA-Z][a-zA-Z0-9\-\+\.]*:|\.\./|\./|#).*"/>
+      </xsd:restriction>
+   </xsd:simpleType>
+</xsd:schema>
diff --git a/pycsw/core/schemas/ogc/filter/2.0/filterAll.xsd b/pycsw/core/schemas/ogc/filter/2.0/filterAll.xsd
new file mode 100644
index 0000000..70b5d78
--- /dev/null
+++ b/pycsw/core/schemas/ogc/filter/2.0/filterAll.xsd
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xsd:schema
+   targetNamespace="http://www.opengis.net/fes/2.0"
+   xmlns:fes="http://www.opengis.net/fes/2.0"
+   xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+   elementFormDefault="qualified"
+   version="2.0.2">
+
+   <xsd:annotation>
+      <xsd:documentation>
+         This XML Schema document includes and imports, directly or indirectly,
+         all the XML Schema defined by the Filter Encoding Standard.
+
+         Filter Encoding is an OGC Standard.
+         Copyright (c) 2010, 2014 Open Geospatial Consortium.
+         To obtain additional rights of use, visit http://www.opengeospatial.org/legal/ .
+      </xsd:documentation>
+   </xsd:annotation>
+
+   <xsd:include schemaLocation="query.xsd"/>
+   <xsd:include schemaLocation="filter.xsd"/>
+   <xsd:include schemaLocation="sort.xsd"/>
+</xsd:schema>
diff --git a/pycsw/core/schemas/ogc/filter/2.0/filterCapabilities.xsd b/pycsw/core/schemas/ogc/filter/2.0/filterCapabilities.xsd
new file mode 100644
index 0000000..7dfd77d
--- /dev/null
+++ b/pycsw/core/schemas/ogc/filter/2.0/filterCapabilities.xsd
@@ -0,0 +1,286 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xsd:schema
+   targetNamespace="http://www.opengis.net/fes/2.0"
+   xmlns:fes="http://www.opengis.net/fes/2.0"
+   xmlns:ows="http://www.opengis.net/ows/1.1"
+   xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+   xmlns:xml="http://www.w3.org/XML/1998/namespace"
+   elementFormDefault="qualified"
+   version="2.0.2">
+   
+   <xsd:annotation>
+      <xsd:documentation>
+         This XML Schema defines OGC query filter capabilities documents.
+         
+         Filter Encoding is an OGC Standard.
+         Copyright (c) 2010, 2014 Open Geospatial Consortium.
+         To obtain additional rights of use, visit http://www.opengeospatial.org/legal/ .
+      </xsd:documentation>
+   </xsd:annotation>
+
+   <xsd:include schemaLocation="filterAll.xsd"/>
+   <xsd:import namespace="http://www.w3.org/XML/1998/namespace"
+               schemaLocation="../../../w3c/2001/xml.xsd"/>
+
+   <xsd:import namespace="http://www.opengis.net/ows/1.1"
+        schemaLocation="../../ows/1.1.0/owsAll.xsd"/>
+
+   <xsd:element name="Filter_Capabilities">
+      <xsd:complexType>
+         <xsd:sequence>
+            <xsd:element name="Conformance"
+                         type="fes:ConformanceType"/>
+            <xsd:element name="Id_Capabilities"
+                         type="fes:Id_CapabilitiesType"
+                         minOccurs="0"/>
+            <xsd:element name="Scalar_Capabilities"
+                         type="fes:Scalar_CapabilitiesType"
+                         minOccurs="0"/>
+            <xsd:element name="Spatial_Capabilities"
+                         type="fes:Spatial_CapabilitiesType"
+                         minOccurs="0"/>
+            <xsd:element name="Temporal_Capabilities"
+                         type="fes:Temporal_CapabilitiesType"
+                         minOccurs="0"/>
+            <xsd:element name="Functions"
+                         type="fes:AvailableFunctionsType" minOccurs="0"/>
+            <xsd:element name="Extended_Capabilities"
+                         type="fes:Extended_CapabilitiesType"
+                         minOccurs="0"/>
+         </xsd:sequence>
+      </xsd:complexType>
+   </xsd:element>
+
+   <!-- CONFORMANCE -->
+   <xsd:complexType name="ConformanceType">
+      <xsd:sequence>
+         <xsd:element name="Constraint"
+                      type="ows:DomainType" maxOccurs="unbounded"/>
+      </xsd:sequence>
+   </xsd:complexType>
+
+   <!-- RESOURCE IDENTIFIERS -->
+   <xsd:complexType name="Id_CapabilitiesType">
+      <xsd:sequence>
+         <xsd:element name="ResourceIdentifier"
+                      type="fes:ResourceIdentifierType" maxOccurs="unbounded"/>
+      </xsd:sequence>
+   </xsd:complexType>
+   <xsd:complexType name="ResourceIdentifierType">
+      <xsd:sequence>
+         <xsd:element ref="ows:Metadata" minOccurs="0"/>
+      </xsd:sequence>
+      <xsd:attribute name="name" type="xsd:QName" use="required"/>
+   </xsd:complexType>
+
+   <!-- SCALAR CAPABILITIES -->
+   <xsd:complexType name="Scalar_CapabilitiesType">
+      <xsd:sequence>
+         <xsd:element ref="fes:LogicalOperators" minOccurs="0"/>
+         <xsd:element name="ComparisonOperators"
+                      type="fes:ComparisonOperatorsType" minOccurs="0"/>
+      </xsd:sequence>
+   </xsd:complexType>
+   <xsd:element name="LogicalOperators">
+      <xsd:complexType/>
+   </xsd:element>
+   <xsd:complexType name="ComparisonOperatorsType">
+      <xsd:sequence maxOccurs="unbounded">
+         <xsd:element name="ComparisonOperator"
+                      type="fes:ComparisonOperatorType"/>
+      </xsd:sequence>
+   </xsd:complexType>
+   <xsd:complexType name="ComparisonOperatorType">
+      <xsd:attribute name="name"
+                     type="fes:ComparisonOperatorNameType" use="required"/>
+   </xsd:complexType>
+   <xsd:simpleType name="ComparisonOperatorNameType">
+      <xsd:union>
+         <xsd:simpleType>
+            <xsd:restriction base="xsd:string">
+               <xsd:enumeration value="PropertyIsEqualTo"/>
+               <xsd:enumeration value="PropertyIsNotEqualTo"/>
+               <xsd:enumeration value="PropertyIsLessThan"/>
+               <xsd:enumeration value="PropertyIsGreaterThan"/>
+               <xsd:enumeration value="PropertyIsLessThanOrEqualTo"/>
+               <xsd:enumeration value="PropertyIsGreaterThanOrEqualTo"/>
+               <xsd:enumeration value="PropertyIsLike"/>
+               <xsd:enumeration value="PropertyIsNull"/>
+               <xsd:enumeration value="PropertyIsNil"/>
+               <xsd:enumeration value="PropertyIsBetween"/>
+            </xsd:restriction>
+         </xsd:simpleType>
+         <xsd:simpleType>
+            <xsd:restriction base="xsd:string">
+               <xsd:pattern value="extension:\w{2,}"/>
+            </xsd:restriction>
+         </xsd:simpleType>
+      </xsd:union>
+   </xsd:simpleType>
+   <xsd:complexType name="AvailableFunctionsType">
+      <xsd:sequence>
+         <xsd:element name="Function"
+                      type="fes:AvailableFunctionType" maxOccurs="unbounded"/>
+      </xsd:sequence>
+   </xsd:complexType>
+   <xsd:complexType name="AvailableFunctionType">
+      <xsd:sequence>
+         <xsd:element ref="ows:Metadata" minOccurs="0"/>
+         <xsd:element name="Returns" type="xsd:QName"/>
+         <xsd:element name="Arguments"
+                      type="fes:ArgumentsType" minOccurs="0"/>
+      </xsd:sequence>
+      <xsd:attribute name="name" type="xsd:string" use="required"/>
+   </xsd:complexType>
+   <xsd:complexType name="ArgumentsType">
+      <xsd:sequence>
+         <xsd:element name="Argument"
+                      type="fes:ArgumentType" maxOccurs="unbounded"/>
+      </xsd:sequence>
+   </xsd:complexType>
+   <xsd:complexType name="ArgumentType">
+      <xsd:sequence>
+         <xsd:element ref="ows:Metadata" minOccurs="0"/>
+         <xsd:element name="Type" type="xsd:QName"/>
+      </xsd:sequence>
+      <xsd:attribute name="name" type="xsd:string" use="required"/>
+   </xsd:complexType>
+
+   <!-- SPATIAL CAPABILITIES -->
+   <xsd:complexType name="Spatial_CapabilitiesType">
+      <xsd:sequence>
+         <xsd:element name="GeometryOperands"
+                      type="fes:GeometryOperandsType"/>
+         <xsd:element name="SpatialOperators"
+                      type="fes:SpatialOperatorsType"/>
+      </xsd:sequence>
+   </xsd:complexType>
+   <xsd:complexType name="GeometryOperandsType">
+      <xsd:sequence>
+         <xsd:element name="GeometryOperand" maxOccurs="unbounded">
+            <xsd:complexType>
+               <xsd:attribute name="name" type="xsd:QName" use="required"/>
+            </xsd:complexType>
+         </xsd:element>
+      </xsd:sequence>
+   </xsd:complexType>
+   <xsd:complexType name="SpatialOperatorsType">
+      <xsd:sequence>
+         <xsd:element name="SpatialOperator"
+                      type="fes:SpatialOperatorType"
+                      maxOccurs="unbounded"/>
+      </xsd:sequence>
+   </xsd:complexType>
+   <xsd:complexType name="SpatialOperatorType">
+      <xsd:sequence>
+         <xsd:element name="GeometryOperands"
+                      type="fes:GeometryOperandsType"
+                      minOccurs="0"/>
+      </xsd:sequence>
+      <xsd:attribute name="name" type="fes:SpatialOperatorNameType"/>
+   </xsd:complexType>
+   <xsd:simpleType name="SpatialOperatorNameType">
+      <xsd:union>
+         <xsd:simpleType>
+            <xsd:restriction base="xsd:string">
+               <xsd:enumeration value="BBOX"/>
+               <xsd:enumeration value="Equals"/>
+               <xsd:enumeration value="Disjoint"/>
+               <xsd:enumeration value="Intersects"/>
+               <xsd:enumeration value="Touches"/>
+               <xsd:enumeration value="Crosses"/>
+               <xsd:enumeration value="Within"/>
+               <xsd:enumeration value="Contains"/>
+               <xsd:enumeration value="Overlaps"/>
+               <xsd:enumeration value="Beyond"/>
+               <xsd:enumeration value="DWithin"/>
+            </xsd:restriction>
+         </xsd:simpleType>
+         <xsd:simpleType>
+            <xsd:restriction base="xsd:string">
+               <xsd:pattern value="extension:\w{2,}"/>
+            </xsd:restriction>
+         </xsd:simpleType>
+      </xsd:union>
+   </xsd:simpleType>
+
+   <!-- TEMPORAL CAPABILITIES -->
+   <xsd:complexType name="Temporal_CapabilitiesType">
+      <xsd:sequence>
+         <xsd:element name="TemporalOperands"
+                      type="fes:TemporalOperandsType"/>
+         <xsd:element name="TemporalOperators"
+                      type="fes:TemporalOperatorsType"/>
+      </xsd:sequence>
+   </xsd:complexType>
+   <xsd:complexType name="TemporalOperandsType">
+      <xsd:sequence>
+         <xsd:element name="TemporalOperand" maxOccurs="unbounded">
+            <xsd:complexType>
+               <xsd:attribute name="name" type="xsd:QName" use="required"/>
+            </xsd:complexType>
+         </xsd:element>
+      </xsd:sequence>
+   </xsd:complexType>
+   <xsd:complexType name="TemporalOperatorsType">
+      <xsd:sequence>
+         <xsd:element name="TemporalOperator"
+                      type="fes:TemporalOperatorType"
+                      maxOccurs="unbounded"/>
+      </xsd:sequence>
+   </xsd:complexType>
+   <xsd:complexType name="TemporalOperatorType">
+      <xsd:sequence>
+         <xsd:element name="TemporalOperands"
+                      type="fes:TemporalOperandsType"
+                      minOccurs="0"/>
+      </xsd:sequence>
+      <xsd:attribute name="name"
+                     type="fes:TemporalOperatorNameType" use="required"/>
+   </xsd:complexType>
+   <xsd:simpleType name="TemporalOperatorNameType">
+      <xsd:union>
+         <xsd:simpleType>
+            <xsd:restriction base="xsd:string">
+               <xsd:enumeration value="After"/>
+               <xsd:enumeration value="Before"/>
+               <xsd:enumeration value="Begins"/>
+               <xsd:enumeration value="BegunBy"/>
+               <xsd:enumeration value="TContains"/>
+               <xsd:enumeration value="During"/>
+               <xsd:enumeration value="TEquals"/>
+               <xsd:enumeration value="TOverlaps"/>
+               <xsd:enumeration value="Meets"/>
+               <xsd:enumeration value="OverlappedBy"/>
+               <xsd:enumeration value="MetBy"/>
+               <xsd:enumeration value="Ends"/>
+               <xsd:enumeration value="EndedBy"/>
+            </xsd:restriction>
+         </xsd:simpleType>
+         <xsd:simpleType>
+            <xsd:restriction base="xsd:string">
+               <xsd:pattern value="extension:\w{2,}"/>
+            </xsd:restriction>
+         </xsd:simpleType>
+      </xsd:union>
+   </xsd:simpleType>
+
+   <!-- EXTENSION CAPABILITIES -->
+   <xsd:complexType name="Extended_CapabilitiesType">
+      <xsd:sequence>
+         <xsd:element name="AdditionalOperators"
+                      type="fes:AdditionalOperatorsType" minOccurs="0"/>
+      </xsd:sequence>
+   </xsd:complexType>
+   <xsd:complexType name="AdditionalOperatorsType">
+      <xsd:sequence>
+         <xsd:element name="Operator"
+                      type="fes:ExtensionOperatorType"
+                      minOccurs="0" maxOccurs="unbounded"/>
+      </xsd:sequence>
+   </xsd:complexType>
+   <xsd:complexType name="ExtensionOperatorType">
+      <xsd:attribute name="name" type="xsd:QName" use="required"/>
+   </xsd:complexType>
+
+</xsd:schema>
diff --git a/pycsw/core/schemas/ogc/filter/2.0/query.xsd b/pycsw/core/schemas/ogc/filter/2.0/query.xsd
new file mode 100644
index 0000000..b3be570
--- /dev/null
+++ b/pycsw/core/schemas/ogc/filter/2.0/query.xsd
@@ -0,0 +1,70 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xsd:schema
+   targetNamespace="http://www.opengis.net/fes/2.0"
+   xmlns:fes="http://www.opengis.net/fes/2.0"
+   xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+   elementFormDefault="qualified"
+   version="2.0.2">
+
+   <xsd:annotation>
+      <xsd:documentation>
+         Filter Encoding is an OGC Standard.
+         Copyright (c) 2010, 2014 Open Geospatial Consortium.
+         To obtain additional rights of use, visit http://www.opengeospatial.org/legal/ .
+      </xsd:documentation>
+   </xsd:annotation>
+   
+   <xsd:include schemaLocation="filterAll.xsd"/>
+   
+   <xsd:element name="AbstractQueryExpression"
+                type="fes:AbstractQueryExpressionType" abstract="true"/>
+   <xsd:complexType name="AbstractQueryExpressionType" abstract="true">
+      <xsd:attribute name="handle" type="xsd:string"/>
+   </xsd:complexType>
+
+   <xsd:element name="AbstractAdhocQueryExpression"
+                type="fes:AbstractAdhocQueryExpressionType"
+                substitutionGroup="fes:AbstractQueryExpression"
+                abstract="true"/>
+   <xsd:complexType name="AbstractAdhocQueryExpressionType" abstract="true">
+      <xsd:complexContent>
+         <xsd:extension base="fes:AbstractQueryExpressionType">
+            <xsd:sequence>
+               <xsd:element ref="fes:AbstractProjectionClause"
+                            minOccurs="0" maxOccurs="unbounded"/>
+               <xsd:element ref="fes:AbstractSelectionClause" minOccurs="0"/>
+               <xsd:element ref="fes:AbstractSortingClause" minOccurs="0"/>
+            </xsd:sequence>
+            <xsd:attribute name="typeNames"
+                           type="fes:TypeNamesListType" use="required"/>
+            <xsd:attribute name="aliases"
+                           type="fes:AliasesType"/>
+         </xsd:extension>
+      </xsd:complexContent>
+   </xsd:complexType>
+
+   <xsd:simpleType name="TypeNamesListType">
+       <xsd:list itemType="fes:TypeNamesType"/>
+   </xsd:simpleType>
+   <xsd:simpleType name="TypeNamesType">
+       <xsd:union memberTypes="fes:SchemaElement xsd:QName"/>
+   </xsd:simpleType>
+   <xsd:simpleType name="SchemaElement">
+      <xsd:restriction base="xsd:string">
+         <xsd:pattern value="schema\-element\(.+\)"/>
+      </xsd:restriction>
+   </xsd:simpleType>
+   <xsd:simpleType name="AliasesType">
+      <xsd:list itemType="xsd:NCName"/>
+   </xsd:simpleType>
+
+   <xsd:element name="AbstractProjectionClause" abstract="true"/>
+   <xsd:complexType name="AbstractProjectionClauseType" abstract="true"/>
+
+   <xsd:element name="AbstractSelectionClause" abstract="true"/>
+   <xsd:complexType name="AbstractSelectionClauseType" abstract="true"/>
+
+   <xsd:element name="AbstractSortingClause" abstract="true"/>
+   <xsd:complexType name="AbstractSortingClauseType" abstract="true"/>
+
+</xsd:schema>
diff --git a/pycsw/schemas/ogc/filter/1.1.0/sort.xsd b/pycsw/core/schemas/ogc/filter/2.0/sort.xsd
similarity index 54%
rename from pycsw/schemas/ogc/filter/1.1.0/sort.xsd
rename to pycsw/core/schemas/ogc/filter/2.0/sort.xsd
index 0890182..ced3aae 100644
--- a/pycsw/schemas/ogc/filter/1.1.0/sort.xsd
+++ b/pycsw/core/schemas/ogc/filter/2.0/sort.xsd
@@ -1,23 +1,29 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <xsd:schema
-   targetNamespace="http://www.opengis.net/ogc"
-   xmlns:ogc="http://www.opengis.net/ogc"
+   targetNamespace="http://www.opengis.net/fes/2.0"
+   xmlns:fes="http://www.opengis.net/fes/2.0"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    elementFormDefault="qualified"
-   version="1.1.2">
-   <!-- 
-      filter is an OGC Standard.
-      Copyright (c) 2002,2003,2004,2010 Open Geospatial Consortium, Inc. All Rights Reserved.
-      To obtain additional rights of use, visit http://www.opengeospatial.org/legal/ .
-      
-      Updated: 2010-01-22
-   -->
+   version="2.0.2">
+
+   <xsd:annotation>
+      <xsd:documentation>
+         Filter Encoding is an OGC Standard.
+         Copyright (c) 2010, 2014 Open Geospatial Consortium.
+         To obtain additional rights of use, visit http://www.opengeospatial.org/legal/ .
+      </xsd:documentation>
+   </xsd:annotation>
+
+   <xsd:include schemaLocation="filterAll.xsd"/>
+   <xsd:include schemaLocation="query.xsd"/>
    <xsd:include schemaLocation="expr.xsd"/>
 
    <!-- ============================================= -->
    <!-- SORTBY EXPRESSION                             -->
    <!-- ============================================= -->
-   <xsd:element name="SortBy" type="ogc:SortByType"/>
+   <xsd:element name="SortBy"
+                type="fes:SortByType"
+                substitutionGroup="fes:AbstractSortingClause"/>
 
    <!-- ============================================= -->
    <!-- COMPLEX TYPES                                 -->
@@ -25,16 +31,13 @@
    <xsd:complexType name="SortByType">
       <xsd:sequence>
          <xsd:element name="SortProperty"
-                      type="ogc:SortPropertyType"
-                      maxOccurs="unbounded"/>
+                      type="fes:SortPropertyType" maxOccurs="unbounded"/>
       </xsd:sequence>
    </xsd:complexType>
    <xsd:complexType name="SortPropertyType">
       <xsd:sequence>
-         <xsd:element ref="ogc:PropertyName"/>
-         <xsd:element name="SortOrder"
-                      type="ogc:SortOrderType"
-                      minOccurs="0"/>
+         <xsd:element ref="fes:ValueReference"/>
+         <xsd:element name="SortOrder" type="fes:SortOrderType" minOccurs="0"/>
       </xsd:sequence>
    </xsd:complexType>
    <xsd:simpleType name="SortOrderType">
diff --git a/pycsw/schemas/ogc/gml/3.1.1/base/basicTypes.xsd b/pycsw/core/schemas/ogc/gml/3.1.1/base/basicTypes.xsd
similarity index 100%
rename from pycsw/schemas/ogc/gml/3.1.1/base/basicTypes.xsd
rename to pycsw/core/schemas/ogc/gml/3.1.1/base/basicTypes.xsd
diff --git a/pycsw/schemas/ogc/gml/3.1.1/base/coordinateOperations.xsd b/pycsw/core/schemas/ogc/gml/3.1.1/base/coordinateOperations.xsd
similarity index 100%
rename from pycsw/schemas/ogc/gml/3.1.1/base/coordinateOperations.xsd
rename to pycsw/core/schemas/ogc/gml/3.1.1/base/coordinateOperations.xsd
diff --git a/pycsw/schemas/ogc/gml/3.1.1/base/coordinateReferenceSystems.xsd b/pycsw/core/schemas/ogc/gml/3.1.1/base/coordinateReferenceSystems.xsd
similarity index 100%
rename from pycsw/schemas/ogc/gml/3.1.1/base/coordinateReferenceSystems.xsd
rename to pycsw/core/schemas/ogc/gml/3.1.1/base/coordinateReferenceSystems.xsd
diff --git a/pycsw/schemas/ogc/gml/3.1.1/base/coordinateSystems.xsd b/pycsw/core/schemas/ogc/gml/3.1.1/base/coordinateSystems.xsd
similarity index 100%
rename from pycsw/schemas/ogc/gml/3.1.1/base/coordinateSystems.xsd
rename to pycsw/core/schemas/ogc/gml/3.1.1/base/coordinateSystems.xsd
diff --git a/pycsw/schemas/ogc/gml/3.1.1/base/coverage.xsd b/pycsw/core/schemas/ogc/gml/3.1.1/base/coverage.xsd
similarity index 100%
rename from pycsw/schemas/ogc/gml/3.1.1/base/coverage.xsd
rename to pycsw/core/schemas/ogc/gml/3.1.1/base/coverage.xsd
diff --git a/pycsw/schemas/ogc/gml/3.1.1/base/dataQuality.xsd b/pycsw/core/schemas/ogc/gml/3.1.1/base/dataQuality.xsd
similarity index 100%
rename from pycsw/schemas/ogc/gml/3.1.1/base/dataQuality.xsd
rename to pycsw/core/schemas/ogc/gml/3.1.1/base/dataQuality.xsd
diff --git a/pycsw/schemas/ogc/gml/3.1.1/base/datums.xsd b/pycsw/core/schemas/ogc/gml/3.1.1/base/datums.xsd
similarity index 100%
rename from pycsw/schemas/ogc/gml/3.1.1/base/datums.xsd
rename to pycsw/core/schemas/ogc/gml/3.1.1/base/datums.xsd
diff --git a/pycsw/schemas/ogc/gml/3.1.1/base/defaultStyle.xsd b/pycsw/core/schemas/ogc/gml/3.1.1/base/defaultStyle.xsd
similarity index 99%
copy from pycsw/schemas/ogc/gml/3.1.1/base/defaultStyle.xsd
copy to pycsw/core/schemas/ogc/gml/3.1.1/base/defaultStyle.xsd
index 08ecd8f..0648df5 100644
--- a/pycsw/schemas/ogc/gml/3.1.1/base/defaultStyle.xsd
+++ b/pycsw/core/schemas/ogc/gml/3.1.1/base/defaultStyle.xsd
@@ -14,7 +14,7 @@
        includes and imports
 	============================================================== -->
 	<include schemaLocation="measures.xsd"/>
-	<import namespace="http://www.w3.org/2001/SMIL20/" schemaLocation="http://schemas.opengis.net/gml/3.1.1/smil/smil20.xsd"/>
+	<import namespace="http://www.w3.org/2001/SMIL20/" schemaLocation="../smil/smil20.xsd"/>
 	<!-- ==============================================================
       the Style property
 	============================================================== -->
diff --git a/pycsw/schemas/ogc/gml/3.1.1/base/dictionary.xsd b/pycsw/core/schemas/ogc/gml/3.1.1/base/dictionary.xsd
similarity index 100%
rename from pycsw/schemas/ogc/gml/3.1.1/base/dictionary.xsd
rename to pycsw/core/schemas/ogc/gml/3.1.1/base/dictionary.xsd
diff --git a/pycsw/schemas/ogc/gml/3.1.1/base/direction.xsd b/pycsw/core/schemas/ogc/gml/3.1.1/base/direction.xsd
similarity index 100%
rename from pycsw/schemas/ogc/gml/3.1.1/base/direction.xsd
rename to pycsw/core/schemas/ogc/gml/3.1.1/base/direction.xsd
diff --git a/pycsw/schemas/ogc/gml/3.1.1/base/dynamicFeature.xsd b/pycsw/core/schemas/ogc/gml/3.1.1/base/dynamicFeature.xsd
similarity index 100%
rename from pycsw/schemas/ogc/gml/3.1.1/base/dynamicFeature.xsd
rename to pycsw/core/schemas/ogc/gml/3.1.1/base/dynamicFeature.xsd
diff --git a/pycsw/schemas/ogc/gml/3.1.1/base/feature.xsd b/pycsw/core/schemas/ogc/gml/3.1.1/base/feature.xsd
similarity index 100%
rename from pycsw/schemas/ogc/gml/3.1.1/base/feature.xsd
rename to pycsw/core/schemas/ogc/gml/3.1.1/base/feature.xsd
diff --git a/pycsw/schemas/ogc/gml/3.1.1/base/geometryAggregates.xsd b/pycsw/core/schemas/ogc/gml/3.1.1/base/geometryAggregates.xsd
similarity index 100%
rename from pycsw/schemas/ogc/gml/3.1.1/base/geometryAggregates.xsd
rename to pycsw/core/schemas/ogc/gml/3.1.1/base/geometryAggregates.xsd
diff --git a/pycsw/schemas/ogc/gml/3.1.1/base/geometryBasic0d1d.xsd b/pycsw/core/schemas/ogc/gml/3.1.1/base/geometryBasic0d1d.xsd
similarity index 100%
rename from pycsw/schemas/ogc/gml/3.1.1/base/geometryBasic0d1d.xsd
rename to pycsw/core/schemas/ogc/gml/3.1.1/base/geometryBasic0d1d.xsd
diff --git a/pycsw/schemas/ogc/gml/3.1.1/base/geometryBasic2d.xsd b/pycsw/core/schemas/ogc/gml/3.1.1/base/geometryBasic2d.xsd
similarity index 100%
rename from pycsw/schemas/ogc/gml/3.1.1/base/geometryBasic2d.xsd
rename to pycsw/core/schemas/ogc/gml/3.1.1/base/geometryBasic2d.xsd
diff --git a/pycsw/schemas/ogc/gml/3.1.1/base/geometryComplexes.xsd b/pycsw/core/schemas/ogc/gml/3.1.1/base/geometryComplexes.xsd
similarity index 100%
rename from pycsw/schemas/ogc/gml/3.1.1/base/geometryComplexes.xsd
rename to pycsw/core/schemas/ogc/gml/3.1.1/base/geometryComplexes.xsd
diff --git a/pycsw/schemas/ogc/gml/3.1.1/base/geometryPrimitives.xsd b/pycsw/core/schemas/ogc/gml/3.1.1/base/geometryPrimitives.xsd
similarity index 100%
rename from pycsw/schemas/ogc/gml/3.1.1/base/geometryPrimitives.xsd
rename to pycsw/core/schemas/ogc/gml/3.1.1/base/geometryPrimitives.xsd
diff --git a/pycsw/schemas/ogc/gml/3.1.1/base/gml.xsd b/pycsw/core/schemas/ogc/gml/3.1.1/base/gml.xsd
similarity index 100%
copy from pycsw/schemas/ogc/gml/3.1.1/base/gml.xsd
copy to pycsw/core/schemas/ogc/gml/3.1.1/base/gml.xsd
diff --git a/pycsw/schemas/ogc/gml/3.1.1/base/gmlBase.xsd b/pycsw/core/schemas/ogc/gml/3.1.1/base/gmlBase.xsd
similarity index 100%
rename from pycsw/schemas/ogc/gml/3.1.1/base/gmlBase.xsd
rename to pycsw/core/schemas/ogc/gml/3.1.1/base/gmlBase.xsd
diff --git a/pycsw/schemas/ogc/gml/3.1.1/base/grids.xsd b/pycsw/core/schemas/ogc/gml/3.1.1/base/grids.xsd
similarity index 100%
rename from pycsw/schemas/ogc/gml/3.1.1/base/grids.xsd
rename to pycsw/core/schemas/ogc/gml/3.1.1/base/grids.xsd
diff --git a/pycsw/schemas/ogc/gml/3.1.1/base/measures.xsd b/pycsw/core/schemas/ogc/gml/3.1.1/base/measures.xsd
similarity index 100%
rename from pycsw/schemas/ogc/gml/3.1.1/base/measures.xsd
rename to pycsw/core/schemas/ogc/gml/3.1.1/base/measures.xsd
diff --git a/pycsw/schemas/ogc/gml/3.1.1/base/observation.xsd b/pycsw/core/schemas/ogc/gml/3.1.1/base/observation.xsd
similarity index 100%
rename from pycsw/schemas/ogc/gml/3.1.1/base/observation.xsd
rename to pycsw/core/schemas/ogc/gml/3.1.1/base/observation.xsd
diff --git a/pycsw/schemas/ogc/gml/3.1.1/base/referenceSystems.xsd b/pycsw/core/schemas/ogc/gml/3.1.1/base/referenceSystems.xsd
similarity index 100%
rename from pycsw/schemas/ogc/gml/3.1.1/base/referenceSystems.xsd
rename to pycsw/core/schemas/ogc/gml/3.1.1/base/referenceSystems.xsd
diff --git a/pycsw/schemas/ogc/gml/3.1.1/base/temporal.xsd b/pycsw/core/schemas/ogc/gml/3.1.1/base/temporal.xsd
similarity index 100%
rename from pycsw/schemas/ogc/gml/3.1.1/base/temporal.xsd
rename to pycsw/core/schemas/ogc/gml/3.1.1/base/temporal.xsd
diff --git a/pycsw/schemas/ogc/gml/3.1.1/base/temporalReferenceSystems.xsd b/pycsw/core/schemas/ogc/gml/3.1.1/base/temporalReferenceSystems.xsd
similarity index 100%
rename from pycsw/schemas/ogc/gml/3.1.1/base/temporalReferenceSystems.xsd
rename to pycsw/core/schemas/ogc/gml/3.1.1/base/temporalReferenceSystems.xsd
diff --git a/pycsw/schemas/ogc/gml/3.1.1/base/temporalTopology.xsd b/pycsw/core/schemas/ogc/gml/3.1.1/base/temporalTopology.xsd
similarity index 100%
rename from pycsw/schemas/ogc/gml/3.1.1/base/temporalTopology.xsd
rename to pycsw/core/schemas/ogc/gml/3.1.1/base/temporalTopology.xsd
diff --git a/pycsw/schemas/ogc/gml/3.1.1/base/topology.xsd b/pycsw/core/schemas/ogc/gml/3.1.1/base/topology.xsd
similarity index 100%
rename from pycsw/schemas/ogc/gml/3.1.1/base/topology.xsd
rename to pycsw/core/schemas/ogc/gml/3.1.1/base/topology.xsd
diff --git a/pycsw/schemas/ogc/gml/3.1.1/base/units.xsd b/pycsw/core/schemas/ogc/gml/3.1.1/base/units.xsd
similarity index 100%
rename from pycsw/schemas/ogc/gml/3.1.1/base/units.xsd
rename to pycsw/core/schemas/ogc/gml/3.1.1/base/units.xsd
diff --git a/pycsw/schemas/ogc/gml/3.1.1/base/valueObjects.xsd b/pycsw/core/schemas/ogc/gml/3.1.1/base/valueObjects.xsd
similarity index 100%
rename from pycsw/schemas/ogc/gml/3.1.1/base/valueObjects.xsd
rename to pycsw/core/schemas/ogc/gml/3.1.1/base/valueObjects.xsd
diff --git a/pycsw/core/schemas/ogc/gml/3.2.1/SchematronConstraints.xml b/pycsw/core/schemas/ogc/gml/3.2.1/SchematronConstraints.xml
new file mode 100644
index 0000000..6cfd40f
--- /dev/null
+++ b/pycsw/core/schemas/ogc/gml/3.2.1/SchematronConstraints.xml
@@ -0,0 +1,71 @@
+<sch:schema xmlns:sch="http://purl.oclc.org/dsdl/schematron" xmlns:gml="http://www.opengis.net/gml/3.2" xmlns:xlink="http://www.w3.org/1999/xlink" xml:lang="en">
+	<sch:title>Schematron constraints for GML / ISO 19136</sch:title>
+	<sch:ns prefix="sch" uri="http://purl.oclc.org/dsdl/schematron"/>
+	<sch:ns prefix="gml" uri="http://www.opengis.net/gml/3.2"/>
+	<sch:ns prefix="xlink" uri="http://www.w3.org/1999/xlink"/>
+	<sch:pattern>
+		<sch:rule context="gml:ValueArray">
+			<sch:assert test="not(@codeSpace and @uom)">ValueArray may not carry both a reference to a codeSpace and a uom</sch:assert>
+		</sch:rule>
+	</sch:pattern>
+	<sch:pattern>
+		<sch:rule context="gml:ValueArray">
+			<sch:assert test="count(gml:valueComponent/*) = count(gml:valueComponent/*[name() = name(../../gml:valueComponent[1]/*[1])])">All components shall be of the same type</sch:assert>
+			<sch:assert test="count(gml:valueComponents/*) = count(gml:valueComponents/*[name() = name(../*[1])])">All components shall be of the same type</sch:assert>
+		</sch:rule>
+	</sch:pattern>
+	<sch:pattern>
+		<sch:rule context="gml:pos">
+			<sch:assert test="not(@srsDimension) or @srsName">The presence of a dimension attribute implies the presence of the srsName attribute.</sch:assert>
+			<sch:assert test="not(@axisLabels) or @srsName">The presence of an axisLabels attribute implies the presence of the srsName attribute.</sch:assert>
+			<sch:assert test="not(@uomLabels) or @srsName">The presence of an uomLabels attribute implies the presence of the srsName attribute.</sch:assert>
+			<sch:assert test="(not(@uomLabels) and not(@axisLabels)) or (@uomLabels and @axisLabels)">The presence of an uomLabels attribute implies the presence of the axisLabels attribute and vice versa.</sch:assert>
+		</sch:rule>
+	</sch:pattern>
+	<sch:pattern>
+		<sch:rule context="gml:PolyhedralSurface">
+			<sch:assert test="count(gml:patches/*)=count(gml:patches/gml:PolygonPatch)">All patches shall be gml:PolygonPatch elements or an element in the substitution group of gml:PolygonPatch. Note that the test currently does not identify substitutable elements correctly, this will require the use of XPath 2 in the future.</sch:assert>
+		</sch:rule>
+	</sch:pattern>
+	<sch:pattern>
+		<sch:rule context="gml:TriangulatedSurface">
+			<sch:assert test="count(gml:patches/*)=count(gml:patches/gml:Triangle)">All patches shall be gml:Triangle elements or an element in the substitution group of gml:PolygonPatch. Note that the test currently does not identify substitutable elements correctly, this will require the use of XPath 2 in the future.</sch:assert>
+		</sch:rule>
+	</sch:pattern>
+	<sch:pattern>
+		<sch:rule context="gml:abstractStrictAssociationRole">
+			<sch:assert test="not(@xlink:href and (*|text()))">Property element may not carry both a reference to an object and contain an object.</sch:assert>
+			<sch:assert test="@xlink:href | (*|text())">Property element shall either carry a reference to an object or contain an object.</sch:assert>
+		</sch:rule>
+	</sch:pattern>
+	<sch:pattern>
+		<sch:rule context="gml:MultiPointDomain">
+			<sch:assert test="count(gml:domainSet/*)=count(gml:domainSet/gml:MultiPoint)">All values in the domain set shall be gml:MultiPoint elements or an element in its substitution group. Note that the test currently does not identify substitutable elements correctly, this will require the use of XPath 2 in the future.</sch:assert>
+		</sch:rule>
+	</sch:pattern>
+	<sch:pattern>
+		<sch:rule context="gml:MultiCurveDomain">
+			<sch:assert test="count(gml:domainSet/*)=count(gml:domainSet/gml:MultiCurve)">All values in the domain set shall be gml:MultiCurve elements or an element in its substitution group. Note that the test currently does not identify substitutable elements correctly, this will require the use of XPath 2 in the future.</sch:assert>
+		</sch:rule>
+	</sch:pattern>
+	<sch:pattern>
+		<sch:rule context="gml:MultiSurfaceDomain">
+			<sch:assert test="count(gml:domainSet/*)=count(gml:domainSet/gml:MultiSurface)">All values in the domain set shall be gml:MultiSurface elements or an element in its substitution group. Note that the test currently does not identify substitutable elements correctly, this will require the use of XPath 2 in the future.</sch:assert>
+		</sch:rule>
+	</sch:pattern>
+	<sch:pattern>
+		<sch:rule context="gml:MultiSolidDomain">
+			<sch:assert test="count(gml:domainSet/*)=count(gml:domainSet/gml:MultiSolid)">All values in the domain set shall be gml:MultiSolid elements or an element in its substitution group. Note that the test currently does not identify substitutable elements correctly, this will require the use of XPath 2 in the future.</sch:assert>
+		</sch:rule>
+	</sch:pattern>
+	<sch:pattern>
+		<sch:rule context="gml:GridDomain">
+			<sch:assert test="count(gml:domainSet/*)=count(gml:domainSet/gml:Grid)">All values in the domain set shall be gml:Grid elements or an element in its substitution group. Note that the test currently does not identify substitutable elements correctly, this will require the use of XPath 2 in the future.</sch:assert>
+		</sch:rule>
+	</sch:pattern>
+	<sch:pattern>
+		<sch:rule context="gml:RectifiedGridDomain">
+			<sch:assert test="count(gml:domainSet/*)=count(gml:domainSet/gml:RectifiedGrid)">All values in the domain set shall be gml:RectifiedGrid elements or an element in its substitution group. Note that the test currently does not identify substitutable elements correctly, this will require the use of XPath 2 in the future.</sch:assert>
+		</sch:rule>
+	</sch:pattern>
+</sch:schema>
diff --git a/pycsw/core/schemas/ogc/gml/3.2.1/basicTypes.xsd b/pycsw/core/schemas/ogc/gml/3.2.1/basicTypes.xsd
new file mode 100644
index 0000000..d6ffd5f
--- /dev/null
+++ b/pycsw/core/schemas/ogc/gml/3.2.1/basicTypes.xsd
@@ -0,0 +1,268 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<schema targetNamespace="http://www.opengis.net/gml/3.2" xmlns:gml="http://www.opengis.net/gml/3.2" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" version="3.2.1.2">
+	<annotation>
+		<appinfo source="urn:x-ogc:specification:gml:schema-xsd:basicTypes:3.2.1">basicTypes.xsd</appinfo>
+		<documentation>See ISO/DIS 19136 8.2.
+W3C XML Schema provides a set of built-in "simple" types which define methods for representing values as literals without internal markup.  These are described in W3C XML Schema Part 2:2001.  Because GML is an XML encoding in which instances are described using XML Schema, these simple types shall be used as far as possible and practical for the representation of data types.  W3C XML Schema also provides methods for defining 
+-	new simple types by restriction and combination of the built-in types, and 
+-	complex types, with simple content, but which also have XML attributes.  
+In many places where a suitable built-in simple type is not available, simple content types derived using the XML Schema mechanisms are used for the representation of data types in GML.  
+A set of these simple content types that are required by several GML components are defined in the basicTypes schema, as well as some elements based on them. These are primarily based around components needed to record amounts, counts, flags and terms, together with support for exceptions or null values.
+
+GML is an OGC Standard.
+Copyright (c) 2007,2010 Open Geospatial Consortium.
+To obtain additional rights of use, visit http://www.opengeospatial.org/legal/ .
+		</documentation>
+	</annotation>
+	<include schemaLocation="gml.xsd"/>
+	<simpleType name="NilReasonType">
+		<annotation>
+			<documentation>gml:NilReasonType defines a content model that allows recording of an explanation for a void value or other exception.
+gml:NilReasonType is a union of the following enumerated values:
+-	inapplicable there is no value
+-	missing the correct value is not readily available to the sender of this data. Furthermore, a correct value may not exist
+-	template the value will be available later
+-	unknown the correct value is not known to, and not computable by, the sender of this data. However, a correct value probably exists
+-	withheld the value is not divulged
+-	other:text other brief explanation, where text is a string of two or more characters with no included spaces
+and
+-	anyURI which should refer to a resource which describes the reason for the exception
+A particular community may choose to assign more detailed semantics to the standard values provided. Alternatively, the URI method enables a specific or more complete explanation for the absence of a value to be provided elsewhere and indicated by-reference in an instance document.
+gml:NilReasonType is used as a member of a union in a number of simple content types where it is necessary to permit a value from the NilReasonType union as an alternative to the primary type.</documentation>
+		</annotation>
+		<union memberTypes="gml:NilReasonEnumeration anyURI"/>
+	</simpleType>
+	<simpleType name="NilReasonEnumeration">
+		<union>
+			<simpleType>
+				<restriction base="string">
+					<enumeration value="inapplicable"/>
+					<enumeration value="missing"/>
+					<enumeration value="template"/>
+					<enumeration value="unknown"/>
+					<enumeration value="withheld"/>
+				</restriction>
+			</simpleType>
+			<simpleType>
+				<restriction base="string">
+					<pattern value="other:\w{2,}"/>
+				</restriction>
+			</simpleType>
+		</union>
+	</simpleType>
+	<simpleType name="SignType">
+		<annotation>
+			<documentation>gml:SignType is a convenience type with values "+" (plus) and "-" (minus).</documentation>
+		</annotation>
+		<restriction base="string">
+			<enumeration value="-"/>
+			<enumeration value="+"/>
+		</restriction>
+	</simpleType>
+	<simpleType name="booleanOrNilReason">
+		<annotation>
+			<documentation>Extension to the respective XML Schema built-in simple type to allow a choice of either a value of the built-in simple type or a reason for a nil value.</documentation>
+		</annotation>
+		<union memberTypes="gml:NilReasonEnumeration boolean anyURI"/>
+	</simpleType>
+	<simpleType name="doubleOrNilReason">
+		<annotation>
+			<documentation>Extension to the respective XML Schema built-in simple type to allow a choice of either a value of the built-in simple type or a reason for a nil value.</documentation>
+		</annotation>
+		<union memberTypes="gml:NilReasonEnumeration double anyURI"/>
+	</simpleType>
+	<simpleType name="integerOrNilReason">
+		<annotation>
+			<documentation>Extension to the respective XML Schema built-in simple type to allow a choice of either a value of the built-in simple type or a reason for a nil value.</documentation>
+		</annotation>
+		<union memberTypes="gml:NilReasonEnumeration integer anyURI"/>
+	</simpleType>
+	<simpleType name="NameOrNilReason">
+		<annotation>
+			<documentation>Extension to the respective XML Schema built-in simple type to allow a choice of either a value of the built-in simple type or a reason for a nil value.</documentation>
+		</annotation>
+		<union memberTypes="gml:NilReasonEnumeration Name anyURI"/>
+	</simpleType>
+	<simpleType name="stringOrNilReason">
+		<annotation>
+			<documentation>Extension to the respective XML Schema built-in simple type to allow a choice of either a value of the built-in simple type or a reason for a nil value.</documentation>
+		</annotation>
+		<union memberTypes="gml:NilReasonEnumeration string anyURI"/>
+	</simpleType>
+	<complexType name="CodeType">
+		<annotation>
+			<documentation>gml:CodeType is a generalized type to be used for a term, keyword or name.
+It adds a XML attribute codeSpace to a term, where the value of the codeSpace attribute (if present) shall indicate a dictionary, thesaurus, classification scheme, authority, or pattern for the term.</documentation>
+		</annotation>
+		<simpleContent>
+			<extension base="string">
+				<attribute name="codeSpace" type="anyURI"/>
+			</extension>
+		</simpleContent>
+	</complexType>
+	<complexType name="CodeWithAuthorityType">
+		<annotation>
+			<documentation>gml:CodeWithAuthorityType requires that the codeSpace attribute is provided in an instance.</documentation>
+		</annotation>
+		<simpleContent>
+			<restriction base="gml:CodeType">
+				<attribute name="codeSpace" type="anyURI" use="required"/>
+			</restriction>
+		</simpleContent>
+	</complexType>
+	<complexType name="MeasureType">
+		<annotation>
+			<documentation>gml:MeasureType supports recording an amount encoded as a value of XML Schema double, together with a units of measure indicated by an attribute uom, short for "units Of measure". The value of the uom attribute identifies a reference system for the amount, usually a ratio or interval scale.</documentation>
+		</annotation>
+		<simpleContent>
+			<extension base="double">
+				<attribute name="uom" type="gml:UomIdentifier" use="required"/>
+			</extension>
+		</simpleContent>
+	</complexType>
+	<simpleType name="UomIdentifier">
+		<annotation>
+			<documentation>The simple type gml:UomIdentifer defines the syntax and value space of the unit of measure identifier.</documentation>
+		</annotation>
+		<union memberTypes="gml:UomSymbol gml:UomURI"/>
+	</simpleType>
+	<simpleType name="UomSymbol">
+		<annotation>
+			<documentation>This type specifies a character string of length at least one, and restricted such that it must not contain any of the following characters: ":" (colon), " " (space), (newline), (carriage return), (tab). This allows values corresponding to familiar abbreviations, such as "kg", "m/s", etc. 
+It is recommended that the symbol be an identifier for a unit of measure as specified in the "Unified Code of Units of Measure" (UCUM) (http://aurora.regenstrief.org/UCUM). This provides a set of symbols and a grammar for constructing identifiers for units of measure that are unique, and may be easily entered with a keyboard supporting the limited character set known as 7-bit ASCII. ISO 2955 formerly provided a specification with this scope, but was withdrawn in 2001. UCUM largely follow [...]
+		</annotation>
+		<restriction base="string">
+			<pattern value="[^: \n\r\t]+"/>
+		</restriction>
+	</simpleType>
+	<simpleType name="UomURI">
+		<annotation>
+			<documentation>This type specifies a URI, restricted such that it must start with one of the following sequences: "#", "./", "../", or a string of characters followed by a ":". These patterns ensure that the most common URI forms are supported, including absolute and relative URIs and URIs that are simple fragment identifiers, but prohibits certain forms of relative URI that could be mistaken for unit of measure symbol . 
+NOTE	It is possible to re-write such a relative URI to conform to the restriction (e.g. "./m/s").
+In an instance document, on elements of type gml:MeasureType the mandatory uom attribute shall carry a value corresponding to either 
+-	a conventional unit of measure symbol,
+-	a link to a definition of a unit of measure that does not have a conventional symbol, or when it is desired to indicate a precise or variant definition.</documentation>
+		</annotation>
+		<restriction base="anyURI">
+			<pattern value="([a-zA-Z][a-zA-Z0-9\-\+\.]*:|\.\./|\./|#).*"/>
+		</restriction>
+	</simpleType>
+	<complexType name="CoordinatesType">
+		<annotation>
+			<documentation>This type is deprecated for tuples with ordinate values that are numbers.
+CoordinatesType is a text string, intended to be used to record an array of tuples or coordinates. 
+While it is not possible to enforce the internal structure of the string through schema validation, some optional attributes have been provided in previous versions of GML to support a description of the internal structure. These attributes are deprecated. The attributes were intended to be used as follows:
+Decimal	symbol used for a decimal point (default="." a stop or period)
+cs        	symbol used to separate components within a tuple or coordinate string (default="," a comma)
+ts        	symbol used to separate tuples or coordinate strings (default=" " a space)
+Since it is based on the XML Schema string type, CoordinatesType may be used in the construction of tables of tuples or arrays of tuples, including ones that contain mixed text and numeric values.</documentation>
+		</annotation>
+		<simpleContent>
+			<extension base="string">
+				<attribute name="decimal" type="string" default="."/>
+				<attribute name="cs" type="string" default=","/>
+				<attribute name="ts" type="string" default="&#x20;"/>
+			</extension>
+		</simpleContent>
+	</complexType>
+	<simpleType name="booleanList">
+		<annotation>
+			<documentation>A type for a list of values of the respective simple type.</documentation>
+		</annotation>
+		<list itemType="boolean"/>
+	</simpleType>
+	<simpleType name="doubleList">
+		<annotation>
+			<documentation>A type for a list of values of the respective simple type.</documentation>
+		</annotation>
+		<list itemType="double"/>
+	</simpleType>
+	<simpleType name="integerList">
+		<annotation>
+			<documentation>A type for a list of values of the respective simple type.</documentation>
+		</annotation>
+		<list itemType="integer"/>
+	</simpleType>
+	<simpleType name="NameList">
+		<annotation>
+			<documentation>A type for a list of values of the respective simple type.</documentation>
+		</annotation>
+		<list itemType="Name"/>
+	</simpleType>
+	<simpleType name="NCNameList">
+		<annotation>
+			<documentation>A type for a list of values of the respective simple type.</documentation>
+		</annotation>
+		<list itemType="NCName"/>
+	</simpleType>
+	<simpleType name="QNameList">
+		<annotation>
+			<documentation>A type for a list of values of the respective simple type.</documentation>
+		</annotation>
+		<list itemType="QName"/>
+	</simpleType>
+	<simpleType name="booleanOrNilReasonList">
+		<annotation>
+			<documentation>A type for a list of values of the respective simple type.</documentation>
+		</annotation>
+		<list itemType="gml:booleanOrNilReason"/>
+	</simpleType>
+	<simpleType name="NameOrNilReasonList">
+		<annotation>
+			<documentation>A type for a list of values of the respective simple type.</documentation>
+		</annotation>
+		<list itemType="gml:NameOrNilReason"/>
+	</simpleType>
+	<simpleType name="doubleOrNilReasonList">
+		<annotation>
+			<documentation>A type for a list of values of the respective simple type.</documentation>
+		</annotation>
+		<list itemType="gml:doubleOrNilReason"/>
+	</simpleType>
+	<simpleType name="integerOrNilReasonList">
+		<annotation>
+			<documentation>A type for a list of values of the respective simple type.</documentation>
+		</annotation>
+		<list itemType="gml:integerOrNilReason"/>
+	</simpleType>
+	<complexType name="CodeListType">
+		<annotation>
+			<documentation>gml:CodeListType provides for lists of terms. The values in an instance element shall all be valid according to the rules of the dictionary, classification scheme, or authority identified by the value of its codeSpace attribute.</documentation>
+		</annotation>
+		<simpleContent>
+			<extension base="gml:NameList">
+				<attribute name="codeSpace" type="anyURI"/>
+			</extension>
+		</simpleContent>
+	</complexType>
+	<complexType name="CodeOrNilReasonListType">
+		<annotation>
+			<documentation>gml:CodeOrNilReasonListType provides for lists of terms. The values in an instance element shall all be valid according to the rules of the dictionary, classification scheme, or authority identified by the value of its codeSpace attribute. An instance element may also include embedded values from NilReasonType. It is intended to be used in situations where a term or classification is expected, but the value may be absent for some reason.</documentation>
+		</annotation>
+		<simpleContent>
+			<extension base="gml:NameOrNilReasonList">
+				<attribute name="codeSpace" type="anyURI"/>
+			</extension>
+		</simpleContent>
+	</complexType>
+	<complexType name="MeasureListType">
+		<annotation>
+			<documentation>gml:MeasureListType provides for a list of quantities.</documentation>
+		</annotation>
+		<simpleContent>
+			<extension base="gml:doubleList">
+				<attribute name="uom" type="gml:UomIdentifier" use="required"/>
+			</extension>
+		</simpleContent>
+	</complexType>
+	<complexType name="MeasureOrNilReasonListType">
+		<annotation>
+			<documentation>gml:MeasureOrNilReasonListType provides for a list of quantities. An instance element may also include embedded values from NilReasonType. It is intended to be used in situations where a value is expected, but the value may be absent for some reason.</documentation>
+		</annotation>
+		<simpleContent>
+			<extension base="gml:doubleOrNilReasonList">
+				<attribute name="uom" type="gml:UomIdentifier" use="required"/>
+			</extension>
+		</simpleContent>
+	</complexType>
+</schema>
diff --git a/pycsw/core/schemas/ogc/gml/3.2.1/coordinateOperations.xsd b/pycsw/core/schemas/ogc/gml/3.2.1/coordinateOperations.xsd
new file mode 100644
index 0000000..73b757b
--- /dev/null
+++ b/pycsw/core/schemas/ogc/gml/3.2.1/coordinateOperations.xsd
@@ -0,0 +1,525 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<schema targetNamespace="http://www.opengis.net/gml/3.2" elementFormDefault="qualified" xml:lang="en" xmlns:gml="http://www.opengis.net/gml/3.2" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns="http://www.w3.org/2001/XMLSchema" version="3.2.1.2">
+	<annotation>
+		<appinfo source="urn:x-ogc:specification:gml:schema-xsd:coordinateOperations:3.2.1">coordinateOperations.xsd</appinfo>
+		<documentation>See ISO/DIS 19136 13.6.
+The spatial or temporal coordinate operations schema components can be divided into five logical parts, which define elements and types for XML encoding of the definitions of:
+-	Multiple abstract coordinate operations
+-	Multiple concrete types of coordinate operations, including Transformations and Conversions
+-	Abstract and concrete parameter values and groups
+-	Operation methods
+-	Abstract and concrete operation parameters and groups
+These schema component encodes the Coordinate Operation package of the UML Model for ISO 19111 Clause 11.
+
+GML is an OGC Standard.
+Copyright (c) 2007,2010 Open Geospatial Consortium.
+To obtain additional rights of use, visit http://www.opengeospatial.org/legal/ .
+		</documentation>
+	</annotation>
+	<include schemaLocation="gml.xsd"/>
+	<include schemaLocation="referenceSystems.xsd"/>
+	<include schemaLocation="measures.xsd"/>
+	<import namespace="http://www.isotc211.org/2005/gmd" schemaLocation="../../../../../plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gmd/gmd.xsd"/>
+	<element name="AbstractCoordinateOperation" type="gml:AbstractCoordinateOperationType" abstract="true" substitutionGroup="gml:Definition">
+		<annotation>
+			<documentation>gml:AbstractCoordinateOperation is a mathematical operation on coordinates that transforms or converts coordinates to another coordinate reference system. Many but not all coordinate operations (from CRS A to CRS B) also uniquely define the inverse operation (from CRS B to CRS A). In some cases, the operation method algorithm for the inverse operation is the same as for the forward algorithm, but the signs of some operation parameter values shall be reversed. In other c [...]
+The optional coordinateOperationAccuracy property elements provide estimates of the impact of this coordinate operation on point position accuracy.</documentation>
+		</annotation>
+	</element>
+	<complexType name="AbstractCoordinateOperationType" abstract="true">
+		<complexContent>
+			<extension base="gml:IdentifiedObjectType">
+				<sequence>
+					<element ref="gml:domainOfValidity" minOccurs="0"/>
+					<element ref="gml:scope" maxOccurs="unbounded"/>
+					<element ref="gml:operationVersion" minOccurs="0"/>
+					<element ref="gml:coordinateOperationAccuracy" minOccurs="0" maxOccurs="unbounded"/>
+					<element ref="gml:sourceCRS" minOccurs="0"/>
+					<element ref="gml:targetCRS" minOccurs="0"/>
+				</sequence>
+			</extension>
+		</complexContent>
+	</complexType>
+	<element name="operationVersion" type="string">
+		<annotation>
+			<documentation>gml:operationVersion is the version of the coordinate transformation (i.e., instantiation due to the stochastic nature of the parameters). Mandatory when describing a transformation, and should not be supplied for a conversion.</documentation>
+		</annotation>
+	</element>
+	<element name="coordinateOperationAccuracy">
+		<annotation>
+			<documentation>gml:coordinateOperationAccuracy is an association role to a DQ_PositionalAccuracy object as encoded in ISO/TS 19139, either referencing or containing the definition of that positional accuracy. That object contains an estimate of the impact of this coordinate operation on point accuracy. That is, it gives position error estimates for the target coordinates of this coordinate operation, assuming no errors in the source coordinates.</documentation>
+		</annotation>
+		<complexType>
+			<sequence minOccurs="0">
+				<element ref="gmd:AbstractDQ_PositionalAccuracy"/>
+			</sequence>
+			<attributeGroup ref="gml:AssociationAttributeGroup"/>
+		</complexType>
+	</element>
+	<element name="sourceCRS" type="gml:CRSPropertyType">
+		<annotation>
+			<documentation>gml:sourceCRS is an association role to the source CRS (coordinate reference system) of this coordinate operation.</documentation>
+		</annotation>
+	</element>
+	<element name="targetCRS" type="gml:CRSPropertyType">
+		<annotation>
+			<documentation>gml:targetCRS is an association role to the target CRS (coordinate reference system) of this coordinate operation.</documentation>
+		</annotation>
+	</element>
+	<complexType name="CoordinateOperationPropertyType">
+		<annotation>
+			<documentation>gml:CoordinateOperationPropertyType is a property type for association roles to a coordinate operation, either referencing or containing the definition of that coordinate operation.</documentation>
+		</annotation>
+		<sequence minOccurs="0">
+			<element ref="gml:AbstractCoordinateOperation"/>
+		</sequence>
+		<attributeGroup ref="gml:AssociationAttributeGroup"/>
+	</complexType>
+	<element name="AbstractSingleOperation" type="gml:AbstractCoordinateOperationType" abstract="true" substitutionGroup="gml:AbstractCoordinateOperation">
+		<annotation>
+			<documentation>gml:AbstractSingleOperation is a single (not concatenated) coordinate operation.</documentation>
+		</annotation>
+	</element>
+	<complexType name="SingleOperationPropertyType">
+		<annotation>
+			<documentation>gml:SingleOperationPropertyType is a property type for association roles to a single operation, either referencing or containing the definition of that single operation.</documentation>
+		</annotation>
+		<sequence minOccurs="0">
+			<element ref="gml:AbstractSingleOperation"/>
+		</sequence>
+		<attributeGroup ref="gml:AssociationAttributeGroup"/>
+	</complexType>
+	<element name="AbstractGeneralConversion" type="gml:AbstractGeneralConversionType" abstract="true" substitutionGroup="gml:AbstractOperation">
+		<annotation>
+			<documentation>gm:AbstractGeneralConversion is an abstract operation on coordinates that does not include any change of datum. The best-known example of a coordinate conversion is a map projection. The parameters describing coordinate conversions are defined rather than empirically derived. Note that some conversions have no parameters. The operationVersion, sourceCRS, and targetCRS elements are omitted in a coordinate conversion.
+This abstract complex type is expected to be extended for well-known operation methods with many Conversion instances, in GML Application Schemas that define operation-method-specialized element names and contents. This conversion uses an operation method, usually with associated parameter values. However, operation methods and parameter values are directly associated with concrete subtypes, not with this abstract type. All concrete types derived from this type shall extend this type to  [...]
+		</annotation>
+	</element>
+	<complexType name="AbstractGeneralConversionType" abstract="true">
+		<complexContent>
+			<restriction base="gml:AbstractCoordinateOperationType">
+				<sequence>
+					<element ref="gml:metaDataProperty" minOccurs="0" maxOccurs="unbounded"/>
+					<element ref="gml:description" minOccurs="0"/>
+					<element ref="gml:descriptionReference" minOccurs="0"/>
+					<element ref="gml:identifier"/>
+					<element ref="gml:name" minOccurs="0" maxOccurs="unbounded"/>
+					<element ref="gml:remarks" minOccurs="0"/>
+					<element ref="gml:domainOfValidity" minOccurs="0"/>
+					<element ref="gml:scope" maxOccurs="unbounded"/>
+					<element ref="gml:coordinateOperationAccuracy" minOccurs="0" maxOccurs="unbounded"/>
+				</sequence>
+				<attribute ref="gml:id" use="required"/>
+			</restriction>
+		</complexContent>
+	</complexType>
+	<complexType name="GeneralConversionPropertyType">
+		<annotation>
+			<documentation>gml:GeneralConversionPropertyType is a property type for association roles to a general conversion, either referencing or containing the definition of that conversion.</documentation>
+		</annotation>
+		<sequence minOccurs="0">
+			<element ref="gml:AbstractGeneralConversion"/>
+		</sequence>
+		<attributeGroup ref="gml:AssociationAttributeGroup"/>
+	</complexType>
+	<element name="AbstractGeneralTransformation" type="gml:AbstractGeneralTransformationType" abstract="true" substitutionGroup="gml:AbstractOperation">
+		<annotation>
+			<documentation>gml:AbstractGeneralTransformation is an abstract operation on coordinates that usually includes a change of Datum. The parameters of a coordinate transformation are empirically derived from data containing the coordinates of a series of points in both coordinate reference systems. This computational process is usually "over-determined", allowing derivation of error (or accuracy) estimates for the transformation. Also, the stochastic nature of the parameters may result i [...]
+This abstract complex type is expected to be extended for well-known operation methods with many Transformation instances, in Application Schemas that define operation-method-specialized value element names and contents. This transformation uses an operation method with associated parameter values. However, operation methods and parameter values are directly associated with concrete subtypes, not with this abstract type. All concrete types derived from this type shall extend this type to [...]
+		</annotation>
+	</element>
+	<complexType name="AbstractGeneralTransformationType" abstract="true">
+		<complexContent>
+			<restriction base="gml:AbstractCoordinateOperationType">
+				<sequence>
+					<element ref="gml:metaDataProperty" minOccurs="0" maxOccurs="unbounded"/>
+					<element ref="gml:description" minOccurs="0"/>
+					<element ref="gml:descriptionReference" minOccurs="0"/>
+					<element ref="gml:identifier"/>
+					<element ref="gml:name" minOccurs="0" maxOccurs="unbounded"/>
+					<element ref="gml:remarks" minOccurs="0"/>
+					<element ref="gml:domainOfValidity" minOccurs="0"/>
+					<element ref="gml:scope" maxOccurs="unbounded"/>
+					<element ref="gml:operationVersion"/>
+					<element ref="gml:coordinateOperationAccuracy" minOccurs="0" maxOccurs="unbounded"/>
+					<element ref="gml:sourceCRS"/>
+					<element ref="gml:targetCRS"/>
+				</sequence>
+				<attribute ref="gml:id" use="required"/>
+			</restriction>
+		</complexContent>
+	</complexType>
+	<complexType name="GeneralTransformationPropertyType">
+		<annotation>
+			<documentation>gml:GeneralTransformationPropertyType is a property type for association roles to a general transformation, either referencing or containing the definition of that transformation.</documentation>
+		</annotation>
+		<sequence minOccurs="0">
+			<element ref="gml:AbstractGeneralTransformation"/>
+		</sequence>
+		<attributeGroup ref="gml:AssociationAttributeGroup"/>
+	</complexType>
+	<element name="ConcatenatedOperation" type="gml:ConcatenatedOperationType" substitutionGroup="gml:AbstractCoordinateOperation"/>
+	<complexType name="ConcatenatedOperationType">
+		<annotation>
+			<documentation>gml:ConcatenatedOperation is an ordered sequence of two or more coordinate operations. This sequence of operations is constrained by the requirement that the source coordinate reference system of step (n+1) must be the same as the target coordinate reference system of step (n). The source coordinate reference system of the first step and the target coordinate reference system of the last step are the source and target coordinate reference system associated with the conc [...]
+The gml:coordOperation property elements are an ordered sequence of associations to the two or more operations used by this concatenated operation. The AggregationAttributeGroup should be used to specify that the coordOperation associations are ordered.</documentation>
+		</annotation>
+		<complexContent>
+			<extension base="gml:AbstractCoordinateOperationType">
+				<sequence>
+					<element ref="gml:coordOperation" minOccurs="2" maxOccurs="unbounded"/>
+				</sequence>
+				<attributeGroup ref="gml:AggregationAttributeGroup"/>
+			</extension>
+		</complexContent>
+	</complexType>
+	<element name="coordOperation" type="gml:CoordinateOperationPropertyType">
+		<annotation>
+			<documentation>gml:coordOperation is an association role to a coordinate operation.</documentation>
+		</annotation>
+	</element>
+	<complexType name="ConcatenatedOperationPropertyType">
+		<annotation>
+			<documentation>gml:ConcatenatedOperationPropertyType is a property type for association roles to a concatenated operation, either referencing or containing the definition of that concatenated operation.</documentation>
+		</annotation>
+		<sequence minOccurs="0">
+			<element ref="gml:ConcatenatedOperation"/>
+		</sequence>
+		<attributeGroup ref="gml:AssociationAttributeGroup"/>
+	</complexType>
+	<element name="PassThroughOperation" type="gml:PassThroughOperationType" substitutionGroup="gml:AbstractSingleOperation">
+		<annotation>
+			<documentation>gml:PassThroughOperation is a pass-through operation specifies that a subset of a coordinate tuple is subject to a specific coordinate operation.
+The modifiedCoordinate property elements are an ordered sequence of positive integers defining the positions in a coordinate tuple of the coordinates affected by this pass-through operation. The AggregationAttributeGroup should be used to specify that the modifiedCoordinate elements are ordered.</documentation>
+		</annotation>
+	</element>
+	<complexType name="PassThroughOperationType">
+		<complexContent>
+			<extension base="gml:AbstractCoordinateOperationType">
+				<sequence>
+					<element ref="gml:modifiedCoordinate" maxOccurs="unbounded"/>
+					<element ref="gml:coordOperation"/>
+				</sequence>
+				<attributeGroup ref="gml:AggregationAttributeGroup"/>
+			</extension>
+		</complexContent>
+	</complexType>
+	<element name="modifiedCoordinate" type="positiveInteger">
+		<annotation>
+			<documentation>gml:modifiedCoordinate is a positive integer defining a position in a coordinate tuple.</documentation>
+		</annotation>
+	</element>
+	<complexType name="PassThroughOperationPropertyType">
+		<annotation>
+			<documentation>gml:PassThroughOperationPropertyType is a property type for association roles to a pass through operation, either referencing or containing the definition of that pass through operation.</documentation>
+		</annotation>
+		<sequence minOccurs="0">
+			<element ref="gml:PassThroughOperation"/>
+		</sequence>
+		<attributeGroup ref="gml:AssociationAttributeGroup"/>
+	</complexType>
+	<element name="Conversion" type="gml:ConversionType" substitutionGroup="gml:AbstractGeneralConversion">
+		<annotation>
+			<documentation>gml:Conversion is a concrete operation on coordinates that does not include any change of Datum. The best-known example of a coordinate conversion is a map projection. The parameters describing coordinate conversions are defined rather than empirically derived. Note that some conversions have no parameters.
+This concrete complex type can be used without using a GML Application Schema that defines operation-method-specialized element names and contents, especially for methods with only one Conversion instance.
+The usesValue property elements are an unordered list of composition associations to the set of parameter values used by this conversion operation.</documentation>
+		</annotation>
+	</element>
+	<complexType name="ConversionType">
+		<complexContent>
+			<extension base="gml:AbstractGeneralConversionType">
+				<sequence>
+					<element ref="gml:method"/>
+					<element ref="gml:parameterValue" minOccurs="0" maxOccurs="unbounded"/>
+				</sequence>
+			</extension>
+		</complexContent>
+	</complexType>
+	<element name="method" type="gml:OperationMethodPropertyType">
+		<annotation>
+			<documentation>gml:method is an association role to the operation method used by a coordinate operation.</documentation>
+		</annotation>
+	</element>
+	<element name="parameterValue" type="gml:AbstractGeneralParameterValuePropertyType">
+		<annotation>
+			<documentation>gml:parameterValue is a composition association to a parameter value or group of parameter values used by a coordinate operation.</documentation>
+		</annotation>
+	</element>
+	<complexType name="ConversionPropertyType">
+		<annotation>
+			<documentation>gml:ConversionPropertyType is a property type for association roles to a concrete general-purpose conversion, either referencing or containing the definition of that conversion.</documentation>
+		</annotation>
+		<sequence minOccurs="0">
+			<element ref="gml:Conversion"/>
+		</sequence>
+		<attributeGroup ref="gml:AssociationAttributeGroup"/>
+	</complexType>
+	<element name="Transformation" type="gml:TransformationType" substitutionGroup="gml:AbstractGeneralTransformation">
+		<annotation>
+			<documentation>gml:Transformation is a concrete object element derived from gml:GeneralTransformation (13.6.2.13).
+This concrete object can be used for all operation methods, without using a GML Application Schema that defines operation-method-specialized element names and contents, especially for methods with only one Transformation instance.
+The parameterValue elements are an unordered list of composition associations to the set of parameter values used by this conversion operation.</documentation>
+		</annotation>
+	</element>
+	<complexType name="TransformationType">
+		<complexContent>
+			<extension base="gml:AbstractGeneralTransformationType">
+				<sequence>
+					<element ref="gml:method"/>
+					<element ref="gml:parameterValue" minOccurs="0" maxOccurs="unbounded"/>
+				</sequence>
+			</extension>
+		</complexContent>
+	</complexType>
+	<complexType name="TransformationPropertyType">
+		<annotation>
+			<documentation>gml:TransformationPropertyType is a property type for association roles to a transformation, either referencing or containing the definition of that transformation.</documentation>
+		</annotation>
+		<sequence minOccurs="0">
+			<element ref="gml:Transformation"/>
+		</sequence>
+		<attributeGroup ref="gml:AssociationAttributeGroup"/>
+	</complexType>
+	<element name="AbstractGeneralParameterValue" type="gml:AbstractGeneralParameterValueType" abstract="true" substitutionGroup="gml:AbstractObject">
+		<annotation>
+			<documentation>gml:AbstractGeneralParameterValue is an abstract parameter value or group of parameter values.
+This abstract complexType is expected to be extended and restricted for well-known operation methods with many instances, in Application Schemas that define operation-method-specialized element names and contents. Specific parameter value elements are directly contained in concrete subtypes, not in this abstract type. All concrete types derived from this type shall extend this type to include one "...Value" element with an appropriate type, which should be one of the element types allowe [...]
+		</annotation>
+	</element>
+	<complexType name="AbstractGeneralParameterValueType" abstract="true">
+		<sequence/>
+	</complexType>
+	<complexType name="AbstractGeneralParameterValuePropertyType">
+		<annotation>
+			<documentation>gml:AbstractGeneralParameterValuePropertyType is a  property type for inline association roles to a parameter value or group of parameter values, always containing the values.</documentation>
+		</annotation>
+		<sequence>
+			<element ref="gml:AbstractGeneralParameterValue"/>
+		</sequence>
+	</complexType>
+	<element name="ParameterValue" type="gml:ParameterValueType" substitutionGroup="gml:AbstractGeneralParameterValue">
+		<annotation>
+			<documentation>gml:ParameterValue is a parameter value, an ordered sequence of values, or a reference to a file of parameter values. This concrete complex type may be used for operation methods without using an Application Schema that defines operation-method-specialized element names and contents, especially for methods with only one instance. This complex type may be used, extended, or restricted for well-known operation methods, especially for methods with many instances.</documentation>
+		</annotation>
+	</element>
+	<complexType name="ParameterValueType">
+		<complexContent>
+			<extension base="gml:AbstractGeneralParameterValueType">
+				<sequence>
+					<choice>
+						<element ref="gml:value"/>
+						<element ref="gml:dmsAngleValue"/>
+						<element ref="gml:stringValue"/>
+						<element ref="gml:integerValue"/>
+						<element ref="gml:booleanValue"/>
+						<element ref="gml:valueList"/>
+						<element ref="gml:integerValueList"/>
+						<element ref="gml:valueFile"/>
+					</choice>
+					<element ref="gml:operationParameter"/>
+				</sequence>
+			</extension>
+		</complexContent>
+	</complexType>
+	<element name="value" type="gml:MeasureType">
+		<annotation>
+			<documentation>gml:value is a numeric value of an operation parameter, with its associated unit of measure.</documentation>
+		</annotation>
+	</element>
+	<element name="stringValue" type="string">
+		<annotation>
+			<documentation>gml:stringValue is a character string value of an operation parameter. A string value does not have an associated unit of measure.</documentation>
+		</annotation>
+	</element>
+	<element name="integerValue" type="positiveInteger">
+		<annotation>
+			<documentation>gml:integerValue is a positive integer value of an operation parameter, usually used for a count. An integer value does not have an associated unit of measure.</documentation>
+		</annotation>
+	</element>
+	<element name="booleanValue" type="boolean">
+		<annotation>
+			<documentation>gml:booleanValue is a boolean value of an operation parameter. A Boolean value does not have an associated unit of measure.</documentation>
+		</annotation>
+	</element>
+	<element name="valueList" type="gml:MeasureListType">
+		<annotation>
+			<documentation>gml:valueList is an ordered sequence of two or more numeric values of an operation parameter list, where each value has the same associated unit of measure. An element of this type contains a space-separated sequence of double values.</documentation>
+		</annotation>
+	</element>
+	<element name="integerValueList" type="gml:integerList">
+		<annotation>
+			<documentation>gml:integerValueList is an ordered sequence of two or more integer values of an operation parameter list, usually used for counts. These integer values do not have an associated unit of measure. An element of this type contains a space-separated sequence of integer values.</documentation>
+		</annotation>
+	</element>
+	<element name="valueFile" type="anyURI">
+		<annotation>
+			<documentation>gml:valueFile is a reference to a file or a part of a file containing one or more parameter values, each numeric value with its associated unit of measure. When referencing a part of a file, that file shall contain multiple identified parts, such as an XML encoded document. Furthermore, the referenced file or part of a file may reference another part of the same or different files, as allowed in XML documents.</documentation>
+		</annotation>
+	</element>
+	<element name="operationParameter" type="gml:OperationParameterPropertyType">
+		<annotation>
+			<documentation>gml:operationParameter is an association role to the operation parameter of which this is a value.</documentation>
+		</annotation>
+	</element>
+	<element name="ParameterValueGroup" type="gml:ParameterValueGroupType" substitutionGroup="gml:AbstractGeneralParameterValue">
+		<annotation>
+			<documentation>gml:ParameterValueGroup is a group of related parameter values. The same group can be repeated more than once in a Conversion, Transformation, or higher level ParameterValueGroup, if those instances contain different values of one or more parameterValues which suitably distinquish among those groups. This concrete complex type can be used for operation methods without using an Application Schema that defines operation-method-specialized element names and contents. This  [...]
+The parameterValue elements are an unordered set of composition association roles to the parameter values and groups of values included in this group.</documentation>
+		</annotation>
+	</element>
+	<complexType name="ParameterValueGroupType">
+		<complexContent>
+			<extension base="gml:AbstractGeneralParameterValueType">
+				<sequence>
+					<element ref="gml:parameterValue" minOccurs="2" maxOccurs="unbounded"/>
+					<element ref="gml:group"/>
+				</sequence>
+			</extension>
+		</complexContent>
+	</complexType>
+	<element name="group" type="gml:OperationParameterGroupPropertyType">
+		<annotation>
+			<documentation>gml:group is an association role to the operation parameter group for which this element provides parameter values.</documentation>
+		</annotation>
+	</element>
+	<element name="OperationMethod" type="gml:OperationMethodType" substitutionGroup="gml:Definition">
+		<annotation>
+			<documentation>gml:OperationMethod is a method (algorithm or procedure) used to perform a coordinate operation. Most operation methods use a number of operation parameters, although some coordinate conversions use none. Each coordinate operation using the method assigns values to these parameters.
+The parameter elements are an unordered list of associations to the set of operation parameters and parameter groups used by this operation method.</documentation>
+		</annotation>
+	</element>
+	<complexType name="OperationMethodType">
+		<complexContent>
+			<extension base="gml:IdentifiedObjectType">
+				<sequence>
+					<choice>
+						<element ref="gml:formulaCitation"/>
+						<element ref="gml:formula"/>
+					</choice>
+					<element ref="gml:sourceDimensions" minOccurs="0"/>
+					<element ref="gml:targetDimensions" minOccurs="0"/>
+					<element ref="gml:parameter" minOccurs="0" maxOccurs="unbounded"/>
+				</sequence>
+			</extension>
+		</complexContent>
+	</complexType>
+	<element name="formulaCitation">
+		<annotation>
+			<documentation>gml:formulaCitation provides a reference to a publication giving the formula(s) or procedure used by an coordinate operation method.</documentation>
+		</annotation>
+		<complexType>
+			<sequence minOccurs="0">
+				<element ref="gmd:CI_Citation"/>
+			</sequence>
+			<attributeGroup ref="gml:AssociationAttributeGroup"/>
+		</complexType>
+	</element>
+	<element name="formula" type="gml:CodeType">
+		<annotation>
+			<documentation>gml:formula Formula(s) or procedure used by an operation method. The use of the codespace attribite has been deprecated. The property value shall be a character string.</documentation>
+		</annotation>
+	</element>
+	<element name="sourceDimensions" type="positiveInteger">
+		<annotation>
+			<documentation>gml:sourceDimensions is the number of dimensions in the source CRS of this operation method.</documentation>
+		</annotation>
+	</element>
+	<element name="targetDimensions" type="positiveInteger">
+		<annotation>
+			<documentation>gml:targetDimensions is the number of dimensions in the target CRS of this operation method.</documentation>
+		</annotation>
+	</element>
+	<element name="parameter" type="gml:AbstractGeneralOperationParameterPropertyType">
+		<annotation>
+			<documentation>gml:parameter is an association to an operation parameter or parameter group.</documentation>
+		</annotation>
+	</element>
+	<complexType name="OperationMethodPropertyType">
+		<annotation>
+			<documentation>gml:OperationMethodPropertyType is a property type for association roles to a concrete general-purpose operation method, either referencing or containing the definition of that method.</documentation>
+		</annotation>
+		<sequence minOccurs="0">
+			<element ref="gml:OperationMethod"/>
+		</sequence>
+		<attributeGroup ref="gml:AssociationAttributeGroup"/>
+	</complexType>
+	<element name="AbstractGeneralOperationParameter" type="gml:AbstractGeneralOperationParameterType" abstract="true" substitutionGroup="gml:Definition">
+		<annotation>
+			<documentation>gml:GeneralOperationParameter is the abstract definition of a parameter or group of parameters used by an operation method.</documentation>
+		</annotation>
+	</element>
+	<complexType name="AbstractGeneralOperationParameterType" abstract="true">
+		<complexContent>
+			<extension base="gml:IdentifiedObjectType">
+				<sequence>
+					<element ref="gml:minimumOccurs" minOccurs="0"/>
+				</sequence>
+			</extension>
+		</complexContent>
+	</complexType>
+	<element name="minimumOccurs" type="nonNegativeInteger">
+		<annotation>
+			<documentation>gml:minimumOccurs is the minimum number of times that values for this parameter group or parameter are required. If this attribute is omitted, the minimum number shall be one.</documentation>
+		</annotation>
+	</element>
+	<complexType name="AbstractGeneralOperationParameterPropertyType">
+		<annotation>
+			<documentation>gml:AbstractGeneralOperationParameterPropertyType is a property type for association roles to an operation parameter or group, either referencing or containing the definition of that parameter or group.</documentation>
+		</annotation>
+		<sequence minOccurs="0">
+			<element ref="gml:AbstractGeneralOperationParameter"/>
+		</sequence>
+		<attributeGroup ref="gml:AssociationAttributeGroup"/>
+	</complexType>
+	<element name="OperationParameter" type="gml:OperationParameterType" substitutionGroup="gml:AbstractGeneralOperationParameter">
+		<annotation>
+			<documentation>gml:OperationParameter is the definition of a parameter used by an operation method. Most parameter values are numeric, but other types of parameter values are possible. This complex type is expected to be used or extended for all operation methods, without defining operation-method-specialized element names.</documentation>
+		</annotation>
+	</element>
+	<complexType name="OperationParameterType">
+		<complexContent>
+			<extension base="gml:AbstractGeneralOperationParameterType">
+				<sequence/>
+			</extension>
+		</complexContent>
+	</complexType>
+	<complexType name="OperationParameterPropertyType">
+		<annotation>
+			<documentation>gml:OperationParameterPropertyType is a property type for association roles to an operation parameter, either referencing or containing the definition of that parameter.</documentation>
+		</annotation>
+		<sequence minOccurs="0">
+			<element ref="gml:OperationParameter"/>
+		</sequence>
+		<attributeGroup ref="gml:AssociationAttributeGroup"/>
+	</complexType>
+	<element name="OperationParameterGroup" type="gml:OperationParameterGroupType" substitutionGroup="gml:AbstractGeneralOperationParameter">
+		<annotation>
+			<documentation>gml:OperationParameterGroup is the definition of a group of parameters used by an operation method. This complex type is expected to be used or extended for all applicable operation methods, without defining operation-method-specialized element names.
+The generalOperationParameter elements are an unordered list of associations to the set of operation parameters that are members of this group.</documentation>
+		</annotation>
+	</element>
+	<complexType name="OperationParameterGroupType">
+		<complexContent>
+			<extension base="gml:AbstractGeneralOperationParameterType">
+				<sequence>
+					<element ref="gml:maximumOccurs" minOccurs="0"/>
+					<element ref="gml:parameter" minOccurs="2" maxOccurs="unbounded"/>
+				</sequence>
+			</extension>
+		</complexContent>
+	</complexType>
+	<element name="maximumOccurs" type="positiveInteger">
+		<annotation>
+			<documentation>gml:maximumOccurs is the maximum number of times that values for this parameter group may be included. If this attribute is omitted, the maximum number shall be one.</documentation>
+		</annotation>
+	</element>
+	<complexType name="OperationParameterGroupPropertyType">
+		<annotation>
+			<documentation>gml:OperationParameterPropertyType is a property type for association roles to an operation parameter group, either referencing or containing the definition of that parameter group.</documentation>
+		</annotation>
+		<sequence minOccurs="0">
+			<element ref="gml:OperationParameterGroup"/>
+		</sequence>
+		<attributeGroup ref="gml:AssociationAttributeGroup"/>
+	</complexType>
+</schema>
diff --git a/pycsw/core/schemas/ogc/gml/3.2.1/coordinateReferenceSystems.xsd b/pycsw/core/schemas/ogc/gml/3.2.1/coordinateReferenceSystems.xsd
new file mode 100644
index 0000000..72a6ced
--- /dev/null
+++ b/pycsw/core/schemas/ogc/gml/3.2.1/coordinateReferenceSystems.xsd
@@ -0,0 +1,373 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<schema targetNamespace="http://www.opengis.net/gml/3.2" xmlns="http://www.w3.org/2001/XMLSchema" xmlns:gml="http://www.opengis.net/gml/3.2" elementFormDefault="qualified" xml:lang="en" version="3.2.1.2">
+	<annotation>
+		<appinfo source="urn:x-ogc:specification:gml:schema-xsd:coordinateReferenceSystems:3.2.1">coordinateReferenceSystems.xsd</appinfo>
+		<documentation>See ISO/DIS 19136 13.3.
+The spatial-temporal coordinate reference systems schema components are divided into two logical parts. One part defines elements and types for XML encoding of abstract coordinate reference systems definitions. The larger part defines specialized constructs for XML encoding of definitions of the multiple concrete types of spatial-temporal coordinate reference systems.
+These schema components encode the Coordinate Reference System packages of the UML Models of ISO 19111 Clause 8 and ISO/DIS 19136 D.3.10, with the exception of the abstract "SC_CRS" class.
+
+GML is an OGC Standard.
+Copyright (c) 2007,2010 Open Geospatial Consortium.
+To obtain additional rights of use, visit http://www.opengeospatial.org/legal/ .
+		</documentation>
+	</annotation>
+	<include schemaLocation="gml.xsd"/>
+	<include schemaLocation="coordinateSystems.xsd"/>
+	<include schemaLocation="datums.xsd"/>
+	<include schemaLocation="coordinateOperations.xsd"/>
+	<element name="AbstractSingleCRS" type="gml:AbstractCRSType" abstract="true" substitutionGroup="gml:AbstractCRS">
+		<annotation>
+			<documentation>gml:AbstractSingleCRS implements a coordinate reference system consisting of one coordinate system and one datum (as opposed to a Compound CRS).</documentation>
+		</annotation>
+	</element>
+	<complexType name="SingleCRSPropertyType">
+		<annotation>
+			<documentation>gml:SingleCRSPropertyType is a property type for association roles to a single coordinate reference system, either referencing or containing the definition of that coordinate reference system.</documentation>
+		</annotation>
+		<sequence minOccurs="0">
+			<element ref="gml:AbstractSingleCRS"/>
+		</sequence>
+		<attributeGroup ref="gml:AssociationAttributeGroup"/>
+	</complexType>
+	<element name="AbstractGeneralDerivedCRS" type="gml:AbstractGeneralDerivedCRSType" abstract="true" substitutionGroup="gml:AbstractSingleCRS">
+		<annotation>
+			<documentation>gml:AbstractGeneralDerivedCRS is a coordinate reference system that is defined by its coordinate conversion from another coordinate reference system. This abstract complex type shall not be used, extended, or restricted, in a GML Application Schema, to define a concrete subtype with a meaning equivalent to a concrete subtype specified in this document.</documentation>
+		</annotation>
+	</element>
+	<complexType name="AbstractGeneralDerivedCRSType" abstract="true">
+		<complexContent>
+			<extension base="gml:AbstractCRSType">
+				<sequence>
+					<element ref="gml:conversion"/>
+				</sequence>
+			</extension>
+		</complexContent>
+	</complexType>
+	<element name="conversion" type="gml:GeneralConversionPropertyType">
+		<annotation>
+			<documentation>gml:conversion is an association role to the coordinate conversion used to define the derived CRS.</documentation>
+		</annotation>
+	</element>
+	<element name="CompoundCRS" type="gml:CompoundCRSType" substitutionGroup="gml:AbstractCRS">
+		<annotation>
+			<documentation>gml:CompundCRS is a coordinate reference system describing the position of points through two or more independent coordinate reference systems. It is associated with a non-repeating sequence of two or more instances of SingleCRS.</documentation>
+		</annotation>
+	</element>
+	<complexType name="CompoundCRSType">
+		<complexContent>
+			<extension base="gml:AbstractCRSType">
+				<sequence>
+					<element ref="gml:componentReferenceSystem" minOccurs="2" maxOccurs="unbounded"/>
+				</sequence>
+				<attributeGroup ref="gml:AggregationAttributeGroup"/>
+			</extension>
+		</complexContent>
+	</complexType>
+	<element name="componentReferenceSystem" type="gml:SingleCRSPropertyType">
+		<annotation>
+			<documentation>The gml:componentReferenceSystem elements are an ordered sequence of associations to all the component coordinate reference systems included in this compound coordinate reference system. The gml:AggregationAttributeGroup should be used to specify that the gml:componentReferenceSystem properties are ordered.</documentation>
+		</annotation>
+	</element>
+	<complexType name="CompoundCRSPropertyType">
+		<annotation>
+			<documentation>gml:CompoundCRSPropertyType is a property type for association roles to a compound coordinate reference system, either referencing or containing the definition of that reference system.</documentation>
+		</annotation>
+		<sequence minOccurs="0">
+			<element ref="gml:CompoundCRS"/>
+		</sequence>
+		<attributeGroup ref="gml:AssociationAttributeGroup"/>
+	</complexType>
+	<element name="GeodeticCRS" type="gml:GeodeticCRSType" substitutionGroup="gml:AbstractSingleCRS"/>
+	<complexType name="GeodeticCRSType">
+		<annotation>
+			<documentation>gml:GeodeticCRS is a coordinate reference system based on a geodetic datum.</documentation>
+		</annotation>
+		<complexContent>
+			<extension base="gml:AbstractCRSType">
+				<sequence>
+					<choice>
+						<element ref="gml:ellipsoidalCS"/>
+						<element ref="gml:cartesianCS"/>
+						<element ref="gml:sphericalCS"/>
+					</choice>
+					<element ref="gml:geodeticDatum"/>
+				</sequence>
+			</extension>
+		</complexContent>
+	</complexType>
+	<element name="ellipsoidalCS" type="gml:EllipsoidalCSPropertyType">
+		<annotation>
+			<documentation>gml:ellipsoidalCS is an association role to the ellipsoidal coordinate system used by this CRS.</documentation>
+		</annotation>
+	</element>
+	<element name="cartesianCS" type="gml:CartesianCSPropertyType">
+		<annotation>
+			<documentation>gml:cartesianCS is an association role to the Cartesian coordinate system used by this CRS.</documentation>
+		</annotation>
+	</element>
+	<element name="sphericalCS" type="gml:SphericalCSPropertyType">
+		<annotation>
+			<documentation>gml:sphericalCS is an association role to the spherical coordinate system used by this CRS.</documentation>
+		</annotation>
+	</element>
+	<element name="geodeticDatum" type="gml:GeodeticDatumPropertyType">
+		<annotation>
+			<documentation>gml:geodeticDatum is an association role to the geodetic datum used by this CRS.
+</documentation>
+		</annotation>
+	</element>
+	<complexType name="GeodeticCRSPropertyType">
+		<annotation>
+			<documentation>gml:GeodeticCRSPropertyType is a property type for association roles to a geodetic coordinate reference system, either referencing or containing the definition of that reference system.</documentation>
+		</annotation>
+		<sequence minOccurs="0">
+			<element ref="gml:GeodeticCRS"/>
+		</sequence>
+		<attributeGroup ref="gml:AssociationAttributeGroup"/>
+	</complexType>
+	<element name="VerticalCRS" type="gml:VerticalCRSType" substitutionGroup="gml:AbstractSingleCRS">
+		<annotation>
+			<documentation>gml:VerticalCRS is a 1D coordinate reference system used for recording heights or depths. Vertical CRSs make use of the direction of gravity to define the concept of height or depth, but the relationship with gravity may not be straightforward. By implication, ellipsoidal heights (h) cannot be captured in a vertical coordinate reference system. Ellipsoidal heights cannot exist independently, but only as an inseparable part of a 3D coordinate tuple defined in a geographi [...]
+		</annotation>
+	</element>
+	<complexType name="VerticalCRSType">
+		<complexContent>
+			<extension base="gml:AbstractCRSType">
+				<sequence>
+					<element ref="gml:verticalCS"/>
+					<element ref="gml:verticalDatum"/>
+				</sequence>
+			</extension>
+		</complexContent>
+	</complexType>
+	<element name="verticalCS" type="gml:VerticalCSPropertyType">
+		<annotation>
+			<documentation>gml:verticalCS is an association role to the vertical coordinate system used by this CRS.</documentation>
+		</annotation>
+	</element>
+	<element name="verticalDatum" type="gml:VerticalDatumPropertyType">
+		<annotation>
+			<documentation>gml:verticalDatum is an association role to the vertical datum used by this CRS.</documentation>
+		</annotation>
+	</element>
+	<complexType name="VerticalCRSPropertyType">
+		<annotation>
+			<documentation>gml:VerticalCRSPropertyType is a property type for association roles to a vertical coordinate reference system, either referencing or containing the definition of that reference system.</documentation>
+		</annotation>
+		<sequence minOccurs="0">
+			<element ref="gml:VerticalCRS"/>
+		</sequence>
+		<attributeGroup ref="gml:AssociationAttributeGroup"/>
+	</complexType>
+	<element name="ProjectedCRS" type="gml:ProjectedCRSType" substitutionGroup="gml:AbstractGeneralDerivedCRS">
+		<annotation>
+			<documentation>gml:ProjectedCRS is a 2D coordinate reference system used to approximate the shape of the earth on a planar surface, but in such a way that the distortion that is inherent to the approximation is carefully controlled and known. Distortion correction is commonly applied to calculated bearings and distances to produce values that are a close match to actual field values.</documentation>
+		</annotation>
+	</element>
+	<complexType name="ProjectedCRSType">
+		<complexContent>
+			<extension base="gml:AbstractGeneralDerivedCRSType">
+				<sequence>
+					<choice>
+						<element ref="gml:baseGeodeticCRS"/>
+						<element ref="gml:baseGeographicCRS"/>
+					</choice>
+					<element ref="gml:cartesianCS"/>
+				</sequence>
+			</extension>
+		</complexContent>
+	</complexType>
+	<element name="baseGeodeticCRS" type="gml:GeodeticCRSPropertyType">
+		<annotation>
+			<documentation>gml:baseGeodeticCRS is an association role to the geodetic coordinate reference system used by this projected CRS.</documentation>
+		</annotation>
+	</element>
+	<complexType name="ProjectedCRSPropertyType">
+		<annotation>
+			<documentation>gml:ProjectedCRSPropertyType is a property type for association roles to a projected coordinate reference system, either referencing or containing the definition of that reference system.</documentation>
+		</annotation>
+		<sequence minOccurs="0">
+			<element ref="gml:ProjectedCRS"/>
+		</sequence>
+		<attributeGroup ref="gml:AssociationAttributeGroup"/>
+	</complexType>
+	<element name="DerivedCRS" type="gml:DerivedCRSType" substitutionGroup="gml:AbstractGeneralDerivedCRS">
+		<annotation>
+			<documentation>gml:DerivedCRS is a single coordinate reference system that is defined by its coordinate conversion from another single coordinate reference system known as the base CRS. The base CRS can be a projected coordinate reference system, if this DerivedCRS is used for a georectified grid coverage as described in ISO 19123, Clause 8.</documentation>
+		</annotation>
+	</element>
+	<complexType name="DerivedCRSType">
+		<complexContent>
+			<extension base="gml:AbstractGeneralDerivedCRSType">
+				<sequence>
+					<element ref="gml:baseCRS"/>
+					<element ref="gml:derivedCRSType"/>
+					<element ref="gml:coordinateSystem"/>
+				</sequence>
+			</extension>
+		</complexContent>
+	</complexType>
+	<element name="baseCRS" type="gml:SingleCRSPropertyType">
+		<annotation>
+			<documentation>gml:baseCRS is an association role to the coordinate reference system used by this derived CRS.</documentation>
+		</annotation>
+	</element>
+	<element name="derivedCRSType" type="gml:CodeWithAuthorityType">
+		<annotation>
+			<documentation>The gml:derivedCRSType property describes the type of a derived coordinate reference system. The required codeSpace attribute shall reference a source of information specifying the values and meanings of all the allowed string values for this property.</documentation>
+		</annotation>
+	</element>
+	<element name="coordinateSystem" type="gml:CoordinateSystemPropertyType">
+		<annotation>
+			<documentation>An association role to the coordinate system used by this CRS.</documentation>
+		</annotation>
+	</element>
+	<complexType name="DerivedCRSPropertyType">
+		<annotation>
+			<documentation>gml:DerivedCRSPropertyType is a property type for association roles to a non-projected derived coordinate reference system, either referencing or containing the definition of that reference system.</documentation>
+		</annotation>
+		<sequence minOccurs="0">
+			<element ref="gml:DerivedCRS"/>
+		</sequence>
+		<attributeGroup ref="gml:AssociationAttributeGroup"/>
+	</complexType>
+	<element name="EngineeringCRS" type="gml:EngineeringCRSType" substitutionGroup="gml:AbstractSingleCRS">
+		<annotation>
+			<documentation>gml:EngineeringCRS is a contextually local coordinate reference system which can be divided into two broad categories:
+-	earth-fixed systems applied to engineering activities on or near the surface of the earth;
+-	CRSs on moving platforms such as road vehicles, vessels, aircraft, or spacecraft, see ISO 19111 8.3.</documentation>
+		</annotation>
+	</element>
+	<complexType name="EngineeringCRSType">
+		<complexContent>
+			<extension base="gml:AbstractCRSType">
+				<sequence>
+					<choice>
+						<element ref="gml:affineCS"/>
+						<element ref="gml:cartesianCS"/>
+						<element ref="gml:cylindricalCS"/>
+						<element ref="gml:linearCS"/>
+						<element ref="gml:polarCS"/>
+						<element ref="gml:sphericalCS"/>
+						<element ref="gml:userDefinedCS"/>
+						<element ref="gml:coordinateSystem">
+							<annotation>
+								<appinfo>deprecated</appinfo>
+							</annotation>
+						</element>
+					</choice>
+					<element ref="gml:engineeringDatum"/>
+				</sequence>
+			</extension>
+		</complexContent>
+	</complexType>
+	<element name="cylindricalCS" type="gml:CylindricalCSPropertyType">
+		<annotation>
+			<documentation>gml:cylindricalCS is an association role to the cylindrical coordinate system used by this CRS.</documentation>
+		</annotation>
+	</element>
+	<element name="linearCS" type="gml:LinearCSPropertyType">
+		<annotation>
+			<documentation>gml:linearCS is an association role to the linear coordinate system used by this CRS.</documentation>
+		</annotation>
+	</element>
+	<element name="polarCS" type="gml:PolarCSPropertyType">
+		<annotation>
+			<documentation>gml:polarCS is an association role to the polar coordinate system used by this CRS.</documentation>
+		</annotation>
+	</element>
+	<element name="userDefinedCS" type="gml:UserDefinedCSPropertyType">
+		<annotation>
+			<documentation>gml:userDefinedCS is an association role to the user defined coordinate system used by this CRS.</documentation>
+		</annotation>
+	</element>
+	<element name="engineeringDatum" type="gml:EngineeringDatumPropertyType">
+		<annotation>
+			<documentation>gml:engineeringDatum is an association role to the engineering datum used by this CRS.</documentation>
+		</annotation>
+	</element>
+	<complexType name="EngineeringCRSPropertyType">
+		<annotation>
+			<documentation>gml:EngineeringCRSPropertyType is a property type for association roles to an engineering coordinate reference system, either referencing or containing the definition of that reference system.</documentation>
+		</annotation>
+		<sequence minOccurs="0">
+			<element ref="gml:EngineeringCRS"/>
+		</sequence>
+		<attributeGroup ref="gml:AssociationAttributeGroup"/>
+	</complexType>
+	<element name="ImageCRS" type="gml:ImageCRSType" substitutionGroup="gml:AbstractSingleCRS">
+		<annotation>
+			<documentation>gml:ImageCRS is an engineering coordinate reference system applied to locations in images. Image coordinate reference systems are treated as a separate sub-type because the definition of the associated image datum contains two attributes not relevant to other engineering datums.</documentation>
+		</annotation>
+	</element>
+	<complexType name="ImageCRSType">
+		<complexContent>
+			<extension base="gml:AbstractCRSType">
+				<sequence>
+					<choice>
+						<element ref="gml:cartesianCS"/>
+						<element ref="gml:affineCS"/>
+						<element ref="gml:usesObliqueCartesianCS"/>
+					</choice>
+					<element ref="gml:imageDatum"/>
+				</sequence>
+			</extension>
+		</complexContent>
+	</complexType>
+	<element name="affineCS" type="gml:AffineCSPropertyType">
+		<annotation>
+			<documentation>gml:affineCS is an association role to the affine coordinate system used by this CRS.</documentation>
+		</annotation>
+	</element>
+	<element name="imageDatum" type="gml:ImageDatumPropertyType">
+		<annotation>
+			<documentation>gml:imageDatum is an association role to the image datum used by this CRS.</documentation>
+		</annotation>
+	</element>
+	<complexType name="ImageCRSPropertyType">
+		<annotation>
+			<documentation>gml:ImageCRSPropertyType is a property type for association roles to an image coordinate reference system, either referencing or containing the definition of that reference system.</documentation>
+		</annotation>
+		<sequence minOccurs="0">
+			<element ref="gml:ImageCRS"/>
+		</sequence>
+		<attributeGroup ref="gml:AssociationAttributeGroup"/>
+	</complexType>
+	<element name="TemporalCRS" type="gml:TemporalCRSType" substitutionGroup="gml:AbstractSingleCRS">
+		<annotation>
+			<documentation>gml:TemporalCRS is a 1D coordinate reference system used for the recording of time.</documentation>
+		</annotation>
+	</element>
+	<complexType name="TemporalCRSType">
+		<complexContent>
+			<extension base="gml:AbstractCRSType">
+				<sequence>
+					<choice>
+						<element ref="gml:timeCS"/>
+						<element ref="gml:usesTemporalCS"/>
+					</choice>
+					<element ref="gml:temporalDatum"/>
+				</sequence>
+			</extension>
+		</complexContent>
+	</complexType>
+	<element name="timeCS" type="gml:TimeCSPropertyType">
+		<annotation>
+			<documentation>gml:timeCS is an association role to the time coordinate system used by this CRS.</documentation>
+		</annotation>
+	</element>
+	<element name="temporalDatum" type="gml:TemporalDatumPropertyType">
+		<annotation>
+			<documentation>gml:temporalDatum is an association role to the temporal datum used by this CRS.</documentation>
+		</annotation>
+	</element>
+	<complexType name="TemporalCRSPropertyType">
+		<annotation>
+			<documentation>gml:TemporalCRSPropertyType is a property type for association roles to a temporal coordinate reference system, either referencing or containing the definition of that reference system.</documentation>
+		</annotation>
+		<sequence minOccurs="0">
+			<element ref="gml:TemporalCRS"/>
+		</sequence>
+		<attributeGroup ref="gml:AssociationAttributeGroup"/>
+	</complexType>
+</schema>
diff --git a/pycsw/core/schemas/ogc/gml/3.2.1/coordinateSystems.xsd b/pycsw/core/schemas/ogc/gml/3.2.1/coordinateSystems.xsd
new file mode 100644
index 0000000..37627f2
--- /dev/null
+++ b/pycsw/core/schemas/ogc/gml/3.2.1/coordinateSystems.xsd
@@ -0,0 +1,297 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<schema targetNamespace="http://www.opengis.net/gml/3.2" xmlns="http://www.w3.org/2001/XMLSchema" xmlns:gml="http://www.opengis.net/gml/3.2" elementFormDefault="qualified" xml:lang="en"  version="3.2.1.2">
+	<annotation>
+		<appinfo source="urn:x-ogc:specification:gml:schema-xsd:coordinateSystems:3.2.1">coordinateSystems.xsd</appinfo>
+		<documentation>See ISO/DIS 19136 13.4.
+The coordinate systems schema components can be divded into  three logical parts, which define elements and types for XML encoding of the definitions of:
+-	Coordinate system axes
+-	Abstract coordinate system
+-	Multiple concrete types of spatial-temporal coordinate systems
+These schema components encode the Coordinate System packages of the UML Models of ISO 19111 Clause 9 and ISO/DIS 19136 D.3.10.
+
+GML is an OGC Standard.
+Copyright (c) 2007,2010 Open Geospatial Consortium.
+To obtain additional rights of use, visit http://www.opengeospatial.org/legal/ .
+		</documentation>
+	</annotation>
+	<include schemaLocation="gml.xsd"/>
+	<include schemaLocation="referenceSystems.xsd"/>
+	<element name="CoordinateSystemAxis" type="gml:CoordinateSystemAxisType" substitutionGroup="gml:Definition">
+		<annotation>
+			<documentation>gml:CoordinateSystemAxis is a definition of a coordinate system axis.</documentation>
+		</annotation>
+	</element>
+	<complexType name="CoordinateSystemAxisType">
+		<complexContent>
+			<extension base="gml:IdentifiedObjectType">
+				<sequence>
+					<element ref="gml:axisAbbrev"/>
+					<element ref="gml:axisDirection"/>
+					<element ref="gml:minimumValue" minOccurs="0"/>
+					<element ref="gml:maximumValue" minOccurs="0"/>
+					<element ref="gml:rangeMeaning" minOccurs="0"/>
+				</sequence>
+				<attribute name="uom" type="gml:UomIdentifier" use="required">
+					<annotation>
+						<documentation>The uom attribute provides an identifier of the unit of measure used for this coordinate system axis. The value of this coordinate in a coordinate tuple shall be recorded using this unit of measure, whenever those coordinates use a coordinate reference system that uses a coordinate system that uses this axis.</documentation>
+					</annotation>
+				</attribute>
+			</extension>
+		</complexContent>
+	</complexType>
+	<element name="axisAbbrev" type="gml:CodeType">
+		<annotation>
+			<documentation>gml:axisAbbrev is the abbreviation used for this coordinate system axis; this abbreviation is also used to identify the coordinates in the coordinate tuple. The codeSpace attribute may reference a source of more information on a set of standardized abbreviations, or on this abbreviation.</documentation>
+		</annotation>
+	</element>
+	<element name="axisDirection" type="gml:CodeWithAuthorityType">
+		<annotation>
+			<documentation>gml:axisDirection is the direction of this coordinate system axis (or in the case of Cartesian projected coordinates, the direction of this coordinate system axis at the origin).
+Within any set of coordinate system axes, only one of each pair of terms may be used. For earth-fixed CRSs, this direction is often approximate and intended to provide a human interpretable meaning to the axis. When a geodetic datum is used, the precise directions of the axes may therefore vary slightly from this approximate direction.
+The codeSpace attribute shall reference a source of information specifying the values and meanings of all the allowed string values for this property.</documentation>
+		</annotation>
+	</element>
+	<element name="minimumValue" type="double">
+		<annotation>
+			<documentation>The gml:minimumValue and gml:maximumValue properties allow the specification of minimum and maximum value normally allowed for this axis, in the unit of measure for the axis. For a continuous angular axis such as longitude, the values wrap-around at this value. Also, values beyond this minimum/maximum can be used for specified purposes, such as in a bounding box. A value of minus infinity shall be allowed for the gml:minimumValue element, a value of plus infiniy for the [...]
+		</annotation>
+	</element>
+	<element name="maximumValue" type="double">
+		<annotation>
+			<documentation>The gml:minimumValue and gml:maximumValue properties allow the specification of minimum and maximum value normally allowed for this axis, in the unit of measure for the axis. For a continuous angular axis such as longitude, the values wrap-around at this value. Also, values beyond this minimum/maximum can be used for specified purposes, such as in a bounding box. A value of minus infinity shall be allowed for the gml:minimumValue element, a value of plus infiniy for the [...]
+		</annotation>
+	</element>
+	<element name="rangeMeaning" type="gml:CodeWithAuthorityType">
+		<annotation>
+			<documentation>gml:rangeMeaning describes the meaning of axis value range specified by gml:minimumValue and gml:maximumValue. This element shall be omitted when both gml:minimumValue and gml:maximumValue are omitted. This element should be included when gml:minimumValue and/or gml:maximumValue are included. If this element is omitted when the gml:minimumValue and/or gml:maximumValue are included, the meaning is unspecified. The codeSpace attribute shall reference a source of informati [...]
+		</annotation>
+	</element>
+	<complexType name="CoordinateSystemAxisPropertyType">
+		<annotation>
+			<documentation>gml:CoordinateSystemAxisPropertyType is a property type for association roles to a coordinate system axis, either referencing or containing the definition of that axis.</documentation>
+		</annotation>
+		<sequence minOccurs="0">
+			<element ref="gml:CoordinateSystemAxis"/>
+		</sequence>
+		<attributeGroup ref="gml:AssociationAttributeGroup"/>
+	</complexType>
+	<element name="AbstractCoordinateSystem" type="gml:AbstractCoordinateSystemType" abstract="true" substitutionGroup="gml:Definition">
+		<annotation>
+			<documentation>gml:AbstractCoordinateSystem is a coordinate system (CS) is the non-repeating sequence of coordinate system axes that spans a given coordinate space. A CS is derived from a set of mathematical rules for specifying how coordinates in a given space are to be assigned to points. The coordinate values in a coordinate tuple shall be recorded in the order in which the coordinate system axes associations are recorded. This abstract complex type shall not be used, extended, or  [...]
+		</annotation>
+	</element>
+	<complexType name="AbstractCoordinateSystemType" abstract="true">
+		<complexContent>
+			<extension base="gml:IdentifiedObjectType">
+				<sequence>
+					<element ref="gml:axis" maxOccurs="unbounded"/>
+				</sequence>
+				<attributeGroup ref="gml:AggregationAttributeGroup"/>
+			</extension>
+		</complexContent>
+	</complexType>
+	<element name="axis" type="gml:CoordinateSystemAxisPropertyType">
+		<annotation>
+			<documentation>The gml:axis property is an association role (ordered sequence) to the coordinate system axes included in this coordinate system. The coordinate values in a coordinate tuple shall be recorded in the order in which the coordinate system axes associations are recorded, whenever those coordinates use a coordinate reference system that uses this coordinate system. The gml:AggregationAttributeGroup should be used to specify that the axis objects are ordered.</documentation>
+		</annotation>
+	</element>
+	<complexType name="CoordinateSystemPropertyType">
+		<annotation>
+			<documentation>gml:CoordinateSystemPropertyType is a property type for association roles to a coordinate system, either referencing or containing the definition of that coordinate system.</documentation>
+		</annotation>
+		<sequence minOccurs="0">
+			<element ref="gml:AbstractCoordinateSystem"/>
+		</sequence>
+		<attributeGroup ref="gml:AssociationAttributeGroup"/>
+	</complexType>
+	<element name="EllipsoidalCS" type="gml:EllipsoidalCSType" substitutionGroup="gml:AbstractCoordinateSystem">
+		<annotation>
+			<documentation>gml:EllipsoidalCS is a two- or three-dimensional coordinate system in which position is specified by geodetic latitude, geodetic longitude, and (in the three-dimensional case) ellipsoidal height. An EllipsoidalCS shall have two or three gml:axis property elements; the number of associations shall equal the dimension of the CS.</documentation>
+		</annotation>
+	</element>
+	<complexType name="EllipsoidalCSType">
+		<complexContent>
+			<extension base="gml:AbstractCoordinateSystemType"/>
+		</complexContent>
+	</complexType>
+	<complexType name="EllipsoidalCSPropertyType">
+		<annotation>
+			<documentation>gml:EllipsoidalCSPropertyType is a property type for association roles to an ellipsoidal coordinate system, either referencing or containing the definition of that coordinate system.</documentation>
+		</annotation>
+		<sequence minOccurs="0">
+			<element ref="gml:EllipsoidalCS"/>
+		</sequence>
+		<attributeGroup ref="gml:AssociationAttributeGroup"/>
+	</complexType>
+	<element name="CartesianCS" type="gml:CartesianCSType" substitutionGroup="gml:AbstractCoordinateSystem">
+		<annotation>
+			<documentation>gml:CartesianCS is a 1-, 2-, or 3-dimensional coordinate system. In the 1-dimensional case, it contains a single straight coordinate axis. In the 2- and 3-dimensional cases gives the position of points relative to orthogonal straight axes. In the multi-dimensional case, all axes shall have the same length unit of measure. A CartesianCS shall have one, two, or three gml:axis property elements.</documentation>
+		</annotation>
+	</element>
+	<complexType name="CartesianCSType">
+		<complexContent>
+			<extension base="gml:AbstractCoordinateSystemType"/>
+		</complexContent>
+	</complexType>
+	<complexType name="CartesianCSPropertyType">
+		<annotation>
+			<documentation>gml:CartesianCSPropertyType is a property type for association roles to a Cartesian coordinate system, either referencing or containing the definition of that coordinate system.</documentation>
+		</annotation>
+		<sequence minOccurs="0">
+			<element ref="gml:CartesianCS"/>
+		</sequence>
+		<attributeGroup ref="gml:AssociationAttributeGroup"/>
+	</complexType>
+	<element name="VerticalCS" type="gml:VerticalCSType" substitutionGroup="gml:AbstractCoordinateSystem">
+		<annotation>
+			<documentation>gml:VerticalCS is a one-dimensional coordinate system used to record the heights or depths of points. Such a coordinate system is usually dependent on the Earth's gravity field, perhaps loosely as when atmospheric pressure is the basis for the vertical coordinate system axis. A VerticalCS shall have one gml:axis property element.</documentation>
+		</annotation>
+	</element>
+	<complexType name="VerticalCSType">
+		<complexContent>
+			<extension base="gml:AbstractCoordinateSystemType"/>
+		</complexContent>
+	</complexType>
+	<complexType name="VerticalCSPropertyType">
+		<annotation>
+			<documentation>gml:VerticalCSPropertyType is a property type for association roles to a vertical coordinate system, either referencing or containing the definition of that coordinate system.</documentation>
+		</annotation>
+		<sequence minOccurs="0">
+			<element ref="gml:VerticalCS"/>
+		</sequence>
+		<attributeGroup ref="gml:AssociationAttributeGroup"/>
+	</complexType>
+	<element name="TimeCS" type="gml:TimeCSType" substitutionGroup="gml:AbstractCoordinateSystem">
+		<annotation>
+			<documentation>gml:TimeCS is a one-dimensional coordinate system containing a time axis, used to describe the temporal position of a point in the specified time units from a specified time origin. A TimeCS shall have one gml:axis property element.</documentation>
+		</annotation>
+	</element>
+	<complexType name="TimeCSType">
+		<complexContent>
+			<extension base="gml:AbstractCoordinateSystemType"/>
+		</complexContent>
+	</complexType>
+	<complexType name="TimeCSPropertyType">
+		<annotation>
+			<documentation>gml:TimeCSPropertyType is a property type for association roles to a time coordinate system, either referencing or containing the definition of that coordinate system.</documentation>
+		</annotation>
+		<sequence minOccurs="0">
+			<element ref="gml:TimeCS"/>
+		</sequence>
+		<attributeGroup ref="gml:AssociationAttributeGroup"/>
+	</complexType>
+	<element name="LinearCS" type="gml:LinearCSType" substitutionGroup="gml:AbstractCoordinateSystem">
+		<annotation>
+			<documentation>gml:LinearCS is a one-dimensional coordinate system that consists of the points that lie on the single axis described. The associated coordinate is the distance – with or without offset – from the specified datum to the point along the axis. A LinearCS shall have one gml:axis property element.</documentation>
+		</annotation>
+	</element>
+	<complexType name="LinearCSType">
+		<complexContent>
+			<extension base="gml:AbstractCoordinateSystemType"/>
+		</complexContent>
+	</complexType>
+	<complexType name="LinearCSPropertyType">
+		<annotation>
+			<documentation>gml:LinearCSPropertyType is a property type for association roles to a linear coordinate system, either referencing or containing the definition of that coordinate system.</documentation>
+		</annotation>
+		<sequence minOccurs="0">
+			<element ref="gml:LinearCS"/>
+		</sequence>
+		<attributeGroup ref="gml:AssociationAttributeGroup"/>
+	</complexType>
+	<element name="UserDefinedCS" type="gml:UserDefinedCSType" substitutionGroup="gml:AbstractCoordinateSystem">
+		<annotation>
+			<documentation>gml:UserDefinedCS is a two- or three-dimensional coordinate system that consists of any combination of coordinate axes not covered by any other coordinate system type. A UserDefinedCS shall have two or three gml:axis property elements; the number of property elements shall equal the dimension of the CS.</documentation>
+		</annotation>
+	</element>
+	<complexType name="UserDefinedCSType">
+		<complexContent>
+			<extension base="gml:AbstractCoordinateSystemType"/>
+		</complexContent>
+	</complexType>
+	<complexType name="UserDefinedCSPropertyType">
+		<annotation>
+			<documentation>gml:UserDefinedCSPropertyType is a property type for association roles to a user-defined coordinate system, either referencing or containing the definition of that coordinate system.</documentation>
+		</annotation>
+		<sequence minOccurs="0">
+			<element ref="gml:UserDefinedCS"/>
+		</sequence>
+		<attributeGroup ref="gml:AssociationAttributeGroup"/>
+	</complexType>
+	<element name="SphericalCS" type="gml:SphericalCSType" substitutionGroup="gml:AbstractCoordinateSystem">
+		<annotation>
+			<documentation>gml:SphericalCS is a three-dimensional coordinate system with one distance measured from the origin and two angular coordinates. A SphericalCS shall have three gml:axis property elements.</documentation>
+		</annotation>
+	</element>
+	<complexType name="SphericalCSType">
+		<complexContent>
+			<extension base="gml:AbstractCoordinateSystemType"/>
+		</complexContent>
+	</complexType>
+	<complexType name="SphericalCSPropertyType">
+		<annotation>
+			<documentation>gml:SphericalCSPropertyType is property type for association roles to a spherical coordinate system, either referencing or containing the definition of that coordinate system.</documentation>
+		</annotation>
+		<sequence minOccurs="0">
+			<element ref="gml:SphericalCS"/>
+		</sequence>
+		<attributeGroup ref="gml:AssociationAttributeGroup"/>
+	</complexType>
+	<element name="PolarCS" type="gml:PolarCSType" substitutionGroup="gml:AbstractCoordinateSystem">
+		<annotation>
+			<documentation>gml:PolarCS ia s two-dimensional coordinate system in which position is specified by the distance from the origin and the angle between the line from the origin to a point and a reference direction. A PolarCS shall have two gml:axis property elements.</documentation>
+		</annotation>
+	</element>
+	<complexType name="PolarCSType">
+		<complexContent>
+			<extension base="gml:AbstractCoordinateSystemType"/>
+		</complexContent>
+	</complexType>
+	<complexType name="PolarCSPropertyType">
+		<annotation>
+			<documentation>gml:PolarCSPropertyType is a property type for association roles to a polar coordinate system, either referencing or containing the definition of that coordinate system.</documentation>
+		</annotation>
+		<sequence minOccurs="0">
+			<element ref="gml:PolarCS"/>
+		</sequence>
+		<attributeGroup ref="gml:AssociationAttributeGroup"/>
+	</complexType>
+	<element name="CylindricalCS" type="gml:CylindricalCSType" substitutionGroup="gml:AbstractCoordinateSystem">
+		<annotation>
+			<documentation>gml:CylindricalCS is a three-dimensional coordinate system consisting of a polar coordinate system extended by a straight coordinate axis perpendicular to the plane spanned by the polar coordinate system. A CylindricalCS shall have three gml:axis property elements.</documentation>
+		</annotation>
+	</element>
+	<complexType name="CylindricalCSType">
+		<complexContent>
+			<extension base="gml:AbstractCoordinateSystemType"/>
+		</complexContent>
+	</complexType>
+	<complexType name="CylindricalCSPropertyType">
+		<annotation>
+			<documentation>gml:CylindricalCSPropertyType is a property type for association roles to a cylindrical coordinate system, either referencing or containing the definition of that coordinate system.</documentation>
+		</annotation>
+		<sequence minOccurs="0">
+			<element ref="gml:CylindricalCS"/>
+		</sequence>
+		<attributeGroup ref="gml:AssociationAttributeGroup"/>
+	</complexType>
+	<element name="AffineCS" type="gml:AffineCSType" substitutionGroup="gml:AbstractCoordinateSystem">
+		<annotation>
+			<documentation>gml:AffineCS is a two- or three-dimensional coordinate system with straight axes that are not necessarily orthogonal. An AffineCS shall have two or three gml:axis property elements; the number of property elements shall equal the dimension of the CS.</documentation>
+		</annotation>
+	</element>
+	<complexType name="AffineCSType">
+		<complexContent>
+			<extension base="gml:AbstractCoordinateSystemType"/>
+		</complexContent>
+	</complexType>
+	<complexType name="AffineCSPropertyType">
+		<annotation>
+			<documentation>gml:AffineCSPropertyType is a property type for association roles to an affine coordinate system, either referencing or containing the definition of that coordinate system.</documentation>
+		</annotation>
+		<sequence minOccurs="0">
+			<element ref="gml:AffineCS"/>
+		</sequence>
+		<attributeGroup ref="gml:AssociationAttributeGroup"/>
+	</complexType>
+</schema>
diff --git a/pycsw/core/schemas/ogc/gml/3.2.1/coverage.xsd b/pycsw/core/schemas/ogc/gml/3.2.1/coverage.xsd
new file mode 100644
index 0000000..a1bbfa4
--- /dev/null
+++ b/pycsw/core/schemas/ogc/gml/3.2.1/coverage.xsd
@@ -0,0 +1,292 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<schema targetNamespace="http://www.opengis.net/gml/3.2" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2001/XMLSchema" xmlns:gml="http://www.opengis.net/gml/3.2" elementFormDefault="qualified" version="3.2.1.2">
+	<annotation>
+		<appinfo source="urn:x-ogc:specification:gml:schema-xsd:coverage:3.2.1">coverage.xsd</appinfo>
+		<documentation>See ISO/DIS 19136 20.3.
+A coverage incorporates a mapping from a spatiotemporal domain to a range set, the latter providing the set in which the attribute values live.  The range set may be an arbitrary set including discrete lists, integer or floating point ranges, and multi-dimensional vector spaces.
+A coverage can be viewed as the graph of the coverage function f:A à B, that is as the set of ordered pairs {(x, f(x)) | where x is in A}. This view is especially applicable to the GML encoding of a coverage.  In the case of a discrete coverage, the domain set A is partitioned into a collection of subsets (typically a disjoint collection) A = UAi and the function f is constant on each Ai. For a spatial domain, the Ai are geometry elements, hence the coverage can be viewed as a collection [...]
+A coverage is implemented as a GML feature. We can thus speak of a "temperature distribution feature", or a "remotely sensed image feature", or a "soil distribution feature".
+As is the case for any GML object, a coverage object may also be the value of a property of a feature.
+
+GML is an OGC Standard.
+Copyright (c) 2007,2010 Open Geospatial Consortium.
+To obtain additional rights of use, visit http://www.opengeospatial.org/legal/ .
+		</documentation>
+	</annotation>
+	<include schemaLocation="gml.xsd"/>
+	<include schemaLocation="feature.xsd"/>
+	<include schemaLocation="valueObjects.xsd"/>
+	<include schemaLocation="grids.xsd"/>
+	<include schemaLocation="geometryAggregates.xsd"/>
+	<complexType name="AbstractCoverageType" abstract="true">
+		<annotation>
+			<documentation>The base type for coverages is gml:AbstractCoverageType. The basic elements of a coverage can be seen in this content model: the coverage contains gml:domainSet and gml:rangeSet properties. The gml:domainSet property describes the domain of the coverage and the gml:rangeSet property describes the range of the coverage.</documentation>
+		</annotation>
+		<complexContent>
+			<extension base="gml:AbstractFeatureType">
+				<sequence>
+					<element ref="gml:domainSet"/>
+					<element ref="gml:rangeSet"/>
+				</sequence>
+			</extension>
+		</complexContent>
+	</complexType>
+	<element name="AbstractCoverage" type="gml:AbstractCoverageType" abstract="true" substitutionGroup="gml:AbstractFeature">
+		<annotation>
+			<documentation>This element serves as the head of a substitution group which may contain any coverage whose type is derived from gml:AbstractCoverageType.  It may act as a variable in the definition of content models where it is required to permit any coverage to be valid.</documentation>
+		</annotation>
+	</element>
+	<complexType name="DiscreteCoverageType">
+		<complexContent>
+			<extension base="gml:AbstractCoverageType">
+				<sequence>
+					<element ref="gml:coverageFunction" minOccurs="0"/>
+				</sequence>
+			</extension>
+		</complexContent>
+	</complexType>
+	<element name="AbstractDiscreteCoverage" type="gml:DiscreteCoverageType" abstract="true" substitutionGroup="gml:AbstractCoverage">
+		<annotation>
+			<documentation>A discrete coverage consists of a domain set, range set and optionally a coverage function. The domain set consists of either spatial or temporal geometry objects, finite in number. The range set is comprised of a finite number of attribute values each of which is associated to every direct position within any single spatiotemporal object in the domain. In other words, the range values are constant on each spatiotemporal object in the domain. This coverage function maps [...]
+This element serves as the head of a substitution group which may contain any discrete coverage whose type is derived from gml:DiscreteCoverageType.</documentation>
+		</annotation>
+	</element>
+	<complexType name="AbstractContinuousCoverageType" abstract="true">
+		<complexContent>
+			<extension base="gml:AbstractCoverageType">
+				<sequence>
+					<element ref="gml:coverageFunction" minOccurs="0"/>
+				</sequence>
+			</extension>
+		</complexContent>
+	</complexType>
+	<element name="AbstractContinuousCoverage" type="gml:AbstractContinuousCoverageType" abstract="true" substitutionGroup="gml:AbstractFeature">
+		<annotation>
+			<documentation>A continuous coverage as defined in ISO 19123 is a coverage that can return different values for the same feature attribute at different direct positions within a single spatiotemporal object in its spatiotemporal domain. The base type for continuous coverages is AbstractContinuousCoverageType.
+The coverageFunction element describes the mapping function. 
+The abstract element gml:AbstractContinuousCoverage serves as the head of a substitution group which may contain any continuous coverage whose type is derived from gml:AbstractContinuousCoverageType.</documentation>
+		</annotation>
+	</element>
+	<element name="domainSet" type="gml:DomainSetType">
+		<annotation>
+			<documentation>The gml:domainSet property element describes the spatio-temporal region of interest, within which the coverage is defined. Its content model is given by gml:DomainSetType.
+The value of the domain is thus a choice between a gml:AbstractGeometry and a gml:AbstractTimeObject.  In the instance these abstract elements will normally be substituted by a geometry complex or temporal complex, to represent spatial coverages and time-series, respectively.  
+The presence of the gml:AssociationAttributeGroup means that domainSet follows the usual GML property model and may use the xlink:href attribute to point to the domain, as an alternative to describing the domain inline. Ownership semantics may be provided using the gml:OwnershipAttributeGroup.
+</documentation>
+		</annotation>
+	</element>
+	<complexType name="DomainSetType">
+		<sequence minOccurs="0">
+			<choice>
+				<element ref="gml:AbstractGeometry"/>
+				<element ref="gml:AbstractTimeObject"/>
+			</choice>
+		</sequence>
+		<attributeGroup ref="gml:OwnershipAttributeGroup"/>
+		<attributeGroup ref="gml:AssociationAttributeGroup"/>
+	</complexType>
+	<element name="rangeSet" type="gml:RangeSetType">
+		<annotation>
+			<documentation>The gml:rangeSet property element contains the values of the coverage (sometimes called the attribute values).  Its content model is given by gml:RangeSetType.
+This content model supports a structural description of the range.  The semantic information describing the range set is embedded using a uniform method, as part of the explicit values, or as a template value accompanying the representation using gml:DataBlock and gml:File.
+The values from each component (or "band") in the range may be encoded within a gml:ValueArray element or a concrete member of the gml:AbstractScalarValueList substitution group . Use of these elements satisfies the value-type homogeneity requirement.</documentation>
+		</annotation>
+	</element>
+	<complexType name="RangeSetType">
+		<choice>
+			<element ref="gml:ValueArray" maxOccurs="unbounded"/>
+			<element ref="gml:AbstractScalarValueList" maxOccurs="unbounded"/>
+			<element ref="gml:DataBlock"/>
+			<element ref="gml:File"/>
+		</choice>
+	</complexType>
+	<element name="DataBlock" type="gml:DataBlockType" substitutionGroup="gml:AbstractObject">
+		<annotation>
+			<documentation>gml:DataBlock describes the Range as a block of text encoded values similar to a Common Separated Value (CSV) representation.
+The range set parameterization is described by the property gml:rangeParameters.</documentation>
+		</annotation>
+	</element>
+	<complexType name="DataBlockType">
+		<sequence>
+			<element ref="gml:rangeParameters"/>
+			<choice>
+				<element ref="gml:tupleList"/>
+				<element ref="gml:doubleOrNilReasonTupleList"/>
+			</choice>
+		</sequence>
+	</complexType>
+	<element name="rangeParameters" type="gml:AssociationRoleType"/>
+	<element name="tupleList" type="gml:CoordinatesType">
+		<annotation>
+			<documentation>gml:CoordinatesType consists of a list of coordinate tuples, with each coordinate tuple separated by the ts or tuple separator (whitespace), and each coordinate in the tuple by the cs or coordinate separator (comma).
+The gml:tupleList encoding is effectively "band-interleaved".</documentation>
+		</annotation>
+	</element>
+	<element name="doubleOrNilReasonTupleList" type="gml:doubleOrNilReasonList">
+		<annotation>
+			<documentation>gml:doubleOrNilReasonList consists of a list of gml:doubleOrNilReason values, each separated by a whitespace. The gml:doubleOrNilReason values are grouped into tuples where the dimension of each tuple in the list is equal to the number of range parameters.</documentation>
+		</annotation>
+	</element>
+	<element name="File" type="gml:FileType" substitutionGroup="gml:AbstractObject">
+		<annotation>
+			<documentation>for efficiency reasons, GML also provides a means of encoding the range set in an arbitrary external encoding, such as a binary file.  This encoding may be "well-known" but this is not required. This mode uses the gml:File element.
+The values of the coverage (attribute values in the range set) are transmitted in a external file that is referenced from the XML structure described by gml:FileType.  The external file is referenced by the gml:fileReference property that is an anyURI (the gml:fileName property has been deprecated).  This means that the external file may be located remotely from the referencing GML instance. 
+The gml:compression property points to a definition of a compression algorithm through an anyURI.  This may be a retrievable, computable definition or simply a reference to an unambiguous name for the compression method.
+The gml:mimeType property points to a definition of the file mime type.
+The gml:fileStructure property is defined by a codelist. Note further that all values shall be enclosed in a single file. Multi-file structures for values are not supported in GML.
+The semantics of the range set is described as above using the gml:rangeParameters property.
+Note that if any compression algorithm is applied, the structure above applies only to the pre-compression or post-decompression structure of the file.
+Note that the fields within a record match the gml:valueComponents of the gml:CompositeValue in document order.</documentation>
+		</annotation>
+	</element>
+	<complexType name="FileType">
+		<sequence>
+			<element ref="gml:rangeParameters"/>
+			<choice>
+				<element name="fileName" type="anyURI">
+					<annotation>
+						<appinfo>deprecated</appinfo>
+					</annotation>
+				</element>
+				<element name="fileReference" type="anyURI"/>
+			</choice>
+			<element name="fileStructure" type="gml:CodeType"/>
+			<element name="mimeType" type="anyURI" minOccurs="0"/>
+			<element name="compression" type="anyURI" minOccurs="0"/>
+		</sequence>
+	</complexType>
+	<element name="coverageFunction" type="gml:CoverageFunctionType" substitutionGroup="gml:AbstractObject">
+		<annotation>
+			<documentation>The gml:coverageFunction property describes the mapping function from the domain to the range of the coverage.
+The value of the CoverageFunction is one of gml:CoverageMappingRule and gml:GridFunction.
+If the gml:coverageFunction property is omitted for a gridded coverage (including rectified gridded coverages) the gml:startPoint is assumed to be the value of the gml:low property in the gml:Grid geometry, and the gml:sequenceRule is assumed to be linear and the gml:axisOrder property is assumed to be "+1 +2".</documentation>
+		</annotation>
+	</element>
+	<complexType name="CoverageFunctionType">
+		<choice>
+			<element ref="gml:MappingRule"/>
+			<element ref="gml:CoverageMappingRule"/>
+			<element ref="gml:GridFunction"/>
+		</choice>
+	</complexType>
+	<element name="CoverageMappingRule" type="gml:MappingRuleType" substitutionGroup="gml:AbstractObject">
+		<annotation>
+			<documentation>gml:CoverageMappingRule provides a formal or informal description of the coverage function.
+The mapping rule may be defined as an in-line string (gml:ruleDefinition) or via a remote reference through xlink:href (gml:ruleReference).  
+If no rule name is specified, the default is 'Linear' with respect to members of the domain in document order.</documentation>
+		</annotation>
+	</element>
+	<complexType name="MappingRuleType" final="#all">
+		<choice>
+			<element name="ruleDefinition" type="string"/>
+			<element name="ruleReference" type="gml:ReferenceType"/>
+		</choice>
+	</complexType>
+	<element name="GridFunction" type="gml:GridFunctionType" substitutionGroup="gml:AbstractObject">
+		<annotation>
+			<documentation>gml:GridFunction provides an explicit mapping rule for grid geometries, i.e. the domain shall be a geometry of type grid.  It describes the mapping of grid posts (discrete point grid coverage) or grid cells (discrete surface coverage) to the values in the range set.
+The gml:startPoint is the index position of a point in the grid that is mapped to the first point in the range set (this is also the index position of the first grid post).  If the gml:startPoint property is omitted the gml:startPoint is assumed to be equal to the value of gml:low in the gml:Grid geometry. Subsequent points in the mapping are determined by the value of the gml:sequenceRule.</documentation>
+		</annotation>
+	</element>
+	<complexType name="GridFunctionType">
+		<sequence>
+			<element name="sequenceRule" type="gml:SequenceRuleType" minOccurs="0"/>
+			<element name="startPoint" type="gml:integerList" minOccurs="0"/>
+		</sequence>
+	</complexType>
+	<complexType name="SequenceRuleType">
+		<annotation>
+			<documentation>The gml:SequenceRuleType is derived from the gml:SequenceRuleEnumeration through the addition of an axisOrder attribute.  The gml:SequenceRuleEnumeration is an enumerated type. The rule names are defined in ISO 19123. If no rule name is specified the default is "Linear".</documentation>
+		</annotation>
+		<simpleContent>
+			<extension base="gml:SequenceRuleEnumeration">
+				<attribute name="order" type="gml:IncrementOrder">
+					<annotation>
+						<appinfo>deprecated</appinfo>
+					</annotation>
+				</attribute>
+				<attribute name="axisOrder" type="gml:AxisDirectionList"/>
+			</extension>
+		</simpleContent>
+	</complexType>
+	<simpleType name="SequenceRuleEnumeration">
+		<restriction base="string">
+			<enumeration value="Linear"/>
+			<enumeration value="Boustrophedonic"/>
+			<enumeration value="Cantor-diagonal"/>
+			<enumeration value="Spiral"/>
+			<enumeration value="Morton"/>
+			<enumeration value="Hilbert"/>
+		</restriction>
+	</simpleType>
+	<simpleType name="AxisDirectionList">
+		<annotation>
+			<documentation>The different values in a gml:AxisDirectionList indicate the incrementation order to be used on all axes of the grid. Each axis shall be mentioned once and only once.</documentation>
+		</annotation>
+		<list itemType="gml:AxisDirection"/>
+	</simpleType>
+	<simpleType name="AxisDirection">
+		<annotation>
+			<documentation>The value of a gml:AxisDirection indicates the incrementation order to be used on an axis of the grid.</documentation>
+		</annotation>
+		<restriction base="string">
+			<pattern value="[\+\-][1-9][0-9]*"/>
+		</restriction>
+	</simpleType>
+	<element name="MultiPointCoverage" type="gml:DiscreteCoverageType" substitutionGroup="gml:AbstractDiscreteCoverage">
+		<annotation>
+			<documentation>In a gml:MultiPointCoverage the domain set is a gml:MultiPoint, that is a collection of arbitrarily distributed geometric points.
+The content model is identical with gml:DiscreteCoverageType, but that gml:domainSet shall have values gml:MultiPoint.
+In a gml:MultiPointCoverage the mapping from the domain to the range is straightforward.
+-	For gml:DataBlock encodings the points of the gml:MultiPoint are mapped in document order to the tuples of the data block.
+-	For gml:CompositeValue encodings the points of the gml:MultiPoint are mapped to the members of the composite value in document order.
+-	For gml:File encodings the points of the gml:MultiPoint are mapped to the records of the file in sequential order.
+</documentation>
+		</annotation>
+	</element>
+	<element name="MultiCurveCoverage" type="gml:DiscreteCoverageType" substitutionGroup="gml:AbstractDiscreteCoverage">
+		<annotation>
+			<documentation>In a gml:MultiCurveCoverage the domain is partioned into a collection of curves comprising a gml:MultiCurve.  The coverage function then maps each curve in the collection to a value in the range set.
+The content model is identical with gml:DiscreteCoverageType, but that gml:domainSet shall have values gml:MultiCurve.
+In a gml:MultiCurveCoverage the mapping from the domain to the range is straightforward.
+-	For gml:DataBlock encodings the curves of the gml:MultiCurve are mapped in document order to the tuples of the data block.
+-	For gml:CompositeValue encodings the curves of the gml:MultiCurve are mapped to the members of the composite value in document order.
+-	For gml:File encodings the curves of the gml:MultiCurve are mapped to the records of the file in sequential order.
+</documentation>
+		</annotation>
+	</element>
+	<element name="MultiSurfaceCoverage" type="gml:DiscreteCoverageType" substitutionGroup="gml:AbstractDiscreteCoverage">
+		<annotation>
+			<documentation>In a gml:MultiSurfaceCoverage the domain is partioned into a collection of surfaces comprising a gml:MultiSurface.  The coverage function than maps each surface in the collection to a value in the range set.
+The content model is identical with gml:DiscreteCoverageType, but that gml:domainSet shall have values gml:MultiSurface.
+In a gml:MultiSurfaceCoverage the mapping from the domain to the range is straightforward.
+-	For gml:DataBlock encodings the surfaces of the gml:MultiSurface are mapped in document order to the tuples of the data block.
+-	For gml:CompositeValue encodings the surfaces of the gml:MultiSurface are mapped to the members of the composite value in document order.
+-	For gml:File encodings the surfaces of the gml:MultiSurface are mapped to the records of the file in sequential order.
+</documentation>
+		</annotation>
+	</element>
+	<element name="MultiSolidCoverage" type="gml:DiscreteCoverageType" substitutionGroup="gml:AbstractDiscreteCoverage">
+		<annotation>
+			<documentation>In a gml:MultiSolidCoverage the domain is partioned into a collection of solids comprising a gml:MultiSolid.  The coverage function than maps each solid in the collection to a value in the range set.
+The content model is identical with gml:DiscreteCoverageType, but that gml:domainSet shall have values gml:MultiSolid.
+In a gml:MultiSolidCoverage the mapping from the domain to the range is straightforward.
+-	For gml:DataBlock encodings the solids of the gml:MultiSolid are mapped in document order to the tuples of the data block.
+-	For gml:CompositeValue encodings the solids of the gml:MultiSolid are mapped to the members of the composite value in document order.
+-	For gml:File encodings the solids of the gml:MultiSolid are mapped to the records of the file in sequential order.
+</documentation>
+		</annotation>
+	</element>
+	<element name="GridCoverage" type="gml:DiscreteCoverageType" substitutionGroup="gml:AbstractDiscreteCoverage">
+		<annotation>
+			<documentation>A gml:GriddedCoverage is a discrete point coverage in which the domain set is a geometric grid of points.
+Note that this is the same as the gml:MultiPointCoverage except that we have a gml:Grid to describe the domain.
+The simple gridded coverage is not geometrically referenced and hence no geometric positions are assignable to the points in the grid. Such geometric positioning is introduced in the gml:RectifiedGridCoverage.</documentation>
+		</annotation>
+	</element>
+	<element name="RectifiedGridCoverage" type="gml:DiscreteCoverageType" substitutionGroup="gml:AbstractDiscreteCoverage">
+		<annotation>
+			<documentation>The gml:RectifiedGridCoverage is a discrete point coverage based on a rectified grid. It is similar to the grid coverage except that the points of the grid are geometrically referenced. The rectified grid coverage has a domain that is a gml:RectifiedGrid geometry.</documentation>
+		</annotation>
+	</element>
+</schema>
diff --git a/pycsw/core/schemas/ogc/gml/3.2.1/datums.xsd b/pycsw/core/schemas/ogc/gml/3.2.1/datums.xsd
new file mode 100644
index 0000000..a62b866
--- /dev/null
+++ b/pycsw/core/schemas/ogc/gml/3.2.1/datums.xsd
@@ -0,0 +1,287 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- edited with XMLSPY v5 rel. 2 U (http://www.xmlspy.com) by Clemens Portele (interactive instruments) -->
+<schema targetNamespace="http://www.opengis.net/gml/3.2" xmlns="http://www.w3.org/2001/XMLSchema" xmlns:gml="http://www.opengis.net/gml/3.2" elementFormDefault="qualified" xml:lang="en" version="3.2.1.2">
+	<annotation>
+		<appinfo source="urn:x-ogc:specification:gml:schema-xsd:datums:3.2.1">datums.xsd</appinfo>
+		<documentation>See ISO/DIS 19136 13.5
+The datums schema components can be divided into three logical parts, which define elements and types for XML encoding of the definitions of:
+-	Abstract datum
+-	Geodetic datums, including ellipsoid and prime meridian
+-	Multiple other concrete types of spatial or temporal datums
+These schema components encode the Datum packages of the UML Models of ISO 19111 Clause 10 and ISO/DIS 19136 D.3.10.
+
+GML is an OGC Standard.
+Copyright (c) 2007,2010 Open Geospatial Consortium.
+To obtain additional rights of use, visit http://www.opengeospatial.org/legal/ .
+		</documentation>
+	</annotation>
+	<include schemaLocation="gml.xsd"/>
+	<include schemaLocation="referenceSystems.xsd"/>
+	<include schemaLocation="measures.xsd"/>
+	<element name="AbstractDatum" type="gml:AbstractDatumType" abstract="true" substitutionGroup="gml:Definition">
+		<annotation>
+			<documentation>A gml:AbstractDatum specifies the relationship of a coordinate system to the earth, thus creating a coordinate reference system. A datum uses a parameter or set of parameters that determine the location of the origin of the coordinate reference system. Each datum subtype may be associated with only specific types of coordinate systems. This abstract complex type shall not be used, extended, or restricted, in a GML Application Schema, to define a concrete subtype with a  [...]
+		</annotation>
+	</element>
+	<complexType name="AbstractDatumType" abstract="true">
+		<complexContent>
+			<extension base="gml:IdentifiedObjectType">
+				<sequence>
+					<element ref="gml:domainOfValidity" minOccurs="0"/>
+					<element ref="gml:scope" maxOccurs="unbounded"/>
+					<element ref="gml:anchorDefinition" minOccurs="0"/>
+					<element ref="gml:realizationEpoch" minOccurs="0"/>
+				</sequence>
+			</extension>
+		</complexContent>
+	</complexType>
+	<element name="anchorDefinition" type="gml:CodeType">
+		<annotation>
+			<documentation>gml:anchorDefinition is a description, possibly including coordinates, of the definition used to anchor the datum to the Earth. Also known as the "origin", especially for engineering and image datums. The codeSpace attribute may be used to reference a source of more detailed on this point or surface, or on a set of such descriptions.
+-	For a geodetic datum, this point is also known as the fundamental point, which is traditionally the point where the relationship between geoid and ellipsoid is defined. In some cases, the "fundamental point" may consist of a number of points. In those cases, the parameters defining the geoid/ellipsoid relationship have been averaged for these points, and the averages adopted as the datum definition.
+-	For an engineering datum, the anchor definition may be a physical point, or it may be a point with defined coordinates in another CRS.may
+-	For an image datum, the anchor definition is usually either the centre of the image or the corner of the image.
+-	For a temporal datum, this attribute is not defined. Instead of the anchor definition, a temporal datum carries a separate time origin of type DateTime.</documentation>
+		</annotation>
+	</element>
+	<element name="realizationEpoch" type="date">
+		<annotation>
+			<documentation>gml:realizationEpoch is the time after which this datum definition is valid. See ISO 19111 Table 32 for details.</documentation>
+		</annotation>
+	</element>
+	<complexType name="DatumPropertyType">
+		<annotation>
+			<documentation>gml:DatumPropertyType is a property type for association roles to a datum, either referencing or containing the definition of that datum.</documentation>
+		</annotation>
+		<sequence minOccurs="0">
+			<element ref="gml:AbstractDatum"/>
+		</sequence>
+		<attributeGroup ref="gml:AssociationAttributeGroup"/>
+	</complexType>
+	<element name="GeodeticDatum" type="gml:GeodeticDatumType" substitutionGroup="gml:AbstractDatum">
+		<annotation>
+			<documentation>gml:GeodeticDatum is a geodetic datum defines the precise location and orientation in 3-dimensional space of a defined ellipsoid (or sphere), or of a Cartesian coordinate system centered in this ellipsoid (or sphere).</documentation>
+		</annotation>
+	</element>
+	<complexType name="GeodeticDatumType">
+		<complexContent>
+			<extension base="gml:AbstractDatumType">
+				<sequence>
+					<element ref="gml:primeMeridian"/>
+					<element ref="gml:ellipsoid"/>
+				</sequence>
+			</extension>
+		</complexContent>
+	</complexType>
+	<element name="primeMeridian" type="gml:PrimeMeridianPropertyType">
+		<annotation>
+			<documentation>gml:primeMeridian is an association role to the prime meridian used by this geodetic datum.</documentation>
+		</annotation>
+	</element>
+	<element name="ellipsoid" type="gml:EllipsoidPropertyType">
+		<annotation>
+			<documentation>gml:ellipsoid is an association role to the ellipsoid used by this geodetic datum.</documentation>
+		</annotation>
+	</element>
+	<complexType name="GeodeticDatumPropertyType">
+		<annotation>
+			<documentation>gml:GeodeticDatumPropertyType is a property type for association roles to a geodetic datum, either referencing or containing the definition of that datum.</documentation>
+		</annotation>
+		<sequence minOccurs="0">
+			<element ref="gml:GeodeticDatum"/>
+		</sequence>
+		<attributeGroup ref="gml:AssociationAttributeGroup"/>
+	</complexType>
+	<element name="Ellipsoid" type="gml:EllipsoidType" substitutionGroup="gml:Definition">
+		<annotation>
+			<documentation>A gml:Ellipsoid is a geometric figure that may be used to describe the approximate shape of the earth. In mathematical terms, it is a surface formed by the rotation of an ellipse about its minor axis.</documentation>
+		</annotation>
+	</element>
+	<complexType name="EllipsoidType">
+		<complexContent>
+			<extension base="gml:IdentifiedObjectType">
+				<sequence>
+					<element ref="gml:semiMajorAxis"/>
+					<element ref="gml:secondDefiningParameter"/>
+				</sequence>
+			</extension>
+		</complexContent>
+	</complexType>
+	<element name="semiMajorAxis" type="gml:MeasureType">
+		<annotation>
+			<documentation>gml:semiMajorAxis specifies the length of the semi-major axis of the ellipsoid, with its units. Uses the MeasureType with the restriction that the unit of measure referenced by uom must be suitable for a length, such as metres or feet.</documentation>
+		</annotation>
+	</element>
+	<element name="secondDefiningParameter">
+		<annotation>
+			<documentation>gml:secondDefiningParameter is a property containing the definition of the second parameter that defines the shape of an ellipsoid. An ellipsoid requires two defining parameters: semi-major axis and inverse flattening or semi-major axis and semi-minor axis. When the reference body is a sphere rather than an ellipsoid, only a single defining parameter is required, namely the radius of the sphere; in that case, the semi-major axis "degenerates" into the radius of the sphere.
+The inverseFlattening element contains the inverse flattening value of the ellipsoid. This value is a scale factor (or ratio). It uses gml:LengthType with the restriction that the unit of measure referenced by the uom attribute must be suitable for a scale factor, such as percent, permil, or parts-per-million.
+The semiMinorAxis element contains the length of the semi-minor axis of the ellipsoid. When the isSphere element is included, the ellipsoid is degenerate and is actually a sphere. The sphere is completely defined by the semi-major axis, which is the radius of the sphere.</documentation>
+		</annotation>
+		<complexType>
+			<sequence>
+				<element ref="gml:SecondDefiningParameter"/>
+			</sequence>
+		</complexType>
+	</element>
+	<element name="SecondDefiningParameter">
+		<complexType>
+			<choice>
+				<element name="inverseFlattening" type="gml:MeasureType"/>
+				<element name="semiMinorAxis" type="gml:LengthType"/>
+				<element name="isSphere" type="boolean" default="true"/>
+			</choice>
+		</complexType>
+	</element>
+	<complexType name="EllipsoidPropertyType">
+		<annotation>
+			<documentation>gml:EllipsoidPropertyType is a property type for association roles to an ellipsoid, either referencing or containing the definition of that ellipsoid.</documentation>
+		</annotation>
+		<sequence minOccurs="0">
+			<element ref="gml:Ellipsoid"/>
+		</sequence>
+		<attributeGroup ref="gml:AssociationAttributeGroup"/>
+	</complexType>
+	<element name="PrimeMeridian" type="gml:PrimeMeridianType" substitutionGroup="gml:Definition">
+		<annotation>
+			<documentation>A gml:PrimeMeridian defines the origin from which longitude values are determined. The default value for the prime meridian gml:identifier value is "Greenwich".</documentation>
+		</annotation>
+	</element>
+	<complexType name="PrimeMeridianType">
+		<complexContent>
+			<extension base="gml:IdentifiedObjectType">
+				<sequence>
+					<element ref="gml:greenwichLongitude"/>
+				</sequence>
+			</extension>
+		</complexContent>
+	</complexType>
+	<element name="greenwichLongitude" type="gml:AngleType">
+		<annotation>
+			<documentation>gml:greenwichLongitude is the longitude of the prime meridian measured from the Greenwich meridian, positive eastward. If the value of the prime meridian "name" is "Greenwich" then the value of greenwichLongitude shall be 0 degrees.</documentation>
+		</annotation>
+	</element>
+	<complexType name="PrimeMeridianPropertyType">
+		<annotation>
+			<documentation>gml:PrimeMeridianPropertyType is a property type for association roles to a prime meridian, either referencing or containing the definition of that meridian.</documentation>
+		</annotation>
+		<sequence minOccurs="0">
+			<element ref="gml:PrimeMeridian"/>
+		</sequence>
+		<attributeGroup ref="gml:AssociationAttributeGroup"/>
+	</complexType>
+	<element name="EngineeringDatum" type="gml:EngineeringDatumType" substitutionGroup="gml:AbstractDatum">
+		<annotation>
+			<documentation>gml:EngineeringDatum defines the origin of an engineering coordinate reference system, and is used in a region around that origin. This origin may be fixed with respect to the earth (such as a defined point at a construction site), or be a defined point on a moving vehicle (such as on a ship or satellite).</documentation>
+		</annotation>
+	</element>
+	<complexType name="EngineeringDatumType">
+		<complexContent>
+			<extension base="gml:AbstractDatumType"/>
+		</complexContent>
+	</complexType>
+	<complexType name="EngineeringDatumPropertyType">
+		<annotation>
+			<documentation>gml:EngineeringDatumPropertyType is a property type for association roles to an engineering datum, either referencing or containing the definition of that datum.</documentation>
+		</annotation>
+		<sequence minOccurs="0">
+			<element ref="gml:EngineeringDatum"/>
+		</sequence>
+		<attributeGroup ref="gml:AssociationAttributeGroup"/>
+	</complexType>
+	<element name="ImageDatum" type="gml:ImageDatumType" substitutionGroup="gml:AbstractDatum">
+		<annotation>
+			<documentation>gml:ImageDatum defines the origin of an image coordinate reference system, and is used in a local context only. For an image datum, the anchor definition is usually either the centre of the image or the corner of the image. For more information, see ISO 19111 B.3.5.</documentation>
+		</annotation>
+	</element>
+	<complexType name="ImageDatumType">
+		<complexContent>
+			<extension base="gml:AbstractDatumType">
+				<sequence>
+					<element ref="gml:pixelInCell"/>
+				</sequence>
+			</extension>
+		</complexContent>
+	</complexType>
+	<element name="pixelInCell" type="gml:CodeWithAuthorityType">
+		<annotation>
+			<documentation>gml:pixelInCell is a specification of the way an image grid is associated with the image data attributes. The required codeSpace attribute shall reference a source of information specifying the values and meanings of all the allowed string values for this property.</documentation>
+		</annotation>
+	</element>
+	<complexType name="ImageDatumPropertyType">
+		<annotation>
+			<documentation>gml:ImageDatumPropertyType is a property type for association roles to an image datum, either referencing or containing the definition of that datum.</documentation>
+		</annotation>
+		<sequence minOccurs="0">
+			<element ref="gml:ImageDatum"/>
+		</sequence>
+		<attributeGroup ref="gml:AssociationAttributeGroup"/>
+	</complexType>
+	<element name="VerticalDatum" type="gml:VerticalDatumType" substitutionGroup="gml:AbstractDatum">
+		<annotation>
+			<documentation>gml:VerticalDatum is a textual description and/or a set of parameters identifying a particular reference level surface used as a zero-height surface, including its position with respect to the Earth for any of the height types recognized by this International Standard.</documentation>
+		</annotation>
+	</element>
+	<complexType name="VerticalDatumType">
+		<complexContent>
+			<extension base="gml:AbstractDatumType"/>
+		</complexContent>
+	</complexType>
+	<complexType name="VerticalDatumPropertyType">
+		<annotation>
+			<documentation>gml:VerticalDatumPropertyType is property type for association roles to a vertical datum, either referencing or containing the definition of that datum.</documentation>
+		</annotation>
+		<sequence minOccurs="0">
+			<element ref="gml:VerticalDatum"/>
+		</sequence>
+		<attributeGroup ref="gml:AssociationAttributeGroup"/>
+	</complexType>
+	<element name="TemporalDatum" type="gml:TemporalDatumType" substitutionGroup="gml:AbstractDatum">
+		<annotation>
+			<documentation>A gml:TemporalDatum defines the origin of a Temporal Reference System. This type omits the "anchorDefinition" and "realizationEpoch" elements and adds the "origin" element with the dateTime type.</documentation>
+		</annotation>
+	</element>
+	<complexType name="TemporalDatumType">
+		<complexContent>
+			<extension base="gml:TemporalDatumBaseType">
+				<sequence>
+					<element ref="gml:origin"/>
+				</sequence>
+			</extension>
+		</complexContent>
+	</complexType>
+	<complexType name="TemporalDatumBaseType" abstract="true">
+		<annotation>
+			<documentation>The TemporalDatumBaseType partially defines the origin of a temporal coordinate reference system. This type restricts the AbstractDatumType to remove the "anchorDefinition" and "realizationEpoch" elements.</documentation>
+		</annotation>
+		<complexContent>
+			<restriction base="gml:AbstractDatumType">
+				<sequence>
+					<element ref="gml:metaDataProperty" minOccurs="0" maxOccurs="unbounded"/>
+					<element ref="gml:description" minOccurs="0"/>
+					<element ref="gml:descriptionReference" minOccurs="0"/>
+					<element ref="gml:identifier"/>
+					<element ref="gml:name" minOccurs="0" maxOccurs="unbounded"/>
+					<element ref="gml:remarks" minOccurs="0"/>
+					<element ref="gml:domainOfValidity" minOccurs="0"/>
+					<element ref="gml:scope" maxOccurs="unbounded"/>
+				</sequence>
+				<attribute ref="gml:id" use="required"/>
+			</restriction>
+		</complexContent>
+	</complexType>
+	<element name="origin" type="dateTime">
+		<annotation>
+			<documentation>gml:origin is the date and time origin of this temporal datum.</documentation>
+		</annotation>
+	</element>
+	<complexType name="TemporalDatumPropertyType">
+		<annotation>
+			<documentation>gml:TemporalDatumPropertyType is a property type for association roles to a temporal datum, either referencing or containing the definition of that datum.</documentation>
+		</annotation>
+		<sequence minOccurs="0">
+			<element ref="gml:TemporalDatum"/>
+		</sequence>
+		<attributeGroup ref="gml:AssociationAttributeGroup"/>
+	</complexType>
+</schema>
diff --git a/pycsw/schemas/ogc/gml/3.1.1/base/defaultStyle.xsd b/pycsw/core/schemas/ogc/gml/3.2.1/defaultStyle.xsd
similarity index 95%
rename from pycsw/schemas/ogc/gml/3.1.1/base/defaultStyle.xsd
rename to pycsw/core/schemas/ogc/gml/3.2.1/defaultStyle.xsd
index 08ecd8f..16fa6e8 100644
--- a/pycsw/schemas/ogc/gml/3.1.1/base/defaultStyle.xsd
+++ b/pycsw/core/schemas/ogc/gml/3.2.1/defaultStyle.xsd
@@ -1,20 +1,19 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<schema targetNamespace="http://www.opengis.net/gml" xmlns="http://www.w3.org/2001/XMLSchema" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:gml="http://www.opengis.net/gml" xmlns:smil20="http://www.w3.org/2001/SMIL20/" elementFormDefault="qualified" version="3.1.1 2010-01-28">
+<schema targetNamespace="http://www.opengis.net/gml/3.2" xmlns="http://www.w3.org/2001/XMLSchema" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:gml="http://www.opengis.net/gml/3.2" xmlns:smil20="http://www.w3.org/2001/SMIL20/" elementFormDefault="qualified" version="3.2.1.2">
 	<annotation>
-		<appinfo source="urn:opengis:specification:gml:schema-defaultStyle:v3.1.0">defaultStyle.xsd</appinfo>
+		<appinfo source="urn:x-ogc:specification:gml:schema-xsd:gml:3.2.1">defaultStyle.xsd</appinfo>
 		<documentation>
-			Default Style schema for GML 3.1.1
-			
 			GML is an OGC Standard.
-			Copyright (c) 2001,2005,2010 Open Geospatial Consortium, Inc. All Rights Reserved.
+			Copyright (c) 2007,2010 Open Geospatial Consortium.
 			To obtain additional rights of use, visit http://www.opengeospatial.org/legal/ .
 		</documentation>
 	</annotation>
 	<!-- ==============================================================
        includes and imports
 	============================================================== -->
+	<include schemaLocation="gml.xsd"/>
 	<include schemaLocation="measures.xsd"/>
-	<import namespace="http://www.w3.org/2001/SMIL20/" schemaLocation="http://schemas.opengis.net/gml/3.1.1/smil/smil20.xsd"/>
+	<import namespace="http://www.w3.org/2001/SMIL20/" schemaLocation="../3.1.1/smil/smil20.xsd"/>
 	<!-- ==============================================================
       the Style property
 	============================================================== -->
@@ -29,7 +28,7 @@
 			<documentation>[complexType of] Top-level property. Used in application schemas to "attach" the styling information to GML data. The link between the data and the style should be established through this property only.</documentation>
 		</annotation>
 		<sequence>
-			<element ref="gml:_Style" minOccurs="0"/>
+			<element ref="gml:AbstractStyle" minOccurs="0"/>
 		</sequence>
 		<attribute name="about" type="anyURI" use="optional"/>
 		<attributeGroup ref="gml:AssociationAttributeGroup"/>
@@ -37,7 +36,7 @@
 	<!-- ==============================================================
        the Style
 	============================================================== -->
-	<element name="_Style" type="gml:AbstractStyleType" abstract="true" substitutionGroup="gml:_GML">
+	<element name="AbstractStyle" type="gml:AbstractStyleType" abstract="true" substitutionGroup="gml:AbstractGML">
 		<annotation>
 			<documentation>The value of the top-level property. It is an abstract element. Used as the head element of the substitution group for extensibility purposes.</documentation>
 		</annotation>
@@ -52,7 +51,7 @@
 		</complexContent>
 	</complexType>
 	<!-- =========================================================== -->
-	<element name="Style" type="gml:StyleType" substitutionGroup="gml:_Style">
+	<element name="Style" type="gml:StyleType" substitutionGroup="gml:AbstractStyle">
 		<annotation>
 			<documentation>Predefined concrete value of the top-level property. Encapsulates all other styling information.</documentation>
 		</annotation>
@@ -93,7 +92,7 @@
 	<!-- ==============================================================
       Feature Style
 	============================================================== -->
-	<element name="FeatureStyle" type="gml:FeatureStyleType" substitutionGroup="gml:_GML">
+	<element name="FeatureStyle" type="gml:FeatureStyleType" substitutionGroup="gml:AbstractGML">
 		<annotation>
 			<documentation>The style descriptor for features.</documentation>
 		</annotation>
@@ -170,7 +169,7 @@
 	<!-- ==============================================================
        Geometry Style
 	============================================================== -->
-	<element name="GeometryStyle" type="gml:GeometryStyleType" substitutionGroup="gml:_GML">
+	<element name="GeometryStyle" type="gml:GeometryStyleType" substitutionGroup="gml:AbstractGML">
 		<annotation>
 			<documentation>The style descriptor for geometries of a feature.</documentation>
 		</annotation>
@@ -221,7 +220,7 @@
 	<!-- ==============================================================
        Topology Style
 	============================================================== -->
-	<element name="TopologyStyle" type="gml:TopologyStyleType" substitutionGroup="gml:_GML">
+	<element name="TopologyStyle" type="gml:TopologyStyleType" substitutionGroup="gml:AbstractGML">
 		<annotation>
 			<documentation>The style descriptor for topologies of a feature. Describes individual topology elements styles.</documentation>
 		</annotation>
@@ -272,7 +271,7 @@
 	<!-- ==============================================================
        Label Style
 	============================================================== -->
-	<element name="LabelStyle" type="gml:LabelStyleType" substitutionGroup="gml:_GML">
+	<element name="LabelStyle" type="gml:LabelStyleType" substitutionGroup="gml:AbstractGML">
 		<annotation>
 			<documentation>The style descriptor for labels of a feature, geometry or topology.</documentation>
 		</annotation>
@@ -313,7 +312,7 @@
 	<!-- ==============================================================
       Graph Style
 	============================================================== -->
-	<element name="GraphStyle" type="gml:GraphStyleType" substitutionGroup="gml:_GML">
+	<element name="GraphStyle" type="gml:GraphStyleType" substitutionGroup="gml:AbstractGML">
 		<annotation>
 			<documentation>The style descriptor for a graph consisting of a number of features. Describes graph-specific style attributes.</documentation>
 		</annotation>
diff --git a/pycsw/core/schemas/ogc/gml/3.2.1/deprecatedTypes.xsd b/pycsw/core/schemas/ogc/gml/3.2.1/deprecatedTypes.xsd
new file mode 100644
index 0000000..7dbd79b
--- /dev/null
+++ b/pycsw/core/schemas/ogc/gml/3.2.1/deprecatedTypes.xsd
@@ -0,0 +1,1133 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<schema targetNamespace="http://www.opengis.net/gml/3.2" xmlns:gml="http://www.opengis.net/gml/3.2" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" version="3.2.1.2">
+	<annotation>
+		<appinfo source="urn:x-ogc:specification:gml:schema-xsd:deprecatedTypes:3.2.1">deprecatedTypes.xsd</appinfo>
+		<documentation>All global schema components that are part of the GML schema, but were deprecated. See Annex I.
+			
+			GML is an OGC Standard.
+			Copyright (c) 2007,2010 Open Geospatial Consortium.
+			To obtain additional rights of use, visit http://www.opengeospatial.org/legal/ .
+		</documentation>
+	</annotation>
+	<include schemaLocation="gml.xsd"/>
+	<element name="Null" type="gml:NilReasonType">
+		<annotation>
+			<appinfo>deprecated</appinfo>
+		</annotation>
+	</element>
+	<element name="anchorPoint" type="gml:CodeType" substitutionGroup="gml:anchorDefinition">
+		<annotation>
+			<appinfo>deprecated</appinfo>
+		</annotation>
+	</element>
+	<element name="datumRef" type="gml:DatumPropertyType">
+		<annotation>
+			<appinfo>deprecated</appinfo>
+		</annotation>
+	</element>
+	<element name="usesPrimeMeridian" type="gml:PrimeMeridianPropertyType" substitutionGroup="gml:primeMeridian">
+		<annotation>
+			<appinfo>deprecated</appinfo>
+		</annotation>
+	</element>
+	<element name="usesEllipsoid" type="gml:EllipsoidPropertyType" substitutionGroup="gml:ellipsoid">
+		<annotation>
+			<appinfo>deprecated</appinfo>
+		</annotation>
+	</element>
+	<element name="geodeticDatumRef" type="gml:GeodeticDatumPropertyType">
+		<annotation>
+			<appinfo>deprecated</appinfo>
+		</annotation>
+	</element>
+	<element name="ellipsoidRef" type="gml:EllipsoidPropertyType">
+		<annotation>
+			<appinfo>deprecated</appinfo>
+		</annotation>
+	</element>
+	<element name="primeMeridianRef" type="gml:PrimeMeridianPropertyType">
+		<annotation>
+			<appinfo>deprecated</appinfo>
+		</annotation>
+	</element>
+	<element name="engineeringDatumRef" type="gml:EngineeringDatumPropertyType">
+		<annotation>
+			<appinfo>deprecated</appinfo>
+		</annotation>
+	</element>
+	<element name="imageDatumRef" type="gml:ImageDatumPropertyType">
+		<annotation>
+			<appinfo>deprecated</appinfo>
+		</annotation>
+	</element>
+	<element name="verticalDatumRef" type="gml:VerticalDatumPropertyType">
+		<annotation>
+			<appinfo>deprecated</appinfo>
+		</annotation>
+	</element>
+	<element name="temporalDatumRef" type="gml:TemporalDatumPropertyType">
+		<annotation>
+			<appinfo>deprecated</appinfo>
+		</annotation>
+	</element>
+	<element name="coordinateOperationRef" type="gml:CoordinateOperationPropertyType">
+		<annotation>
+			<appinfo>deprecated</appinfo>
+		</annotation>
+	</element>
+	<element name="singleOperationRef" type="gml:SingleOperationPropertyType">
+		<annotation>
+			<appinfo>deprecated</appinfo>
+		</annotation>
+	</element>
+	<element name="AbstractOperation" type="gml:AbstractCoordinateOperationType" abstract="true" substitutionGroup="gml:AbstractSingleOperation">
+		<annotation>
+			<appinfo>deprecated</appinfo>
+		</annotation>
+	</element>
+	<complexType name="OperationPropertyType">
+		<annotation>
+			<appinfo>deprecated</appinfo>
+		</annotation>
+		<sequence minOccurs="0">
+			<element ref="gml:AbstractOperation"/>
+		</sequence>
+		<attributeGroup ref="gml:AssociationAttributeGroup"/>
+	</complexType>
+	<element name="operationRef" type="gml:OperationPropertyType">
+		<annotation>
+			<appinfo>deprecated</appinfo>
+		</annotation>
+	</element>
+	<element name="generalConversionRef" type="gml:GeneralConversionPropertyType">
+		<annotation>
+			<appinfo>deprecated</appinfo>
+		</annotation>
+	</element>
+	<element name="generalTransformationRef" type="gml:GeneralTransformationPropertyType">
+		<annotation>
+			<appinfo>deprecated</appinfo>
+		</annotation>
+	</element>
+	<element name="usesSingleOperation" type="gml:CoordinateOperationPropertyType" substitutionGroup="gml:coordOperation">
+		<annotation>
+			<appinfo>deprecated</appinfo>
+		</annotation>
+	</element>
+	<element name="concatenatedOperationRef" type="gml:ConcatenatedOperationPropertyType">
+		<annotation>
+			<appinfo>deprecated</appinfo>
+		</annotation>
+	</element>
+	<element name="usesOperation" type="gml:CoordinateOperationPropertyType" substitutionGroup="gml:coordOperation">
+		<annotation>
+			<appinfo>deprecated</appinfo>
+		</annotation>
+	</element>
+	<element name="passThroughOperationRef" type="gml:PassThroughOperationPropertyType">
+		<annotation>
+			<appinfo>deprecated</appinfo>
+		</annotation>
+	</element>
+	<element name="usesMethod" type="gml:OperationMethodPropertyType" substitutionGroup="gml:method">
+		<annotation>
+			<appinfo>deprecated</appinfo>
+		</annotation>
+	</element>
+	<element name="usesValue" type="gml:AbstractGeneralParameterValuePropertyType" substitutionGroup="gml:parameterValue">
+		<annotation>
+			<appinfo>deprecated</appinfo>
+		</annotation>
+	</element>
+	<element name="conversionRef" type="gml:ConversionPropertyType">
+		<annotation>
+			<appinfo>deprecated</appinfo>
+		</annotation>
+	</element>
+	<element name="transformationRef" type="gml:TransformationPropertyType">
+		<annotation>
+			<appinfo>deprecated</appinfo>
+		</annotation>
+	</element>
+	<element name="dmsAngleValue" type="gml:DMSAngleType">
+		<annotation>
+			<appinfo>deprecated</appinfo>
+		</annotation>
+	</element>
+	<element name="valueOfParameter" type="gml:OperationParameterPropertyType" substitutionGroup="gml:operationParameter">
+		<annotation>
+			<appinfo>deprecated</appinfo>
+		</annotation>
+	</element>
+	<element name="includesValue" type="gml:AbstractGeneralParameterValuePropertyType" substitutionGroup="gml:parameterValue">
+		<annotation>
+			<appinfo>deprecated</appinfo>
+		</annotation>
+	</element>
+	<element name="valuesOfGroup" type="gml:OperationParameterGroupPropertyType" substitutionGroup="gml:group">
+		<annotation>
+			<appinfo>deprecated</appinfo>
+		</annotation>
+	</element>
+	<element name="methodFormula" type="gml:CodeType" substitutionGroup="gml:formula">
+		<annotation>
+			<appinfo>deprecated</appinfo>
+		</annotation>
+	</element>
+	<element name="usesParameter" type="gml:AbstractGeneralOperationParameterPropertyType" substitutionGroup="gml:generalOperationParameter">
+		<annotation>
+			<appinfo>deprecated</appinfo>
+		</annotation>
+	</element>
+	<element name="operationMethodRef" type="gml:OperationMethodPropertyType">
+		<annotation>
+			<appinfo>deprecated</appinfo>
+		</annotation>
+	</element>
+	<element name="abstractGeneralOperationParameterRef" type="gml:AbstractGeneralOperationParameterPropertyType">
+		<annotation>
+			<appinfo>deprecated</appinfo>
+		</annotation>
+	</element>
+	<element name="operationParameterRef" type="gml:OperationParameterPropertyType">
+		<annotation>
+			<appinfo>deprecated</appinfo>
+		</annotation>
+	</element>
+	<element name="includesParameter" type="gml:AbstractGeneralOperationParameterPropertyType" substitutionGroup="gml:parameter">
+		<annotation>
+			<appinfo>deprecated</appinfo>
+		</annotation>
+	</element>
+	<element name="operationParameterGroupRef" type="gml:OperationParameterPropertyType">
+		<annotation>
+			<appinfo>deprecated</appinfo>
+		</annotation>
+	</element>
+	<element name="referenceSystemRef" type="gml:CRSPropertyType">
+		<annotation>
+			<appinfo>deprecated</appinfo>
+		</annotation>
+	</element>
+	<element name="crsRef" type="gml:CRSPropertyType">
+		<annotation>
+			<appinfo>deprecated</appinfo>
+		</annotation>
+	</element>
+	<element name="coordinateSystemAxisRef" type="gml:CoordinateSystemAxisPropertyType">
+		<annotation>
+			<appinfo>deprecated</appinfo>
+		</annotation>
+	</element>
+	<element name="usesAxis" type="gml:CoordinateSystemAxisPropertyType" substitutionGroup="gml:axis">
+		<annotation>
+			<appinfo>deprecated</appinfo>
+		</annotation>
+	</element>
+	<element name="coordinateSystemRef" type="gml:CoordinateSystemPropertyType">
+		<annotation>
+			<appinfo>deprecated</appinfo>
+		</annotation>
+	</element>
+	<element name="ellipsoidalCSRef" type="gml:EllipsoidalCSPropertyType">
+		<annotation>
+			<appinfo>deprecated</appinfo>
+		</annotation>
+	</element>
+	<element name="cartesianCSRef" type="gml:CartesianCSPropertyType">
+		<annotation>
+			<appinfo>deprecated</appinfo>
+		</annotation>
+	</element>
+	<element name="verticalCSRef" type="gml:VerticalCSPropertyType">
+		<annotation>
+			<appinfo>deprecated</appinfo>
+		</annotation>
+	</element>
+	<element name="TemporalCS" type="gml:TemporalCSType" substitutionGroup="gml:AbstractCoordinateSystem">
+		<annotation>
+			<appinfo>deprecated</appinfo>
+		</annotation>
+	</element>
+	<complexType name="TemporalCSType">
+		<annotation>
+			<appinfo>deprecated</appinfo>
+		</annotation>
+		<complexContent>
+			<extension base="gml:AbstractCoordinateSystemType"/>
+		</complexContent>
+	</complexType>
+	<complexType name="TemporalCSPropertyType">
+		<annotation>
+			<appinfo>deprecated</appinfo>
+		</annotation>
+		<sequence minOccurs="0">
+			<element ref="gml:TemporalCS"/>
+		</sequence>
+		<attributeGroup ref="gml:AssociationAttributeGroup"/>
+	</complexType>
+	<element name="temporalCSRef" type="gml:TemporalCSPropertyType">
+		<annotation>
+			<appinfo>deprecated</appinfo>
+		</annotation>
+	</element>
+	<element name="linearCSRef" type="gml:LinearCSPropertyType">
+		<annotation>
+			<appinfo>deprecated</appinfo>
+		</annotation>
+	</element>
+	<element name="userDefinedCSRef" type="gml:UserDefinedCSPropertyType">
+		<annotation>
+			<appinfo>deprecated</appinfo>
+		</annotation>
+	</element>
+	<element name="sphericalCSRef" type="gml:SphericalCSPropertyType">
+		<annotation>
+			<appinfo>deprecated</appinfo>
+		</annotation>
+	</element>
+	<element name="polarCSRef" type="gml:PolarCSPropertyType">
+		<annotation>
+			<appinfo>deprecated</appinfo>
+		</annotation>
+	</element>
+	<element name="cylindricalCSRef" type="gml:CylindricalCSPropertyType">
+		<annotation>
+			<appinfo>deprecated</appinfo>
+		</annotation>
+	</element>
+	<element name="ObliqueCartesianCS" type="gml:ObliqueCartesianCSType" substitutionGroup="gml:AbstractCoordinateSystem">
+		<annotation>
+			<appinfo>deprecated</appinfo>
+		</annotation>
+	</element>
+	<complexType name="ObliqueCartesianCSType">
+		<annotation>
+			<appinfo>deprecated</appinfo>
+		</annotation>
+		<complexContent>
+			<extension base="gml:AbstractCoordinateSystemType"/>
+		</complexContent>
+	</complexType>
+	<complexType name="ObliqueCartesianCSPropertyType">
+		<annotation>
+			<appinfo>deprecated</appinfo>
+		</annotation>
+		<sequence minOccurs="0">
+			<element ref="gml:ObliqueCartesianCS"/>
+		</sequence>
+		<attributeGroup ref="gml:AssociationAttributeGroup"/>
+	</complexType>
+	<element name="obliqueCartesianCSRef" type="gml:ObliqueCartesianCSPropertyType">
+		<annotation>
+			<appinfo>deprecated</appinfo>
+		</annotation>
+	</element>
+	<element name="singleCRSRef" type="gml:SingleCRSPropertyType">
+		<annotation>
+			<appinfo>deprecated</appinfo>
+		</annotation>
+	</element>
+	<element name="definedByConversion" type="gml:GeneralConversionPropertyType" substitutionGroup="gml:conversion">
+		<annotation>
+			<appinfo>deprecated</appinfo>
+		</annotation>
+	</element>
+	<element name="includesSingleCRS" type="gml:SingleCRSPropertyType" substitutionGroup="gml:componentReferenceSystem">
+		<annotation>
+			<appinfo>deprecated</appinfo>
+		</annotation>
+	</element>
+	<element name="compoundCRSRef" type="gml:CompoundCRSPropertyType">
+		<annotation>
+			<appinfo>deprecated</appinfo>
+		</annotation>
+	</element>
+	<element name="usesEllipsoidalCS" type="gml:EllipsoidalCSPropertyType" substitutionGroup="gml:ellipsoidalCS">
+		<annotation>
+			<appinfo>deprecated</appinfo>
+		</annotation>
+	</element>
+	<element name="usesCartesianCS" type="gml:CartesianCSPropertyType" substitutionGroup="gml:cartesianCS">
+		<annotation>
+			<appinfo>deprecated</appinfo>
+		</annotation>
+	</element>
+	<element name="usesSphericalCS" type="gml:SphericalCSPropertyType" substitutionGroup="gml:sphericalCS">
+		<annotation>
+			<appinfo>deprecated</appinfo>
+		</annotation>
+	</element>
+	<element name="usesGeodeticDatum" type="gml:GeodeticDatumPropertyType" substitutionGroup="gml:geodeticDatum">
+		<annotation>
+			<appinfo>deprecated</appinfo>
+		</annotation>
+	</element>
+	<element name="usesVerticalCS" type="gml:VerticalCSPropertyType" substitutionGroup="gml:verticalCS">
+		<annotation>
+			<appinfo>deprecated</appinfo>
+		</annotation>
+	</element>
+	<element name="usesVerticalDatum" type="gml:VerticalDatumPropertyType" substitutionGroup="gml:verticalDatum">
+		<annotation>
+			<appinfo>deprecated</appinfo>
+		</annotation>
+	</element>
+	<element name="verticalCRSRef" type="gml:VerticalCRSPropertyType">
+		<annotation>
+			<appinfo>deprecated</appinfo>
+		</annotation>
+	</element>
+	<element name="baseGeographicCRS" type="gml:GeographicCRSPropertyType">
+		<annotation>
+			<appinfo>deprecated</appinfo>
+		</annotation>
+	</element>
+	<element name="projectedCRSRef" type="gml:ProjectedCRSPropertyType">
+		<annotation>
+			<appinfo>deprecated</appinfo>
+		</annotation>
+	</element>
+	<element name="usesCS" type="gml:CoordinateSystemPropertyType" substitutionGroup="gml:coordinateSystem">
+		<annotation>
+			<appinfo>deprecated</appinfo>
+		</annotation>
+	</element>
+	<element name="derivedCRSRef" type="gml:DerivedCRSPropertyType">
+		<annotation>
+			<appinfo>deprecated</appinfo>
+		</annotation>
+	</element>
+	<element name="usesEngineeringDatum" type="gml:EngineeringDatumPropertyType" substitutionGroup="gml:engineeringDatum">
+		<annotation>
+			<appinfo>deprecated</appinfo>
+		</annotation>
+	</element>
+	<element name="engineeringCRSRef" type="gml:EngineeringCRSPropertyType">
+		<annotation>
+			<appinfo>deprecated</appinfo>
+		</annotation>
+	</element>
+	<element name="usesAffineCS" type="gml:AffineCSPropertyType" substitutionGroup="gml:affineCS">
+		<annotation>
+			<appinfo>deprecated</appinfo>
+		</annotation>
+	</element>
+	<element name="usesImageDatum" type="gml:ImageDatumPropertyType" substitutionGroup="gml:imageDatum">
+		<annotation>
+			<appinfo>deprecated</appinfo>
+		</annotation>
+	</element>
+	<element name="usesObliqueCartesianCS" type="gml:ObliqueCartesianCSPropertyType">
+		<annotation>
+			<appinfo>deprecated</appinfo>
+		</annotation>
+	</element>
+	<element name="imageCRSRef" type="gml:ImageCRSPropertyType">
+		<annotation>
+			<appinfo>deprecated</appinfo>
+		</annotation>
+	</element>
+	<element name="usesTimeCS" type="gml:TimeCSPropertyType" substitutionGroup="gml:timeCS">
+		<annotation>
+			<appinfo>deprecated</appinfo>
+		</annotation>
+	</element>
+	<element name="usesTemporalCS" type="gml:TemporalCSPropertyType">
+		<annotation>
+			<appinfo>deprecated</appinfo>
+		</annotation>
+	</element>
+	<element name="usesTemporalDatum" type="gml:TemporalDatumPropertyType" substitutionGroup="gml:temporalDatum">
+		<annotation>
+			<appinfo>deprecated</appinfo>
+		</annotation>
+	</element>
+	<element name="temporalCRSRef" type="gml:TemporalCRSPropertyType">
+		<annotation>
+			<appinfo>deprecated</appinfo>
+		</annotation>
+	</element>
+	<element name="GeographicCRS" type="gml:GeographicCRSType" substitutionGroup="gml:AbstractSingleCRS">
+		<annotation>
+			<appinfo>deprecated</appinfo>
+		</annotation>
+	</element>
+	<complexType name="GeographicCRSType">
+		<annotation>
+			<appinfo>deprecated</appinfo>
+		</annotation>
+		<complexContent>
+			<extension base="gml:AbstractCRSType">
+				<sequence>
+					<element ref="gml:usesEllipsoidalCS"/>
+					<element ref="gml:usesGeodeticDatum"/>
+				</sequence>
+			</extension>
+		</complexContent>
+	</complexType>
+	<complexType name="GeographicCRSPropertyType">
+		<annotation>
+			<appinfo>deprecated</appinfo>
+		</annotation>
+		<sequence minOccurs="0">
+			<element ref="gml:GeographicCRS"/>
+		</sequence>
+		<attributeGroup ref="gml:AssociationAttributeGroup"/>
+	</complexType>
+	<element name="geographicCRSRef" type="gml:GeographicCRSPropertyType">
+		<annotation>
+			<appinfo>deprecated</appinfo>
+		</annotation>
+	</element>
+	<element name="GeocentricCRS" type="gml:GeocentricCRSType" substitutionGroup="gml:AbstractSingleCRS">
+		<annotation>
+			<appinfo>deprecated</appinfo>
+		</annotation>
+	</element>
+	<complexType name="GeocentricCRSType">
+		<annotation>
+			<appinfo>deprecated</appinfo>
+		</annotation>
+		<complexContent>
+			<extension base="gml:AbstractCRSType">
+				<sequence>
+					<choice>
+						<element ref="gml:usesCartesianCS"/>
+						<element ref="gml:usesSphericalCS"/>
+					</choice>
+					<element ref="gml:usesGeodeticDatum"/>
+				</sequence>
+			</extension>
+		</complexContent>
+	</complexType>
+	<complexType name="GeocentricCRSPropertyType">
+		<annotation>
+			<appinfo>deprecated</appinfo>
+		</annotation>
+		<sequence minOccurs="0">
+			<element ref="gml:GeocentricCRS"/>
+		</sequence>
+		<attributeGroup ref="gml:AssociationAttributeGroup"/>
+	</complexType>
+	<element name="geocentricCRSRef" type="gml:GeocentricCRSPropertyType">
+		<annotation>
+			<appinfo>deprecated</appinfo>
+		</annotation>
+	</element>
+	<attribute name="uom" type="anyURI">
+		<annotation>
+			<appinfo>deprecated</appinfo>
+		</annotation>
+	</attribute>
+	<simpleType name="SuccessionType">
+		<annotation>
+			<appinfo>deprecated</appinfo>
+		</annotation>
+		<restriction base="string">
+			<enumeration value="substitution"/>
+			<enumeration value="division"/>
+			<enumeration value="fusion"/>
+			<enumeration value="initiation"/>
+		</restriction>
+	</simpleType>
+	<element name="dmsAngle" type="gml:DMSAngleType">
+		<annotation>
+			<appinfo>deprecated</appinfo>
+		</annotation>
+	</element>
+	<complexType name="DMSAngleType">
+		<annotation>
+			<appinfo>deprecated</appinfo>
+		</annotation>
+		<sequence>
+			<element ref="gml:degrees"/>
+			<choice minOccurs="0">
+				<element ref="gml:decimalMinutes"/>
+				<sequence>
+					<element ref="gml:minutes"/>
+					<element ref="gml:seconds" minOccurs="0"/>
+				</sequence>
+			</choice>
+		</sequence>
+	</complexType>
+	<element name="degrees" type="gml:DegreesType">
+		<annotation>
+			<appinfo>deprecated</appinfo>
+		</annotation>
+	</element>
+	<complexType name="DegreesType">
+		<annotation>
+			<appinfo>deprecated</appinfo>
+		</annotation>
+		<simpleContent>
+			<extension base="gml:DegreeValueType">
+				<attribute name="direction">
+					<simpleType>
+						<restriction base="string">
+							<enumeration value="N"/>
+							<enumeration value="E"/>
+							<enumeration value="S"/>
+							<enumeration value="W"/>
+							<enumeration value="+"/>
+							<enumeration value="-"/>
+						</restriction>
+					</simpleType>
+				</attribute>
+			</extension>
+		</simpleContent>
+	</complexType>
+	<simpleType name="DegreeValueType">
+		<annotation>
+			<appinfo>deprecated</appinfo>
+		</annotation>
+		<restriction base="nonNegativeInteger">
+			<maxInclusive value="359"/>
+		</restriction>
+	</simpleType>
+	<element name="decimalMinutes" type="gml:DecimalMinutesType">
+		<annotation>
+			<appinfo>deprecated</appinfo>
+		</annotation>
+	</element>
+	<simpleType name="DecimalMinutesType">
+		<annotation>
+			<appinfo>deprecated</appinfo>
+		</annotation>
+		<restriction base="decimal">
+			<minInclusive value="0.00"/>
+			<maxExclusive value="60.00"/>
+		</restriction>
+	</simpleType>
+	<element name="minutes" type="gml:ArcMinutesType">
+		<annotation>
+			<appinfo>deprecated</appinfo>
+		</annotation>
+	</element>
+	<simpleType name="ArcMinutesType">
+		<annotation>
+			<appinfo>deprecated</appinfo>
+		</annotation>
+		<restriction base="nonNegativeInteger">
+			<maxInclusive value="59"/>
+		</restriction>
+	</simpleType>
+	<element name="seconds" type="gml:ArcSecondsType">
+		<annotation>
+			<appinfo>deprecated</appinfo>
+		</annotation>
+	</element>
+	<simpleType name="ArcSecondsType">
+		<annotation>
+			<appinfo>deprecated</appinfo>
+		</annotation>
+		<restriction base="decimal">
+			<minInclusive value="0.00"/>
+			<maxExclusive value="60.00"/>
+		</restriction>
+	</simpleType>
+	<complexType name="AngleChoiceType">
+		<annotation>
+			<appinfo>deprecated</appinfo>
+		</annotation>
+		<choice>
+			<element ref="gml:angle"/>
+			<element ref="gml:dmsAngle"/>
+		</choice>
+	</complexType>
+	<attribute name="remoteSchema" type="anyURI">
+		<annotation>
+			<appinfo>deprecated</appinfo>
+		</annotation>
+	</attribute>
+	<element name="member" type="gml:AssociationRoleType">
+		<annotation>
+			<appinfo>deprecated</appinfo>
+		</annotation>
+	</element>
+	<complexType name="ArrayAssociationType">
+		<annotation>
+			<appinfo>deprecated</appinfo>
+		</annotation>
+		<sequence>
+			<element ref="gml:AbstractObject" minOccurs="0" maxOccurs="unbounded"/>
+		</sequence>
+		<attributeGroup ref="gml:OwnershipAttributeGroup"/>
+	</complexType>
+	<element name="members" type="gml:ArrayAssociationType">
+		<annotation>
+			<appinfo>deprecated</appinfo>
+		</annotation>
+	</element>
+	<complexType name="StringOrRefType">
+		<annotation>
+			<appinfo>deprecated</appinfo>
+		</annotation>
+		<simpleContent>
+			<extension base="string">
+				<attributeGroup ref="gml:AssociationAttributeGroup"/>
+			</extension>
+		</simpleContent>
+	</complexType>
+	<element name="metaDataProperty" type="gml:MetaDataPropertyType">
+		<annotation>
+			<appinfo>deprecated</appinfo>
+		</annotation>
+	</element>
+	<element name="Bag" type="gml:BagType" substitutionGroup="gml:AbstractGML">
+		<annotation>
+			<appinfo>deprecated</appinfo>
+		</annotation>
+	</element>
+	<complexType name="BagType">
+		<annotation>
+			<appinfo>deprecated</appinfo>
+		</annotation>
+		<complexContent>
+			<extension base="gml:AbstractGMLType">
+				<sequence>
+					<element ref="gml:member" minOccurs="0" maxOccurs="unbounded"/>
+					<element ref="gml:members" minOccurs="0"/>
+				</sequence>
+			</extension>
+		</complexContent>
+	</complexType>
+	<element name="Array" type="gml:ArrayType" substitutionGroup="gml:AbstractGML">
+		<annotation>
+			<appinfo>deprecated</appinfo>
+		</annotation>
+	</element>
+	<complexType name="ArrayType">
+		<annotation>
+			<appinfo>deprecated</appinfo>
+		</annotation>
+		<complexContent>
+			<extension base="gml:AbstractGMLType">
+				<sequence>
+					<element ref="gml:members" minOccurs="0"/>
+				</sequence>
+			</extension>
+		</complexContent>
+	</complexType>
+	<complexType name="MetaDataPropertyType">
+		<annotation>
+			<appinfo>deprecated</appinfo>
+		</annotation>
+		<sequence minOccurs="0">
+			<element ref="gml:AbstractMetaData"/>
+		</sequence>
+		<attributeGroup ref="gml:AssociationAttributeGroup"/>
+		<attribute name="about" type="anyURI"/>
+	</complexType>
+	<element name="AbstractMetaData" type="gml:AbstractMetaDataType" abstract="true" substitutionGroup="gml:AbstractObject">
+		<annotation>
+			<appinfo>deprecated</appinfo>
+		</annotation>
+	</element>
+	<complexType name="AbstractMetaDataType" abstract="true" mixed="true">
+		<annotation>
+			<appinfo>deprecated</appinfo>
+		</annotation>
+		<sequence/>
+		<attribute ref="gml:id"/>
+	</complexType>
+	<element name="GenericMetaData" type="gml:GenericMetaDataType" substitutionGroup="gml:AbstractMetaData">
+		<annotation>
+			<appinfo>deprecated</appinfo>
+		</annotation>
+	</element>
+	<complexType name="GenericMetaDataType" mixed="true">
+		<annotation>
+			<appinfo>deprecated</appinfo>
+		</annotation>
+		<complexContent mixed="true">
+			<extension base="gml:AbstractMetaDataType">
+				<sequence>
+					<any processContents="lax" minOccurs="0" maxOccurs="unbounded"/>
+				</sequence>
+			</extension>
+		</complexContent>
+	</complexType>
+	<element name="coordinates" type="gml:CoordinatesType">
+		<annotation>
+			<appinfo>deprecated</appinfo>
+		</annotation>
+	</element>
+	<element name="pointRep" type="gml:PointPropertyType">
+		<annotation>
+			<appinfo>deprecated</appinfo>
+		</annotation>
+	</element>
+	<element name="location" type="gml:LocationPropertyType">
+		<annotation>
+			<appinfo>deprecated</appinfo>
+		</annotation>
+	</element>
+	<complexType name="LocationPropertyType">
+		<annotation>
+			<appinfo>deprecated</appinfo>
+		</annotation>
+		<sequence>
+			<choice>
+				<element ref="gml:AbstractGeometry"/>
+				<element ref="gml:LocationKeyWord"/>
+				<element ref="gml:LocationString"/>
+				<element ref="gml:Null"/>
+			</choice>
+		</sequence>
+		<attributeGroup ref="gml:AssociationAttributeGroup"/>
+	</complexType>
+	<element name="LocationString" type="gml:StringOrRefType">
+		<annotation>
+			<appinfo>deprecated</appinfo>
+		</annotation>
+	</element>
+	<element name="LocationKeyWord" type="gml:CodeType">
+		<annotation>
+			<appinfo>deprecated</appinfo>
+		</annotation>
+	</element>
+	<element name="priorityLocation" type="gml:PriorityLocationPropertyType" substitutionGroup="gml:location">
+		<annotation>
+			<appinfo>deprecated</appinfo>
+		</annotation>
+	</element>
+	<complexType name="PriorityLocationPropertyType">
+		<annotation>
+			<appinfo>deprecated</appinfo>
+		</annotation>
+		<complexContent>
+			<extension base="gml:LocationPropertyType">
+				<attribute name="priority" type="string"/>
+			</extension>
+		</complexContent>
+	</complexType>
+	<element name="featureMember" type="gml:FeaturePropertyType">
+		<annotation>
+			<appinfo>deprecated</appinfo>
+		</annotation>
+	</element>
+	<element name="featureProperty" type="gml:FeaturePropertyType">
+		<annotation>
+			<appinfo>deprecated</appinfo>
+		</annotation>
+	</element>
+	<complexType name="FeatureArrayPropertyType">
+		<annotation>
+			<appinfo>deprecated</appinfo>
+		</annotation>
+		<sequence minOccurs="0" maxOccurs="unbounded">
+			<element ref="gml:AbstractFeature"/>
+		</sequence>
+	</complexType>
+	<element name="featureMembers" type="gml:FeatureArrayPropertyType">
+		<annotation>
+			<appinfo>deprecated</appinfo>
+		</annotation>
+	</element>
+	<complexType name="BoundedFeatureType" abstract="true">
+		<annotation>
+			<appinfo>deprecated</appinfo>
+		</annotation>
+		<complexContent>
+			<restriction base="gml:AbstractFeatureType">
+				<sequence>
+					<group ref="gml:StandardObjectProperties"/>
+					<element ref="gml:boundedBy"/>
+					<element ref="gml:location" minOccurs="0"/>
+				</sequence>
+			</restriction>
+		</complexContent>
+	</complexType>
+	<complexType name="AbstractFeatureCollectionType" abstract="true">
+		<annotation>
+			<appinfo>deprecated</appinfo>
+		</annotation>
+		<complexContent>
+			<extension base="gml:AbstractFeatureType">
+				<sequence>
+					<element ref="gml:featureMember" minOccurs="0" maxOccurs="unbounded"/>
+					<element ref="gml:featureMembers" minOccurs="0"/>
+				</sequence>
+			</extension>
+		</complexContent>
+	</complexType>
+	<element name="AbstractFeatureCollection" type="gml:AbstractFeatureCollectionType" abstract="true" substitutionGroup="gml:AbstractFeature">
+		<annotation>
+			<appinfo>deprecated</appinfo>
+		</annotation>
+	</element>
+	<element name="FeatureCollection" type="gml:FeatureCollectionType" substitutionGroup="gml:AbstractFeature">
+		<annotation>
+			<appinfo>deprecated</appinfo>
+		</annotation>
+	</element>
+	<complexType name="FeatureCollectionType">
+		<annotation>
+			<appinfo>deprecated</appinfo>
+		</annotation>
+		<complexContent>
+			<extension base="gml:AbstractFeatureCollectionType"/>
+		</complexContent>
+	</complexType>
+	<element name="track" type="gml:HistoryPropertyType" substitutionGroup="gml:history">
+		<annotation>
+			<appinfo>deprecated</appinfo>
+		</annotation>
+	</element>
+	<element name="DefinitionCollection" type="gml:DictionaryType" substitutionGroup="gml:Definition">
+		<annotation>
+			<appinfo>deprecated</appinfo>
+		</annotation>
+	</element>
+	<element name="definitionMember" type="gml:DictionaryEntryType" substitutionGroup="gml:dictionaryEntry">
+		<annotation>
+			<appinfo>deprecated</appinfo>
+		</annotation>
+	</element>
+	<element name="indirectEntry" type="gml:IndirectEntryType">
+		<annotation>
+			<appinfo>deprecated</appinfo>
+		</annotation>
+	</element>
+	<complexType name="IndirectEntryType">
+		<annotation>
+			<appinfo>deprecated</appinfo>
+		</annotation>
+		<sequence>
+			<element ref="gml:DefinitionProxy"/>
+		</sequence>
+	</complexType>
+	<element name="DefinitionProxy" type="gml:DefinitionProxyType" substitutionGroup="gml:Definition">
+		<annotation>
+			<appinfo>deprecated</appinfo>
+		</annotation>
+	</element>
+	<complexType name="DefinitionProxyType">
+		<annotation>
+			<appinfo>deprecated</appinfo>
+		</annotation>
+		<complexContent>
+			<extension base="gml:DefinitionType">
+				<sequence>
+					<element ref="gml:definitionRef"/>
+				</sequence>
+			</extension>
+		</complexContent>
+	</complexType>
+	<element name="definitionRef" type="gml:ReferenceType">
+		<annotation>
+			<appinfo>deprecated</appinfo>
+		</annotation>
+	</element>
+	<element name="MappingRule" type="gml:StringOrRefType">
+		<annotation>
+			<appinfo>deprecated</appinfo>
+		</annotation>
+	</element>
+	<simpleType name="IncrementOrder">
+		<annotation>
+			<appinfo>deprecated</appinfo>
+		</annotation>
+		<restriction base="string">
+			<enumeration value="+x+y"/>
+			<enumeration value="+y+x"/>
+			<enumeration value="+x-y"/>
+			<enumeration value="-x-y"/>
+		</restriction>
+	</simpleType>
+	<element name="centerOf" type="gml:PointPropertyType">
+		<annotation>
+			<appinfo>deprecated</appinfo>
+		</annotation>
+	</element>
+	<element name="position" type="gml:PointPropertyType">
+		<annotation>
+			<appinfo>deprecated</appinfo>
+		</annotation>
+	</element>
+	<element name="extentOf" type="gml:SurfacePropertyType">
+		<annotation>
+			<appinfo>deprecated</appinfo>
+		</annotation>
+	</element>
+	<element name="edgeOf" type="gml:CurvePropertyType">
+		<annotation>
+			<appinfo>deprecated</appinfo>
+		</annotation>
+	</element>
+	<element name="centerLineOf" type="gml:CurvePropertyType">
+		<annotation>
+			<appinfo>deprecated</appinfo>
+		</annotation>
+	</element>
+	<element name="multiLocation" type="gml:MultiPointPropertyType">
+		<annotation>
+			<appinfo>deprecated</appinfo>
+		</annotation>
+	</element>
+	<element name="multiCenterOf" type="gml:MultiPointPropertyType">
+		<annotation>
+			<appinfo>deprecated</appinfo>
+		</annotation>
+	</element>
+	<element name="multiPosition" type="gml:MultiPointPropertyType">
+		<annotation>
+			<appinfo>deprecated</appinfo>
+		</annotation>
+	</element>
+	<element name="multiCenterLineOf" type="gml:MultiCurvePropertyType">
+		<annotation>
+			<appinfo>deprecated</appinfo>
+		</annotation>
+	</element>
+	<element name="multiEdgeOf" type="gml:MultiCurvePropertyType">
+		<annotation>
+			<appinfo>deprecated</appinfo>
+		</annotation>
+	</element>
+	<element name="multiCoverage" type="gml:MultiSurfacePropertyType">
+		<annotation>
+			<appinfo>deprecated</appinfo>
+		</annotation>
+	</element>
+	<element name="multiExtentOf" type="gml:MultiSurfacePropertyType">
+		<annotation>
+			<appinfo>deprecated</appinfo>
+		</annotation>
+	</element>
+	<element name="polygonPatches" type="gml:SurfacePatchArrayPropertyType" substitutionGroup="gml:patches">
+		<annotation>
+			<appinfo>deprecated</appinfo>
+		</annotation>
+	</element>
+	<element name="trianglePatches" type="gml:SurfacePatchArrayPropertyType" substitutionGroup="gml:patches">
+		<annotation>
+			<appinfo>deprecated</appinfo>
+		</annotation>
+	</element>
+	<element name="multiPointDomain" type="gml:DomainSetType" substitutionGroup="gml:domainSet">
+		<annotation>
+			<appinfo>deprecated</appinfo>
+		</annotation>
+	</element>
+	<element name="multiCurveDomain" type="gml:DomainSetType" substitutionGroup="gml:domainSet">
+		<annotation>
+			<appinfo>deprecated</appinfo>
+		</annotation>
+	</element>
+	<element name="multiSurfaceDomain" type="gml:DomainSetType" substitutionGroup="gml:domainSet">
+		<annotation>
+			<appinfo>deprecated</appinfo>
+		</annotation>
+	</element>
+	<element name="multiSolidDomain" type="gml:DomainSetType" substitutionGroup="gml:domainSet">
+		<annotation>
+			<appinfo>deprecated</appinfo>
+		</annotation>
+	</element>
+	<element name="gridDomain" type="gml:DomainSetType" substitutionGroup="gml:domainSet">
+		<annotation>
+			<appinfo>deprecated</appinfo>
+		</annotation>
+	</element>
+	<element name="rectifiedGridDomain" type="gml:DomainSetType" substitutionGroup="gml:domainSet">
+		<annotation>
+			<appinfo>deprecated</appinfo>
+		</annotation>
+	</element>
+	<element name="generalOperationParameter" type="gml:AbstractGeneralOperationParameterPropertyType" substitutionGroup="gml:parameter">
+		<annotation>
+			<appinfo>deprecated</appinfo>
+		</annotation>
+	</element>
+	<element name="MovingObjectStatus" type="gml:MovingObjectStatusType" substitutionGroup="gml:AbstractTimeSlice">
+		<annotation>
+			<appinfo>deprecated</appinfo>
+		</annotation>
+	</element>
+	<complexType name="MovingObjectStatusType">
+		<annotation>
+			<appinfo>deprecated</appinfo>
+		</annotation>
+		<complexContent>
+			<extension base="gml:AbstractTimeSliceType">
+				<sequence>
+					<choice>
+						<element name="position" type="gml:GeometryPropertyType"/>
+						<element ref="gml:pos"/>
+						<element ref="gml:locationName"/>
+						<element ref="gml:locationReference"/>
+						<element ref="gml:location"/>
+					</choice>
+					<element name="speed" type="gml:MeasureType" minOccurs="0"/>
+					<element name="bearing" type="gml:DirectionPropertyType" minOccurs="0"/>
+					<element name="acceleration" type="gml:MeasureType" minOccurs="0"/>
+					<element name="elevation" type="gml:MeasureType" minOccurs="0"/>
+					<element ref="gml:status" minOccurs="0"/>
+					<element ref="gml:statusReference" minOccurs="0"/>
+				</sequence>
+			</extension>
+		</complexContent>
+	</complexType>
+	<element name="status" type="gml:StringOrRefType">
+		<annotation>
+			<appinfo>deprecated</appinfo>
+		</annotation>
+	</element>
+	<element name="statusReference" type="gml:ReferenceType">
+		<annotation>
+			<appinfo>deprecated</appinfo>
+		</annotation>
+	</element>
+  <element name="topoComplexProperty" type="gml:TopoComplexPropertyType">
+    <annotation>
+			<appinfo>deprecated</appinfo>
+    </annotation>
+  </element>
+	<element name="multiPointProperty" type="gml:MultiPointPropertyType">
+		<annotation>
+			<appinfo>deprecated</appinfo>
+		</annotation>
+	</element>
+	<element name="multiCurveProperty" type="gml:MultiCurvePropertyType">
+		<annotation>
+			<appinfo>deprecated</appinfo>
+		</annotation>
+	</element>
+	<element name="multiSurfaceProperty" type="gml:MultiSurfacePropertyType">
+		<annotation>
+			<appinfo>deprecated</appinfo>
+		</annotation>
+	</element>
+	<element name="multiSolidProperty" type="gml:MultiSolidPropertyType">
+		<annotation>
+			<appinfo>deprecated</appinfo>
+		</annotation>
+	</element>
+	<element name="multiGeometryProperty" type="gml:MultiGeometryPropertyType">
+		<annotation>
+			<appinfo>deprecated</appinfo>
+		</annotation>
+	</element>
+	<element name="pointArrayProperty" type="gml:PointArrayPropertyType">
+		<annotation>
+			<appinfo>deprecated</appinfo>
+		</annotation>
+	</element>
+	<element name="curveArrayProperty" type="gml:CurveArrayPropertyType">
+		<annotation>
+			<appinfo>deprecated</appinfo>
+		</annotation>
+	</element>
+	<element name="surfaceArrayProperty" type="gml:SurfaceArrayPropertyType">
+		<annotation>
+			<appinfo>deprecated</appinfo>
+		</annotation>
+	</element>
+	<element name="solidArrayProperty" type="gml:SolidArrayPropertyType">
+		<annotation>
+			<appinfo>deprecated</appinfo>
+		</annotation>
+	</element>
+</schema>
diff --git a/pycsw/core/schemas/ogc/gml/3.2.1/dictionary.xsd b/pycsw/core/schemas/ogc/gml/3.2.1/dictionary.xsd
new file mode 100644
index 0000000..8d6f94a
--- /dev/null
+++ b/pycsw/core/schemas/ogc/gml/3.2.1/dictionary.xsd
@@ -0,0 +1,90 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<schema targetNamespace="http://www.opengis.net/gml/3.2" xmlns:gml="http://www.opengis.net/gml/3.2" xmlns="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" version="3.2.1.2">
+	<annotation>
+		<appinfo source="urn:opengis:specification:gml:schema-xsd:dictionary:v3.2.1">dictionary.xsd</appinfo>
+		<documentation>See ISO/DIS 19136 Clause 16.
+Many applications require definitions of terms which are used within instance documents as the values of certain properties or as reference information to tie properties to standard information values in some way.  Units of measure and descriptions of measurable phenomena are two particular examples. 
+It will often be convenient to use definitions provided by external authorities. These may already be packaged for delivery in various ways, both online and offline. In order that they may be referred to from GML documents it is generally necessary that a URI be available for each definition. Where this is the case then it is usually preferable to refer to these directly. 
+Alternatively, it may be convenient or necessary to capture definitions in XML, either embedded within an instance document containing features or as a separate document. The definitions may be transcriptions from an external source, or may be new definitions for a local purpose. In order to support this case, some simple components are provided in GML in the form of 
+-	a generic gml:Definition, which may serve as the basis for more specialized definitions
+-	a generic gml:Dictionary, which allows a set of definitions or references to definitions to be collected 
+These components may be used directly, but also serve as the basis for more specialised definition elements in GML, in particular: coordinate operations, coordinate reference systems, datums, temporal reference systems, and units of measure.  
+Note that the GML definition and dictionary components implement a simple nested hierarchy of definitions with identifiers. The latter provide handles which may be used in the description of more complex relationships between terms. However, the GML dictionary components are not intended to provide direct support for complex taxonomies, ontologies or thesauri.  Specialised XML tools are available to satisfy the more sophisticated requirements.
+
+GML is an OGC Standard.
+Copyright (c) 2007,2010 Open Geospatial Consortium.
+To obtain additional rights of use, visit http://www.opengeospatial.org/legal/ .
+		</documentation>
+	</annotation>
+	<include schemaLocation="gml.xsd"/>
+	<include schemaLocation="gmlBase.xsd"/>
+	<element name="Definition" type="gml:DefinitionType" substitutionGroup="gml:AbstractGML">
+		<annotation>
+			<documentation>The basic gml:Definition element specifies a definition, which can be included in or referenced by a dictionary. 
+The content model for a generic definition is a derivation from gml:AbstractGMLType.  
+The gml:description property element shall hold the definition if this can be captured in a simple text string, or the gml:descriptionReference property element may carry a link to a description elsewhere.
+The gml:identifier element shall provide one identifier identifying this definition. The identifier shall be unique within the dictionaries using this definition. 
+The gml:name elements shall provide zero or more terms and synonyms for which this is the definition.
+The gml:remarks element shall be used to hold additional textual information that is not conceptually part of the definition but is useful in understanding the definition.</documentation>
+		</annotation>
+	</element>
+	<complexType name="DefinitionBaseType">
+		<complexContent>
+			<restriction base="gml:AbstractGMLType">
+				<sequence>
+					<element ref="gml:metaDataProperty" minOccurs="0" maxOccurs="unbounded"/>
+					<element ref="gml:description" minOccurs="0"/>
+					<element ref="gml:descriptionReference" minOccurs="0"/>
+					<element ref="gml:identifier"/>
+					<element ref="gml:name" minOccurs="0" maxOccurs="unbounded"/>
+				</sequence>
+				<attribute ref="gml:id" use="required"/>
+			</restriction>
+		</complexContent>
+	</complexType>
+	<complexType name="DefinitionType">
+		<complexContent>
+			<extension base="gml:DefinitionBaseType">
+				<sequence>
+					<element ref="gml:remarks" minOccurs="0"/>
+				</sequence>
+			</extension>
+		</complexContent>
+	</complexType>
+	<element name="remarks" type="string"/>
+	<element name="Dictionary" type="gml:DictionaryType" substitutionGroup="gml:Definition">
+		<annotation>
+			<documentation>Sets of definitions may be collected into dictionaries or collections.
+A gml:Dictionary is a non-abstract collection of definitions.
+The gml:Dictionary content model adds a list of gml:dictionaryEntry properties that contain or reference gml:Definition objects.  A database handle (gml:id attribute) is required, in order that this collection may be referred to. The standard gml:identifier, gml:description, gml:descriptionReference and gml:name properties are available to reference or contain more information about this dictionary. The gml:description and gml:descriptionReference property elements may be used for a desc [...]
+		</annotation>
+	</element>
+	<complexType name="DictionaryType">
+		<complexContent>
+			<extension base="gml:DefinitionType">
+				<choice minOccurs="0" maxOccurs="unbounded">
+					<element ref="gml:dictionaryEntry"/>
+					<element ref="gml:indirectEntry"/>
+				</choice>
+				<attributeGroup ref="gml:AggregationAttributeGroup"/>
+			</extension>
+		</complexContent>
+	</complexType>
+	<element name="dictionaryEntry" type="gml:DictionaryEntryType">
+		<annotation>
+			<documentation>This property element contains or refers to the definitions which are members of a dictionary. 
+The content model follows the standard GML property pattern, so a gml:dictionaryEntry may either contain or refer to a single gml:Definition. Since gml:Dictionary is substitutable for gml:Definition, the content of an entry may itself be a lower level dictionary. 
+Note that if the value is provided by reference, this definition does not carry a handle (gml:id) in this context, so does not allow external references to this specific definition in this context.  When used in this way the referenced definition will usually be in a dictionary in the same XML document.</documentation>
+		</annotation>
+	</element>
+	<complexType name="DictionaryEntryType">
+		<complexContent>
+			<extension base="gml:AbstractMemberType">
+				<sequence minOccurs="0">
+					<element ref="gml:Definition"/>
+				</sequence>
+				<attributeGroup ref="gml:AssociationAttributeGroup"/>
+			</extension>
+		</complexContent>
+	</complexType>
+</schema>
diff --git a/pycsw/core/schemas/ogc/gml/3.2.1/direction.xsd b/pycsw/core/schemas/ogc/gml/3.2.1/direction.xsd
new file mode 100644
index 0000000..8b0f7f5
--- /dev/null
+++ b/pycsw/core/schemas/ogc/gml/3.2.1/direction.xsd
@@ -0,0 +1,84 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<schema targetNamespace="http://www.opengis.net/gml/3.2" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2001/XMLSchema" xmlns:gml="http://www.opengis.net/gml/3.2" elementFormDefault="qualified" attributeFormDefault="unqualified" version="3.2.1.2">
+	<annotation>
+		<appinfo source="urn:x-ogc:specification:gml:schema-xsd:direction:3.2.1">direction.xsd</appinfo>
+		<documentation>See ISO/DIS 19136 Clause 18.
+The direction schema components provide the GML Application Schema developer with a standard property element to describe direction, and associated objects that may be used to express orientation, direction, heading, bearing or other directional aspects of geographic features.
+
+GML is an OGC Standard.
+Copyright (c) 2007,2010 Open Geospatial Consortium.
+To obtain additional rights of use, visit http://www.opengeospatial.org/legal/ .
+		</documentation>
+	</annotation>
+	<include schemaLocation="gml.xsd"/>
+	<include schemaLocation="geometryBasic0d1d.xsd"/>
+	<element name="direction" type="gml:DirectionPropertyType">
+		<annotation>
+			<documentation>The property gml:direction is intended as a pre-defined property expressing a direction to be assigned to features defined in a GML application schema.</documentation>
+		</annotation>
+	</element>
+	<complexType name="DirectionPropertyType">
+		<choice minOccurs="0">
+			<element name="DirectionVector" type="gml:DirectionVectorType"/>
+			<element name="DirectionDescription" type="gml:DirectionDescriptionType"/>
+			<element name="CompassPoint" type="gml:CompassPointEnumeration"/>
+			<element name="DirectionKeyword" type="gml:CodeType"/>
+			<element name="DirectionString" type="gml:StringOrRefType"/>
+		</choice>
+		<attributeGroup ref="gml:OwnershipAttributeGroup"/>
+		<attributeGroup ref="gml:AssociationAttributeGroup"/>
+	</complexType>
+	<complexType name="DirectionVectorType">
+		<annotation>
+			<documentation>Direction vectors are specified by providing components of a vector.</documentation>
+		</annotation>
+		<choice>
+			<element ref="gml:vector"/>
+			<sequence>
+				<annotation>
+					<appinfo>deprecated</appinfo>
+				</annotation>
+				<element name="horizontalAngle" type="gml:AngleType"/>
+				<element name="verticalAngle" type="gml:AngleType"/>
+			</sequence>
+		</choice>
+	</complexType>
+	<complexType name="DirectionDescriptionType">
+		<annotation>
+			<documentation>direction descriptions are specified by a compass point code, a keyword, a textual description or a reference to a description.
+A gml:compassPoint is specified by a simple enumeration.  	
+In addition, thre elements to contain text-based descriptions of direction are provided.  
+If the direction is specified using a term from a list, gml:keyword should be used, and the list indicated using the value of the codeSpace attribute. 
+if the direction is decribed in prose, gml:direction or gml:reference should be used, allowing the value to be included inline or by reference.</documentation>
+		</annotation>
+		<choice>
+			<element name="compassPoint" type="gml:CompassPointEnumeration"/>
+			<element name="keyword" type="gml:CodeType"/>
+			<element name="description" type="string"/>
+			<element name="reference" type="gml:ReferenceType"/>
+		</choice>
+	</complexType>
+	<simpleType name="CompassPointEnumeration">
+		<annotation>
+			<documentation>These directions are necessarily approximate, giving direction with a precision of 22.5°. It is thus generally unnecessary to specify the reference frame, though this may be detailed in the definition of a GML application language.</documentation>
+		</annotation>
+		<restriction base="string">
+			<enumeration value="N"/>
+			<enumeration value="NNE"/>
+			<enumeration value="NE"/>
+			<enumeration value="ENE"/>
+			<enumeration value="E"/>
+			<enumeration value="ESE"/>
+			<enumeration value="SE"/>
+			<enumeration value="SSE"/>
+			<enumeration value="S"/>
+			<enumeration value="SSW"/>
+			<enumeration value="SW"/>
+			<enumeration value="WSW"/>
+			<enumeration value="W"/>
+			<enumeration value="WNW"/>
+			<enumeration value="NW"/>
+			<enumeration value="NNW"/>
+		</restriction>
+	</simpleType>
+</schema>
diff --git a/pycsw/core/schemas/ogc/gml/3.2.1/dynamicFeature.xsd b/pycsw/core/schemas/ogc/gml/3.2.1/dynamicFeature.xsd
new file mode 100644
index 0000000..d755067
--- /dev/null
+++ b/pycsw/core/schemas/ogc/gml/3.2.1/dynamicFeature.xsd
@@ -0,0 +1,109 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<schema targetNamespace="http://www.opengis.net/gml/3.2" xmlns:gml="http://www.opengis.net/gml/3.2" xmlns="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" version="3.2.1.2">
+	<annotation>
+		<appinfo source="urn:x-ogc:specification:gml:schema-xsd:dynamicFeature:3.2.1">dynamicFeature.xsd</appinfo>
+		<documentation>See ISO/DIS 19136 15.6.
+A number of types and relationships are defined to represent the time-varying properties of geographic features. 
+In a comprehensive treatment of spatiotemporal modeling, Langran (see Bibliography) distinguished three principal temporal entities: states, events, and evidence; the schema specified in the following Subclauses incorporates elements for each.
+
+GML is an OGC Standard.
+Copyright (c) 2007,2010 Open Geospatial Consortium.
+To obtain additional rights of use, visit http://www.opengeospatial.org/legal/ .
+		</documentation>
+	</annotation>
+	<include schemaLocation="gml.xsd"/>
+	<include schemaLocation="feature.xsd"/>
+	<include schemaLocation="direction.xsd"/>
+	<element name="dataSource" type="gml:StringOrRefType">
+		<annotation>
+			<documentation>Evidence is represented by a simple gml:dataSource or gml:dataSourceReference property that indicates the source of the temporal data. The remote link attributes of the gml:dataSource element have been deprecated along with its current type.</documentation>
+		</annotation>
+	</element>
+	<element name="dataSourceReference" type="gml:ReferenceType">
+		<annotation>
+			<documentation>Evidence is represented by a simple gml:dataSource or gml:dataSourceReference property that indicates the source of the temporal data.</documentation>
+		</annotation>
+	</element>
+	<group name="dynamicProperties">
+		<annotation>
+			<documentation>A convenience group. This allows an application schema developer to include dynamic properties in a content model in a standard fashion.</documentation>
+		</annotation>
+		<sequence>
+			<element ref="gml:validTime" minOccurs="0"/>
+			<element ref="gml:history" minOccurs="0"/>
+			<element ref="gml:dataSource" minOccurs="0"/>
+			<element ref="gml:dataSourceReference" minOccurs="0"/>
+		</sequence>
+	</group>
+	<element name="DynamicFeature" type="gml:DynamicFeatureType" substitutionGroup="gml:AbstractFeature">
+		<annotation>
+			<documentation>States are captured by time-stamped instances of a feature. The content model extends the standard gml:AbstractFeatureType with the gml:dynamicProperties model group.
+Each time-stamped instance represents a 'snapshot' of a feature. The dynamic feature classes will normally be extended to suit particular applications.  A dynamic feature bears either a time stamp or a history.</documentation>
+		</annotation>
+	</element>
+	<complexType name="DynamicFeatureType">
+		<complexContent>
+			<extension base="gml:AbstractFeatureType">
+				<group ref="gml:dynamicProperties"/>
+			</extension>
+		</complexContent>
+	</complexType>
+	<element name="DynamicFeatureCollection" type="gml:DynamicFeatureCollectionType" substitutionGroup="gml:DynamicFeature">
+		<annotation>
+			<documentation>A gml:DynamicFeatureCollection is a feature collection that has a gml:validTime property (i.e. is a snapshot of the feature collection) or which has a gml:history property that contains one or more gml:AbstractTimeSlices each of which contain values of the time varying properties of the feature collection.  Note that the gml:DynamicFeatureCollection may be one of the following:
+1.	A feature collection which consists of static feature members (members do not change in time) but which has properties of the collection object as a whole that do change in time .  
+2.	A feature collection which consists of dynamic feature members (the members are gml:DynamicFeatures) but which also has properties of the collection as a whole that vary in time.</documentation>
+		</annotation>
+	</element>
+	<complexType name="DynamicFeatureCollectionType">
+		<complexContent>
+			<extension base="gml:DynamicFeatureType">
+				<sequence>
+					<element ref="gml:dynamicMembers"/>
+				</sequence>
+			</extension>
+		</complexContent>
+	</complexType>
+	<element name="dynamicMembers" type="gml:DynamicFeatureMemberType"/>
+	<complexType name="DynamicFeatureMemberType">
+		<complexContent>
+			<extension base="gml:AbstractFeatureMemberType">
+				<sequence>
+					<element ref="gml:DynamicFeature" minOccurs="0" maxOccurs="unbounded"/>
+				</sequence>
+				<attributeGroup ref="gml:AssociationAttributeGroup"/>
+			</extension>
+		</complexContent>
+	</complexType>
+	<element name="AbstractTimeSlice" type="gml:AbstractTimeSliceType" abstract="true" substitutionGroup="gml:AbstractGML">
+		<annotation>
+			<documentation>To describe an event — an action that occurs at an instant or over an interval of time — GML provides the gml:AbtractTimeSlice element. A timeslice encapsulates the time-varying properties of a dynamic feature -- it shall be extended to represent a time stamped projection of a specific feature. The gml:dataSource property describes how the temporal data was acquired.
+A gml:AbstractTimeSlice instance is a GML object that encapsulates updates of the dynamic—or volatile—properties that reflect some change event; it thus includes only those feature properties that have actually changed due to some process.
+gml:AbstractTimeSlice basically provides a facility for attribute-level time stamping, in contrast to the object-level time stamping of dynamic feature instances. 
+The time slice can thus be viewed as event or process-oriented, whereas a snapshot is more state or structure-oriented. A timeslice has richer causality, whereas a snapshot merely portrays the status of the whole. 
+</documentation>
+		</annotation>
+	</element>
+	<complexType name="AbstractTimeSliceType" abstract="true">
+		<complexContent>
+			<extension base="gml:AbstractGMLType">
+				<sequence>
+					<element ref="gml:validTime"/>
+					<element ref="gml:dataSource" minOccurs="0"/>
+				</sequence>
+			</extension>
+		</complexContent>
+	</complexType>
+	<element name="history" type="gml:HistoryPropertyType">
+		<annotation>
+			<documentation>A generic sequence of events constitute a gml:history of an object.
+The gml:history element contains a set of elements in the substitution group headed by the abstract element gml:AbstractTimeSlice, representing the time-varying properties of interest. The history property of a dynamic feature associates a feature instance with a sequence of time slices (i.e. change events) that encapsulate the evolution of the feature.</documentation>
+		</annotation>
+	</element>
+	<complexType name="HistoryPropertyType">
+		<sequence>
+			<element ref="gml:AbstractTimeSlice" maxOccurs="unbounded"/>
+		</sequence>
+		<attributeGroup ref="gml:OwnershipAttributeGroup"/>
+	</complexType>
+</schema>
diff --git a/pycsw/core/schemas/ogc/gml/3.2.1/feature.xsd b/pycsw/core/schemas/ogc/gml/3.2.1/feature.xsd
new file mode 100644
index 0000000..1892ef6
--- /dev/null
+++ b/pycsw/core/schemas/ogc/gml/3.2.1/feature.xsd
@@ -0,0 +1,94 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<schema targetNamespace="http://www.opengis.net/gml/3.2" xmlns:gml="http://www.opengis.net/gml/3.2" xmlns="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" version="3.2.1.2">
+	<annotation>
+		<appinfo source="urn:x-ogc:specification:gml:schema-xsd:feature:3.2.1">feature.xsd</appinfo>
+		<documentation>See ISO/DIS 19136 Clause 9.
+A GML feature is a (representation of a) identifiable real-world object in a selected domain of discourse. The feature schema provides a framework for the creation of GML features and feature collections.
+
+GML is an OGC Standard.
+Copyright (c) 2007,2010 Open Geospatial Consortium.
+To obtain additional rights of use, visit http://www.opengeospatial.org/legal/ .
+		</documentation>
+	</annotation>
+	<include schemaLocation="gml.xsd"/>
+	<include schemaLocation="geometryAggregates.xsd"/>
+	<include schemaLocation="temporal.xsd"/>
+	<complexType name="AbstractFeatureType" abstract="true">
+		<annotation>
+			<documentation>The basic feature model is given by the gml:AbstractFeatureType.
+The content model for gml:AbstractFeatureType adds two specific properties suitable for geographic features to the content model defined in gml:AbstractGMLType. 
+The value of the gml:boundedBy property describes an envelope that encloses the entire feature instance, and is primarily useful for supporting rapid searching for features that occur in a particular location. 
+The value of the gml:location property describes the extent, position or relative location of the feature.</documentation>
+		</annotation>
+		<complexContent>
+			<extension base="gml:AbstractGMLType">
+				<sequence>
+					<element ref="gml:boundedBy" minOccurs="0"/>
+					<element ref="gml:location" minOccurs="0"/>
+				</sequence>
+			</extension>
+		</complexContent>
+	</complexType>
+	<element name="AbstractFeature" type="gml:AbstractFeatureType" abstract="true" substitutionGroup="gml:AbstractGML">
+		<annotation>
+			<documentation>This abstract element serves as the head of a substitution group which may contain any elements whose content model is derived from gml:AbstractFeatureType.  This may be used as a variable in the construction of content models.  
+gml:AbstractFeature may be thought of as "anything that is a GML feature" and may be used to define variables or templates in which the value of a GML property is "any feature". This occurs in particular in a GML feature collection where the feature member properties contain one or multiple copies of gml:AbstractFeature respectively.</documentation>
+		</annotation>
+	</element>
+	<complexType name="FeaturePropertyType">
+		<sequence minOccurs="0">
+			<element ref="gml:AbstractFeature"/>
+		</sequence>
+		<attributeGroup ref="gml:OwnershipAttributeGroup"/>
+		<attributeGroup ref="gml:AssociationAttributeGroup"/>
+	</complexType>
+	<element name="boundedBy" type="gml:BoundingShapeType" nillable="true">
+		<annotation>
+			<documentation>This property describes the minimum bounding box or rectangle that encloses the entire feature.</documentation>
+		</annotation>
+	</element>
+	<complexType name="BoundingShapeType">
+		<sequence>
+			<choice>
+				<element ref="gml:Envelope"/>
+				<element ref="gml:Null"/>
+			</choice>
+		</sequence>
+		<attribute name="nilReason" type="gml:NilReasonType"/>
+	</complexType>
+	<element name="EnvelopeWithTimePeriod" type="gml:EnvelopeWithTimePeriodType" substitutionGroup="gml:Envelope">
+		<annotation>
+			<documentation>gml:EnvelopeWithTimePeriod is provided for envelopes that include a temporal extent. It adds two time position properties, gml:beginPosition and gml:endPosition, which describe the extent of a time-envelope.  
+Since gml:EnvelopeWithTimePeriod is assigned to the substitution group headed by gml:Envelope, it may be used whenever gml:Envelope is valid.</documentation>
+		</annotation>
+	</element>
+	<complexType name="EnvelopeWithTimePeriodType">
+		<complexContent>
+			<extension base="gml:EnvelopeType">
+				<sequence>
+					<element name="beginPosition" type="gml:TimePositionType"/>
+					<element name="endPosition" type="gml:TimePositionType"/>
+				</sequence>
+				<attribute name="frame" type="anyURI" default="#ISO-8601"/>
+			</extension>
+		</complexContent>
+	</complexType>
+	<element name="locationName" type="gml:CodeType">
+		<annotation>
+			<documentation>The gml:locationName property element is a convenience property where the text value describes the location of the feature. If the location names are selected from a controlled list, then the list shall be identified in the codeSpace attribute.</documentation>
+		</annotation>
+	</element>
+	<element name="locationReference" type="gml:ReferenceType">
+		<annotation>
+			<documentation>The gml:locationReference property element is a convenience property where the text value referenced by the xlink:href attribute describes the location of the feature.</documentation>
+		</annotation>
+	</element>
+	<complexType name="AbstractFeatureMemberType" abstract="true">
+		<annotation>
+			<documentation>To create a collection of GML features, a property type shall be derived by extension from gml:AbstractFeatureMemberType.
+By default, this abstract property type does not imply any ownership of the features in the collection. The owns attribute of gml:OwnershipAttributeGroup may be used on a property element instance to assert ownership of a feature in the collection. A collection shall not own a feature already owned by another object.</documentation>
+		</annotation>
+		<sequence/>
+		<attributeGroup ref="gml:OwnershipAttributeGroup"/>
+	</complexType>
+</schema>
diff --git a/pycsw/core/schemas/ogc/gml/3.2.1/geometryAggregates.xsd b/pycsw/core/schemas/ogc/gml/3.2.1/geometryAggregates.xsd
new file mode 100644
index 0000000..9ffbdc0
--- /dev/null
+++ b/pycsw/core/schemas/ogc/gml/3.2.1/geometryAggregates.xsd
@@ -0,0 +1,197 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<schema targetNamespace="http://www.opengis.net/gml/3.2" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:gml="http://www.opengis.net/gml/3.2" xmlns="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" version="3.2.1.2">
+	<annotation>
+		<appinfo source="urn:x-ogc:specification:gml:schema-xsd:geometryAggregates:3.2.1">geometryAggregates.xsd</appinfo>
+		<documentation>See ISO/DIS 19136 12.3.
+Geometric aggregates (i.e. instances of a subtype of gml:AbstractGeometricAggregateType) are arbitrary aggregations of geometry elements. They are not assumed to have any additional internal structure and are used to "collect" pieces of geometry of a specified type. Application schemas may use aggregates for features that use multiple geometric objects in their representations.
+
+GML is an OGC Standard.
+Copyright (c) 2007,2010 Open Geospatial Consortium.
+To obtain additional rights of use, visit http://www.opengeospatial.org/legal/ .
+		</documentation>
+	</annotation>
+	<include schemaLocation="gml.xsd"/>
+	<include schemaLocation="geometryPrimitives.xsd"/>
+	<complexType name="AbstractGeometricAggregateType" abstract="true">
+		<complexContent>
+			<extension base="gml:AbstractGeometryType">
+				<attributeGroup ref="gml:AggregationAttributeGroup"/>
+			</extension>
+		</complexContent>
+	</complexType>
+	<element name="AbstractGeometricAggregate" type="gml:AbstractGeometricAggregateType" abstract="true" substitutionGroup="gml:AbstractGeometry">
+		<annotation>
+			<documentation>gml:AbstractGeometricAggregate is the abstract head of the substitution group for all geometric aggregates.</documentation>
+		</annotation>
+	</element>
+	<complexType name="MultiGeometryType">
+		<complexContent>
+			<extension base="gml:AbstractGeometricAggregateType">
+				<sequence>
+					<element ref="gml:geometryMember" minOccurs="0" maxOccurs="unbounded"/>
+					<element ref="gml:geometryMembers" minOccurs="0"/>
+				</sequence>
+			</extension>
+		</complexContent>
+	</complexType>
+	<element name="MultiGeometry" type="gml:MultiGeometryType" substitutionGroup="gml:AbstractGeometricAggregate">
+		<annotation>
+			<documentation>gml:MultiGeometry is a collection of one or more GML geometry objects of arbitrary type. 
+The members of the geometric aggregate may be specified either using the "standard" property (gml:geometryMember) or the array property (gml:geometryMembers). It is also valid to use both the "standard" and the array properties in the same collection.</documentation>
+		</annotation>
+	</element>
+	<element name="geometryMember" type="gml:GeometryPropertyType">
+		<annotation>
+			<documentation>This property element either references a geometry element via the XLink-attributes or contains the geometry element.</documentation>
+		</annotation>
+	</element>
+	<element name="geometryMembers" type="gml:GeometryArrayPropertyType">
+		<annotation>
+			<documentation>This property element contains a list of geometry elements. The order of the elements is significant and shall be preserved when processing the array.</documentation>
+		</annotation>
+	</element>
+	<complexType name="MultiGeometryPropertyType">
+		<annotation>
+			<documentation>A property that has a geometric aggregate as its value domain may either be an appropriate geometry element encapsulated in an element of this type or an XLink reference to a remote geometry element (where remote includes geometry elements located elsewhere in the same document). Either the reference or the contained element shall be given, but neither both nor none.</documentation>
+		</annotation>
+		<sequence minOccurs="0">
+			<element ref="gml:AbstractGeometricAggregate"/>
+		</sequence>
+		<attributeGroup ref="gml:AssociationAttributeGroup"/>
+		<attributeGroup ref="gml:OwnershipAttributeGroup"/>
+	</complexType>
+	<complexType name="MultiPointType">
+		<complexContent>
+			<extension base="gml:AbstractGeometricAggregateType">
+				<sequence>
+					<element ref="gml:pointMember" minOccurs="0" maxOccurs="unbounded"/>
+					<element ref="gml:pointMembers" minOccurs="0"/>
+				</sequence>
+			</extension>
+		</complexContent>
+	</complexType>
+	<element name="MultiPoint" type="gml:MultiPointType" substitutionGroup="gml:AbstractGeometricAggregate">
+		<annotation>
+			<documentation>A gml:MultiPoint consists of one or more gml:Points.
+The members of the geometric aggregate may be specified either using the "standard" property (gml:pointMember) or the array property (gml:pointMembers). It is also valid to use both the "standard" and the array properties in the same collection.</documentation>
+		</annotation>
+	</element>
+	<element name="pointMember" type="gml:PointPropertyType">
+		<annotation>
+			<documentation>This property element either references a Point via the XLink-attributes or contains the Point element.</documentation>
+		</annotation>
+	</element>
+	<element name="pointMembers" type="gml:PointArrayPropertyType">
+		<annotation>
+			<documentation>This property element contains a list of points. The order of the elements is significant and shall be preserved when processing the array.</documentation>
+		</annotation>
+	</element>
+	<complexType name="MultiPointPropertyType">
+		<annotation>
+			<documentation>A property that has a collection of points as its value domain may either be an appropriate geometry element encapsulated in an element of this type or an XLink reference to a remote geometry element (where remote includes geometry elements located elsewhere in the same document). Either the reference or the contained element shall be given, but neither both nor none.</documentation>
+		</annotation>
+		<sequence minOccurs="0">
+			<element ref="gml:MultiPoint"/>
+		</sequence>
+		<attributeGroup ref="gml:AssociationAttributeGroup"/>
+		<attributeGroup ref="gml:OwnershipAttributeGroup"/>
+	</complexType>
+	<complexType name="MultiCurveType">
+		<complexContent>
+			<extension base="gml:AbstractGeometricAggregateType">
+				<sequence>
+					<element ref="gml:curveMember" minOccurs="0" maxOccurs="unbounded"/>
+					<element ref="gml:curveMembers" minOccurs="0"/>
+				</sequence>
+			</extension>
+		</complexContent>
+	</complexType>
+	<element name="MultiCurve" type="gml:MultiCurveType" substitutionGroup="gml:AbstractGeometricAggregate">
+		<annotation>
+			<documentation>A gml:MultiCurve is defined by one or more gml:AbstractCurves.
+The members of the geometric aggregate may be specified either using the "standard" property (gml:curveMember) or the array property (gml:curveMembers). It is also valid to use both the "standard" and the array properties in the same collection.</documentation>
+		</annotation>
+	</element>
+	<element name="curveMembers" type="gml:CurveArrayPropertyType">
+		<annotation>
+			<documentation>This property element contains a list of curves. The order of the elements is significant and shall be preserved when processing the array.</documentation>
+		</annotation>
+	</element>
+	<complexType name="MultiCurvePropertyType">
+		<annotation>
+			<documentation>A property that has a collection of curves as its value domain may either be an appropriate geometry element encapsulated in an element of this type or an XLink reference to a remote geometry element (where remote includes geometry elements located elsewhere in the same document). Either the reference or the contained element shall be given, but neither both nor none.</documentation>
+		</annotation>
+		<sequence minOccurs="0">
+			<element ref="gml:MultiCurve"/>
+		</sequence>
+		<attributeGroup ref="gml:AssociationAttributeGroup"/>
+		<attributeGroup ref="gml:OwnershipAttributeGroup"/>
+	</complexType>
+	<complexType name="MultiSurfaceType">
+		<complexContent>
+			<extension base="gml:AbstractGeometricAggregateType">
+				<sequence>
+					<element ref="gml:surfaceMember" minOccurs="0" maxOccurs="unbounded"/>
+					<element ref="gml:surfaceMembers" minOccurs="0"/>
+				</sequence>
+			</extension>
+		</complexContent>
+	</complexType>
+	<element name="MultiSurface" type="gml:MultiSurfaceType" substitutionGroup="gml:AbstractGeometricAggregate">
+		<annotation>
+			<documentation>A gml:MultiSurface is defined by one or more gml:AbstractSurfaces.
+The members of the geometric aggregate may be specified either using the "standard" property (gml:surfaceMember) or the array property (gml:surfaceMembers). It is also valid to use both the "standard" and the array properties in the same collection.</documentation>
+		</annotation>
+	</element>
+	<element name="surfaceMembers" type="gml:SurfaceArrayPropertyType">
+		<annotation>
+			<documentation>This property element contains a list of surfaces. The order of the elements is significant and shall be preserved when processing the array.</documentation>
+		</annotation>
+	</element>
+	<complexType name="MultiSurfacePropertyType">
+		<annotation>
+			<documentation>A property that has a collection of surfaces as its value domain may either be an appropriate geometry element encapsulated in an element of this type or an XLink reference to a remote geometry element (where remote includes geometry elements located elsewhere in the same document). Either the reference or the contained element shall be given, but neither both nor none.</documentation>
+		</annotation>
+		<sequence minOccurs="0">
+			<element ref="gml:MultiSurface"/>
+		</sequence>
+		<attributeGroup ref="gml:AssociationAttributeGroup"/>
+		<attributeGroup ref="gml:OwnershipAttributeGroup"/>
+	</complexType>
+	<complexType name="MultiSolidType">
+		<complexContent>
+			<extension base="gml:AbstractGeometricAggregateType">
+				<sequence>
+					<element ref="gml:solidMember" minOccurs="0" maxOccurs="unbounded"/>
+					<element ref="gml:solidMembers" minOccurs="0"/>
+				</sequence>
+			</extension>
+		</complexContent>
+	</complexType>
+	<element name="MultiSolid" type="gml:MultiSolidType" substitutionGroup="gml:AbstractGeometricAggregate">
+		<annotation>
+			<documentation>A gml:MultiSolid is defined by one or more gml:AbstractSolids.
+The members of the geometric aggregate may be specified either using the "standard" property (gml:solidMember) or the array property (gml:solidMembers). It is also valid to use both the "standard" and the array properties in the same collection.</documentation>
+		</annotation>
+	</element>
+	<element name="solidMember" type="gml:SolidPropertyType">
+		<annotation>
+			<documentation>This property element either references a solid via the XLink-attributes or contains the solid element. A solid element is any element, which is substitutable for gml:AbstractSolid.</documentation>
+		</annotation>
+	</element>
+	<element name="solidMembers" type="gml:SolidArrayPropertyType">
+		<annotation>
+			<documentation>This property element contains a list of solids. The order of the elements is significant and shall be preserved when processing the array.</documentation>
+		</annotation>
+	</element>
+	<complexType name="MultiSolidPropertyType">
+		<annotation>
+			<documentation>A property that has a collection of solids as its value domain may either be an appropriate geometry element encapsulated in an element of this type or an XLink reference to a remote geometry element (where remote includes geometry elements located elsewhere in the same document). Either the reference or the contained element shall be given, but neither both nor none.</documentation>
+		</annotation>
+		<sequence minOccurs="0">
+			<element ref="gml:MultiSolid"/>
+		</sequence>
+		<attributeGroup ref="gml:AssociationAttributeGroup"/>
+		<attributeGroup ref="gml:OwnershipAttributeGroup"/>
+	</complexType>
+</schema>
diff --git a/pycsw/core/schemas/ogc/gml/3.2.1/geometryBasic0d1d.xsd b/pycsw/core/schemas/ogc/gml/3.2.1/geometryBasic0d1d.xsd
new file mode 100644
index 0000000..2ac83e3
--- /dev/null
+++ b/pycsw/core/schemas/ogc/gml/3.2.1/geometryBasic0d1d.xsd
@@ -0,0 +1,277 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<schema targetNamespace="http://www.opengis.net/gml/3.2" xmlns="http://www.w3.org/2001/XMLSchema" xmlns:gml="http://www.opengis.net/gml/3.2" xmlns:xlink="http://www.w3.org/1999/xlink" elementFormDefault="qualified" version="3.2.1.2">
+	<annotation>
+		<appinfo source="urn:x-ogc:specification:gml:schema-xsd:geometryBasic0d1d:3.2.1">geometryBasic0d1d.xsd</appinfo>
+		<documentation>See ISO/DIS 19136 Clause 10.
+Any geometry element that inherits the semantics of AbstractGeometryType may be viewed as a set of direct positions. 
+All of the classes derived from AbstractGeometryType inherit an optional association to a coordinate reference system. All direct positions shall directly or indirectly be associated with a coordinate reference system. When geometry elements are aggregated in another geometry element (such as a MultiGeometry or GeometricComplex), which already has a coordinate reference system specified, then these elements are assumed to be in that same coordinate reference system unless otherwise specified.
+The geometry model distinguishes geometric primitives, aggregates and complexes. 
+Geometric primitives, i.e. instances of a subtype of AbstractGeometricPrimitiveType, will be open, that is, they will not contain their boundary points; curves will not contain their end points, surfaces will not contain their boundary curves, and solids will not contain their bounding surfaces.
+
+GML is an OGC Standard.
+Copyright (c) 2007,2010 Open Geospatial Consortium.
+To obtain additional rights of use, visit http://www.opengeospatial.org/legal/ .
+		</documentation>
+	</annotation>
+	<include schemaLocation="gml.xsd"/>
+	<include schemaLocation="measures.xsd"/>
+	<complexType name="AbstractGeometryType" abstract="true">
+		<annotation>
+			<documentation>All geometry elements are derived directly or indirectly from this abstract supertype. A geometry element may have an identifying attribute (gml:id), one or more names (elements identifier and name) and a description (elements description and descriptionReference) . It may be associated with a spatial reference system (attribute group gml:SRSReferenceGroup).
+The following rules shall be adhered to:
+-	Every geometry type shall derive from this abstract type.
+-	Every geometry element (i.e. an element of a geometry type) shall be directly or indirectly in the substitution group of AbstractGeometry.</documentation>
+		</annotation>
+		<complexContent>
+			<extension base="gml:AbstractGMLType">
+				<attributeGroup ref="gml:SRSReferenceGroup"/>
+			</extension>
+		</complexContent>
+	</complexType>
+	<attributeGroup name="SRSReferenceGroup">
+		<annotation>
+			<documentation>The attribute group SRSReferenceGroup is an optional reference to the CRS used by this geometry, with optional additional information to simplify the processing of the coordinates when a more complete definition of the CRS is not needed.
+In general the attribute srsName points to a CRS instance of gml:AbstractCoordinateReferenceSystem. For well-known references it is not required that the CRS description exists at the location the URI points to. 
+If no srsName attribute is given, the CRS shall be specified as part of the larger context this geometry element is part of.</documentation>
+		</annotation>
+		<attribute name="srsName" type="anyURI"/>
+		<attribute name="srsDimension" type="positiveInteger"/>
+		<attributeGroup ref="gml:SRSInformationGroup"/>
+	</attributeGroup>
+	<attributeGroup name="SRSInformationGroup">
+		<annotation>
+			<documentation>The attributes uomLabels and axisLabels, defined in the SRSInformationGroup attribute group, are optional additional and redundant information for a CRS to simplify the processing of the coordinate values when a more complete definition of the CRS is not needed. This information shall be the same as included in the complete definition of the CRS, referenced by the srsName attribute. When the srsName attribute is included, either both or neither of the axisLabels and uom [...]
+The attribute axisLabels is an ordered list of labels for all the axes of this CRS. The gml:axisAbbrev value should be used for these axis labels, after spaces and forbidden characters are removed. When the srsName attribute is included, this attribute is optional. When the srsName attribute is omitted, this attribute shall also be omitted.
+The attribute uomLabels is an ordered list of unit of measure (uom) labels for all the axes of this CRS. The value of the string in the gml:catalogSymbol should be used for this uom labels, after spaces and forbidden characters are removed. When the axisLabels attribute is included, this attribute shall also be included. When the axisLabels attribute is omitted, this attribute shall also be omitted.</documentation>
+		</annotation>
+		<attribute name="axisLabels" type="gml:NCNameList"/>
+		<attribute name="uomLabels" type="gml:NCNameList"/>
+	</attributeGroup>
+	<element name="AbstractGeometry" type="gml:AbstractGeometryType" abstract="true" substitutionGroup="gml:AbstractGML">
+		<annotation>
+			<documentation>The AbstractGeometry element is the abstract head of the substitution group for all geometry elements of GML. This includes pre-defined and user-defined geometry elements. Any geometry element shall be a direct or indirect extension/restriction of AbstractGeometryType and shall be directly or indirectly in the substitution group of AbstractGeometry.</documentation>
+		</annotation>
+	</element>
+	<complexType name="GeometryPropertyType">
+		<annotation>
+			<documentation>A geometric property may either be any geometry element encapsulated in an element of this type or an XLink reference to a remote geometry element (where remote includes geometry elements located elsewhere in the same or another document). Note that either the reference or the contained element shall be given, but not both or none.
+If a feature has a property that takes a geometry element as its value, this is called a geometry property. A generic type for such a geometry property is GeometryPropertyType.</documentation>
+		</annotation>
+		<sequence minOccurs="0">
+			<element ref="gml:AbstractGeometry"/>
+		</sequence>
+		<attributeGroup ref="gml:AssociationAttributeGroup"/>
+		<attributeGroup ref="gml:OwnershipAttributeGroup"/>
+	</complexType>
+	<complexType name="GeometryArrayPropertyType">
+		<annotation>
+			<documentation>If a feature has a property which takes an array of geometry elements as its value, this is called a geometry array property. A generic type for such a geometry property is GeometryArrayPropertyType. 
+The elements are always contained inline in the array property, referencing geometry elements or arrays of geometry elements via XLinks is not supported.</documentation>
+		</annotation>
+		<sequence minOccurs="0" maxOccurs="unbounded">
+			<element ref="gml:AbstractGeometry"/>
+		</sequence>
+		<attributeGroup ref="gml:OwnershipAttributeGroup"/>
+	</complexType>
+	<complexType name="DirectPositionType">
+		<annotation>
+			<documentation>Direct position instances hold the coordinates for a position within some coordinate reference system (CRS). Since direct positions, as data types, will often be included in larger objects (such as geometry elements) that have references to CRS, the srsName attribute will in general be missing, if this particular direct position is included in a larger element with such a reference to a CRS. In this case, the CRS is implicitly assumed to take on the value of the contain [...]
+if no srsName attribute is given, the CRS shall be specified as part of the larger context this geometry element is part of, typically a geometric object like a point, curve, etc.</documentation>
+		</annotation>
+		<simpleContent>
+			<extension base="gml:doubleList">
+				<attributeGroup ref="gml:SRSReferenceGroup"/>
+			</extension>
+		</simpleContent>
+	</complexType>
+	<element name="pos" type="gml:DirectPositionType"/>
+	<complexType name="DirectPositionListType">
+		<annotation>
+			<documentation>posList instances (and other instances with the content model specified by DirectPositionListType) hold the coordinates for a sequence of direct positions within the same coordinate reference system (CRS).
+if no srsName attribute is given, the CRS shall be specified as part of the larger context this geometry element is part of, typically a geometric object like a point, curve, etc. 
+The optional attribute count specifies the number of direct positions in the list. If the attribute count is present then the attribute srsDimension shall be present, too.
+The number of entries in the list is equal to the product of the dimensionality of the coordinate reference system (i.e. it is a derived value of the coordinate reference system definition) and the number of direct positions.</documentation>
+		</annotation>
+		<simpleContent>
+			<extension base="gml:doubleList">
+				<attributeGroup ref="gml:SRSReferenceGroup"/>
+				<attribute name="count" type="positiveInteger"/>
+			</extension>
+		</simpleContent>
+	</complexType>
+	<element name="posList" type="gml:DirectPositionListType"/>
+	<group name="geometricPositionGroup">
+		<annotation>
+			<documentation>GML supports two different ways to specify a geometric position: either by a direct position (a data type) or a point (a geometric object).
+pos elements are positions that are "owned" by the geometric primitive encapsulating this geometric position.
+pointProperty elements contain a point that may be referenced from other geometry elements or reference another point defined elsewhere (reuse of existing points).</documentation>
+		</annotation>
+		<choice>
+			<element ref="gml:pos"/>
+			<element ref="gml:pointProperty"/>
+		</choice>
+	</group>
+	<group name="geometricPositionListGroup">
+		<annotation>
+			<documentation>GML supports two different ways to specify a list of geometric positions: either by a sequence of geometric positions (by reusing the group definition) or a sequence of direct positions (element posList). 
+The posList element allows for a compact way to specify the coordinates of the positions, if all positions are represented in the same coordinate reference system.</documentation>
+		</annotation>
+		<choice>
+			<element ref="gml:posList"/>
+			<group ref="gml:geometricPositionGroup" maxOccurs="unbounded"/>
+		</choice>
+	</group>
+	<complexType name="VectorType">
+		<annotation>
+			<documentation>For some applications the components of the position may be adjusted to yield a unit vector.</documentation>
+		</annotation>
+		<simpleContent>
+			<restriction base="gml:DirectPositionType"/>
+		</simpleContent>
+	</complexType>
+	<element name="vector" type="gml:VectorType"/>
+	<complexType name="EnvelopeType">
+		<choice>
+			<sequence>
+				<element name="lowerCorner" type="gml:DirectPositionType"/>
+				<element name="upperCorner" type="gml:DirectPositionType"/>
+			</sequence>
+			<element ref="gml:pos" minOccurs="2" maxOccurs="2">
+				<annotation>
+					<appinfo>deprecated</appinfo>
+				</annotation>
+			</element>
+			<element ref="gml:coordinates"/>
+		</choice>
+		<attributeGroup ref="gml:SRSReferenceGroup"/>
+	</complexType>
+	<element name="Envelope" type="gml:EnvelopeType" substitutionGroup="gml:AbstractObject">
+		<annotation>
+			<documentation>Envelope defines an extent using a pair of positions defining opposite corners in arbitrary dimensions. The first direct position is the "lower corner" (a coordinate position consisting of all the minimal ordinates for each dimension for all points within the envelope), the second one the "upper corner" (a coordinate position consisting of all the maximal ordinates for each dimension for all points within the envelope).
+The use of the properties "coordinates" and "pos" has been deprecated. The explicitly named properties "lowerCorner" and "upperCorner" shall be used instead.</documentation>
+		</annotation>
+	</element>
+	<complexType name="AbstractGeometricPrimitiveType" abstract="true">
+		<annotation>
+			<documentation>gml:AbstractGeometricPrimitiveType is the abstract root type of the geometric primitives. A geometric primitive is a geometric object that is not decomposed further into other primitives in the system. All primitives are oriented in the direction implied by the sequence of their coordinate tuples.</documentation>
+		</annotation>
+		<complexContent>
+			<extension base="gml:AbstractGeometryType"/>
+		</complexContent>
+	</complexType>
+	<element name="AbstractGeometricPrimitive" type="gml:AbstractGeometricPrimitiveType" abstract="true" substitutionGroup="gml:AbstractGeometry">
+		<annotation>
+			<documentation>The AbstractGeometricPrimitive element is the abstract head of the substitution group for all (pre- and user-defined) geometric primitives.</documentation>
+		</annotation>
+	</element>
+	<complexType name="GeometricPrimitivePropertyType">
+		<annotation>
+			<documentation>A property that has a geometric primitive as its value domain may either be an appropriate geometry element encapsulated in an element of this type or an XLink reference to a remote geometry element (where remote includes geometry elements located elsewhere in the same document). Either the reference or the contained element shall be given, but neither both nor none.</documentation>
+		</annotation>
+		<sequence minOccurs="0">
+			<element ref="gml:AbstractGeometricPrimitive"/>
+		</sequence>
+		<attributeGroup ref="gml:OwnershipAttributeGroup"/>
+		<attributeGroup ref="gml:AssociationAttributeGroup"/>
+	</complexType>
+	<complexType name="PointType">
+		<complexContent>
+			<extension base="gml:AbstractGeometricPrimitiveType">
+				<sequence>
+					<choice>
+						<element ref="gml:pos"/>
+						<element ref="gml:coordinates"/>
+					</choice>
+				</sequence>
+			</extension>
+		</complexContent>
+	</complexType>
+	<element name="Point" type="gml:PointType" substitutionGroup="gml:AbstractGeometricPrimitive">
+		<annotation>
+			<documentation>A Point is defined by a single coordinate tuple. The direct position of a point is specified by the pos element which is of type DirectPositionType.</documentation>
+		</annotation>
+	</element>
+	<complexType name="PointPropertyType">
+		<annotation>
+			<documentation>A property that has a point as its value domain may either be an appropriate geometry element encapsulated in an element of this type or an XLink reference to a remote geometry element (where remote includes geometry elements located elsewhere in the same document). Either the reference or the contained element shall be given, but neither both nor none.</documentation>
+		</annotation>
+		<sequence minOccurs="0">
+			<element ref="gml:Point"/>
+		</sequence>
+		<attributeGroup ref="gml:AssociationAttributeGroup"/>
+		<attributeGroup ref="gml:OwnershipAttributeGroup"/>
+	</complexType>
+	<element name="pointProperty" type="gml:PointPropertyType">
+		<annotation>
+			<documentation>This property element either references a point via the XLink-attributes or contains the point element. pointProperty is the predefined property which may be used by GML Application Schemas whenever a GML feature has a property with a value that is substitutable for Point.</documentation>
+		</annotation>
+	</element>
+	<complexType name="PointArrayPropertyType">
+		<annotation>
+			<documentation>gml:PointArrayPropertyType is a container for an array of points. The elements are always contained inline in the array property, referencing geometry elements or arrays of geometry elements via XLinks is not supported.</documentation>
+		</annotation>
+		<sequence minOccurs="0" maxOccurs="unbounded">
+			<element ref="gml:Point"/>
+		</sequence>
+		<attributeGroup ref="gml:OwnershipAttributeGroup"/>
+	</complexType>
+	<complexType name="AbstractCurveType" abstract="true">
+		<annotation>
+			<documentation>gml:AbstractCurveType is an abstraction of a curve to support the different levels of complexity. The curve may always be viewed as a geometric primitive, i.e. is continuous.</documentation>
+		</annotation>
+		<complexContent>
+			<extension base="gml:AbstractGeometricPrimitiveType"/>
+		</complexContent>
+	</complexType>
+	<element name="AbstractCurve" type="gml:AbstractCurveType" abstract="true" substitutionGroup="gml:AbstractGeometricPrimitive">
+		<annotation>
+			<documentation>The AbstractCurve element is the abstract head of the substitution group for all (continuous) curve elements.</documentation>
+		</annotation>
+	</element>
+	<complexType name="CurvePropertyType">
+		<annotation>
+			<documentation>A property that has a curve as its value domain may either be an appropriate geometry element encapsulated in an element of this type or an XLink reference to a remote geometry element (where remote includes geometry elements located elsewhere in the same document). Either the reference or the contained element shall be given, but neither both nor none.</documentation>
+		</annotation>
+		<sequence minOccurs="0">
+			<element ref="gml:AbstractCurve"/>
+		</sequence>
+		<attributeGroup ref="gml:AssociationAttributeGroup"/>
+		<attributeGroup ref="gml:OwnershipAttributeGroup"/>
+	</complexType>
+	<element name="curveProperty" type="gml:CurvePropertyType">
+		<annotation>
+			<documentation>This property element either references a curve via the XLink-attributes or contains the curve element. curveProperty is the predefined property which may be used by GML Application Schemas whenever a GML feature has a property with a value that is substitutable for AbstractCurve.</documentation>
+		</annotation>
+	</element>
+	<complexType name="CurveArrayPropertyType">
+		<annotation>
+			<documentation>A container for an array of curves. The elements are always contained in the array property, referencing geometry elements or arrays of geometry elements via XLinks is not supported.</documentation>
+		</annotation>
+		<sequence minOccurs="0" maxOccurs="unbounded">
+			<element ref="gml:AbstractCurve"/>
+		</sequence>
+		<attributeGroup ref="gml:OwnershipAttributeGroup"/>
+	</complexType>
+	<complexType name="LineStringType">
+		<complexContent>
+			<extension base="gml:AbstractCurveType">
+				<sequence>
+					<choice>
+						<choice minOccurs="2" maxOccurs="unbounded">
+							<element ref="gml:pos"/>
+							<element ref="gml:pointProperty"/>
+							<element ref="gml:pointRep"/>
+						</choice>
+						<element ref="gml:posList"/>
+						<element ref="gml:coordinates"/>
+					</choice>
+				</sequence>
+			</extension>
+		</complexContent>
+	</complexType>
+	<element name="LineString" type="gml:LineStringType" substitutionGroup="gml:AbstractCurve">
+		<annotation>
+			<documentation>A LineString is a special curve that consists of a single segment with linear interpolation. It is defined by two or more coordinate tuples, with linear interpolation between them. The number of direct positions in the list shall be at least two.</documentation>
+		</annotation>
+	</element>
+</schema>
diff --git a/pycsw/core/schemas/ogc/gml/3.2.1/geometryBasic2d.xsd b/pycsw/core/schemas/ogc/gml/3.2.1/geometryBasic2d.xsd
new file mode 100644
index 0000000..5781df5
--- /dev/null
+++ b/pycsw/core/schemas/ogc/gml/3.2.1/geometryBasic2d.xsd
@@ -0,0 +1,124 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<schema targetNamespace="http://www.opengis.net/gml/3.2" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:gml="http://www.opengis.net/gml/3.2" xmlns="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" version="3.2.1.2">
+	<annotation>
+		<appinfo source="urn:x-ogc:specification:gml:schema-xsd:geometryBasic2d:3.2.1">geometryBasic2d.xsd</appinfo>
+		<documentation>See ISO/DIS 19136 Clause 10.
+			
+			GML is an OGC Standard.
+			Copyright (c) 2007,2010 Open Geospatial Consortium.
+			To obtain additional rights of use, visit http://www.opengeospatial.org/legal/ .
+		</documentation>
+	</annotation>
+	<include schemaLocation="gml.xsd"/>
+	<include schemaLocation="geometryBasic0d1d.xsd"/>
+	<complexType name="AbstractSurfaceType" abstract="true">
+		<annotation>
+			<documentation>gml:AbstractSurfaceType is an abstraction of a surface to support the different levels of complexity. A surface is always a continuous region of a plane.</documentation>
+		</annotation>
+		<complexContent>
+			<extension base="gml:AbstractGeometricPrimitiveType"/>
+		</complexContent>
+	</complexType>
+	<element name="AbstractSurface" type="gml:AbstractSurfaceType" abstract="true" substitutionGroup="gml:AbstractGeometricPrimitive">
+		<annotation>
+			<documentation>The AbstractSurface element is the abstract head of the substitution group for all (continuous) surface elements.</documentation>
+		</annotation>
+	</element>
+	<complexType name="SurfacePropertyType">
+		<annotation>
+			<documentation>A property that has a surface as its value domain may either be an appropriate geometry element encapsulated in an element of this type or an XLink reference to a remote geometry element (where remote includes geometry elements located elsewhere in the same document). Either the reference or the contained element shall be given, but neither both nor none.</documentation>
+		</annotation>
+		<sequence minOccurs="0">
+			<element ref="gml:AbstractSurface"/>
+		</sequence>
+		<attributeGroup ref="gml:AssociationAttributeGroup"/>
+		<attributeGroup ref="gml:OwnershipAttributeGroup"/>
+	</complexType>
+	<element name="surfaceProperty" type="gml:SurfacePropertyType">
+		<annotation>
+			<documentation>This property element either references a surface via the XLink-attributes or contains the surface element. surfaceProperty is the predefined property which may be used by GML Application Schemas whenever a GML feature has a property with a value that is substitutable for AbstractSurface.</documentation>
+		</annotation>
+	</element>
+	<complexType name="SurfaceArrayPropertyType">
+		<annotation>
+			<documentation>gml:SurfaceArrayPropertyType is a container for an array of surfaces. The elements are always contained in the array property, referencing geometry elements or arrays of geometry elements via XLinks is not supported.</documentation>
+		</annotation>
+		<sequence minOccurs="0" maxOccurs="unbounded">
+			<element ref="gml:AbstractSurface"/>
+		</sequence>
+		<attributeGroup ref="gml:OwnershipAttributeGroup"/>
+	</complexType>
+	<complexType name="PolygonType">
+		<complexContent>
+			<extension base="gml:AbstractSurfaceType">
+				<sequence>
+					<element ref="gml:exterior" minOccurs="0"/>
+					<element ref="gml:interior" minOccurs="0" maxOccurs="unbounded"/>
+				</sequence>
+			</extension>
+		</complexContent>
+	</complexType>
+	<element name="Polygon" type="gml:PolygonType" substitutionGroup="gml:AbstractSurface">
+		<annotation>
+			<documentation>A Polygon is a special surface that is defined by a single surface patch (see D.3.6). The boundary of this patch is coplanar and the polygon uses planar interpolation in its interior. 
+The elements exterior and interior describe the surface boundary of the polygon.</documentation>
+		</annotation>
+	</element>
+	<element name="exterior" type="gml:AbstractRingPropertyType">
+		<annotation>
+			<documentation>A boundary of a surface consists of a number of rings. In the normal 2D case, one of these rings is distinguished as being the exterior boundary. In a general manifold this is not always possible, in which case all boundaries shall be listed as interior boundaries, and the exterior will be empty.</documentation>
+		</annotation>
+	</element>
+	<element name="interior" type="gml:AbstractRingPropertyType">
+		<annotation>
+			<documentation>A boundary of a surface consists of a number of rings. The "interior" rings separate the surface / surface patch from the area enclosed by the rings.</documentation>
+		</annotation>
+	</element>
+	<complexType name="AbstractRingType" abstract="true">
+		<sequence/>
+	</complexType>
+	<element name="AbstractRing" type="gml:AbstractRingType" abstract="true" substitutionGroup="gml:AbstractObject">
+		<annotation>
+			<documentation>An abstraction of a ring to support surface boundaries of different complexity.
+The AbstractRing element is the abstract head of the substituition group for all closed boundaries of a surface patch.</documentation>
+		</annotation>
+	</element>
+	<complexType name="AbstractRingPropertyType">
+		<annotation>
+			<documentation>A property with the content model of gml:AbstractRingPropertyType encapsulates a ring to represent the surface boundary property of a surface.</documentation>
+		</annotation>
+		<sequence>
+			<element ref="gml:AbstractRing"/>
+		</sequence>
+	</complexType>
+	<complexType name="LinearRingType">
+		<complexContent>
+			<extension base="gml:AbstractRingType">
+				<sequence>
+					<choice>
+						<choice minOccurs="4" maxOccurs="unbounded">
+							<element ref="gml:pos"/>
+							<element ref="gml:pointProperty"/>
+							<element ref="gml:pointRep"/>
+						</choice>
+						<element ref="gml:posList"/>
+						<element ref="gml:coordinates"/>
+					</choice>
+				</sequence>
+			</extension>
+		</complexContent>
+	</complexType>
+	<element name="LinearRing" type="gml:LinearRingType" substitutionGroup="gml:AbstractRing">
+		<annotation>
+			<documentation>A LinearRing is defined by four or more coordinate tuples, with linear interpolation between them; the first and last coordinates shall be coincident. The number of direct positions in the list shall be at least four.</documentation>
+		</annotation>
+	</element>
+	<complexType name="LinearRingPropertyType">
+		<annotation>
+			<documentation>A property with the content model of gml:LinearRingPropertyType encapsulates a linear ring to represent a component of a surface boundary.</documentation>
+		</annotation>
+		<sequence>
+			<element ref="gml:LinearRing"/>
+		</sequence>
+	</complexType>
+</schema>
diff --git a/pycsw/core/schemas/ogc/gml/3.2.1/geometryComplexes.xsd b/pycsw/core/schemas/ogc/gml/3.2.1/geometryComplexes.xsd
new file mode 100644
index 0000000..de4f945
--- /dev/null
+++ b/pycsw/core/schemas/ogc/gml/3.2.1/geometryComplexes.xsd
@@ -0,0 +1,95 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<schema targetNamespace="http://www.opengis.net/gml/3.2" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:gml="http://www.opengis.net/gml/3.2" xmlns="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" version="3.2.1.2">
+	<annotation>
+		<appinfo source="urn:x-ogc:specification:gml:schema-xsd:geometryComplexes:3.2.1">geometryComplexes.xsd</appinfo>
+		<documentation>See ISO/DIS 19136 12.2.
+Geometric complexes (i.e. instances of gml:GeometricComplexType) are closed collections of geometric primitives, i.e. they will contain their boundaries. 
+A geometric complex (gml:GeometricComplex) is defined by ISO 19107:2003, 6.6.1 as "a set of primitive geometric objects (in a common coordinate system) whose interiors are disjoint. Further, if a primitive is in a geometric complex, then there exists a set of primitives in that complex whose point-wise union is the boundary of this first primitive."
+A geometric composite (gml:CompositeCurve, gml:CompositeSurface and gml:CompositeSolid) represents a geometric complex with an underlying core geometry that is isomorphic to a primitive, i.e. it can be viewed as a primitive and as a complex. See ISO 19107:2003, 6.1 and 6.6.3 for more details on the nature of composite geometries.
+Geometric complexes and composites are intended to be used in application schemas where the sharing of geometry is important.
+
+GML is an OGC Standard.
+Copyright (c) 2007,2010 Open Geospatial Consortium.
+To obtain additional rights of use, visit http://www.opengeospatial.org/legal/ .
+		</documentation>
+	</annotation>
+	<include schemaLocation="gml.xsd"/>
+	<include schemaLocation="geometryAggregates.xsd"/>
+	<complexType name="GeometricComplexType">
+		<complexContent>
+			<extension base="gml:AbstractGeometryType">
+				<sequence>
+					<element name="element" type="gml:GeometricPrimitivePropertyType" maxOccurs="unbounded"/>
+				</sequence>
+				<attributeGroup ref="gml:AggregationAttributeGroup"/>
+			</extension>
+		</complexContent>
+	</complexType>
+	<element name="GeometricComplex" type="gml:GeometricComplexType" substitutionGroup="gml:AbstractGeometry"/>
+	<complexType name="GeometricComplexPropertyType">
+		<annotation>
+			<documentation>A property that has a geometric complex as its value domain may either be an appropriate geometry element encapsulated in an element of this type or an XLink reference to a remote geometry element (where remote includes geometry elements located elsewhere in the same document). Either the reference or the contained element shall be given, but neither both nor none.</documentation>
+		</annotation>
+		<sequence minOccurs="0">
+			<choice>
+				<element ref="gml:GeometricComplex"/>
+				<element ref="gml:CompositeCurve"/>
+				<element ref="gml:CompositeSurface"/>
+				<element ref="gml:CompositeSolid"/>
+			</choice>
+		</sequence>
+		<attributeGroup ref="gml:OwnershipAttributeGroup"/>
+		<attributeGroup ref="gml:AssociationAttributeGroup"/>
+	</complexType>
+	<complexType name="CompositeCurveType">
+		<complexContent>
+			<extension base="gml:AbstractCurveType">
+				<sequence>
+					<element ref="gml:curveMember" maxOccurs="unbounded"/>
+				</sequence>
+				<attributeGroup ref="gml:AggregationAttributeGroup"/>
+			</extension>
+		</complexContent>
+	</complexType>
+	<element name="CompositeCurve" type="gml:CompositeCurveType" substitutionGroup="gml:AbstractCurve">
+		<annotation>
+			<documentation>A gml:CompositeCurve is represented by a sequence of (orientable) curves such that each curve in the sequence terminates at the start point of the subsequent curve in the list. 
+curveMember references or contains inline one curve in the composite curve. 
+The curves are contiguous, the collection of curves is ordered. Therefore, if provided, the aggregationType attribute shall have the value "sequence".</documentation>
+		</annotation>
+	</element>
+	<complexType name="CompositeSurfaceType">
+		<complexContent>
+			<extension base="gml:AbstractSurfaceType">
+				<sequence>
+					<element ref="gml:surfaceMember" maxOccurs="unbounded"/>
+				</sequence>
+				<attributeGroup ref="gml:AggregationAttributeGroup"/>
+			</extension>
+		</complexContent>
+	</complexType>
+	<element name="CompositeSurface" type="gml:CompositeSurfaceType" substitutionGroup="gml:AbstractSurface">
+		<annotation>
+			<documentation>A gml:CompositeSurface is represented by a set of orientable surfaces. It is geometry type with all the geometric properties of a (primitive) surface. Essentially, a composite surface is a collection of surfaces that join in pairs on common boundary curves and which, when considered as a whole, form a single surface.
+surfaceMember references or contains inline one surface in the composite surface. 
+The surfaces are contiguous.</documentation>
+		</annotation>
+	</element>
+	<complexType name="CompositeSolidType">
+		<complexContent>
+			<extension base="gml:AbstractSolidType">
+				<sequence>
+					<element ref="gml:solidMember" maxOccurs="unbounded"/>
+				</sequence>
+				<attributeGroup ref="gml:AggregationAttributeGroup"/>
+			</extension>
+		</complexContent>
+	</complexType>
+	<element name="CompositeSolid" type="gml:CompositeSolidType" substitutionGroup="gml:AbstractSolid">
+		<annotation>
+			<documentation>gml:CompositeSolid implements ISO 19107 GM_CompositeSolid (see ISO 19107:2003, 6.6.7) as specified in D.2.3.6. 
+A gml:CompositeSolid is represented by a set of orientable surfaces. It is a geometry type with all the geometric properties of a (primitive) solid. Essentially, a composite solid is a collection of solids that join in pairs on common boundary surfaces and which, when considered as a whole, form a single solid. 
+solidMember references or contains one solid in the composite solid. The solids are contiguous.</documentation>
+		</annotation>
+	</element>
+</schema>
diff --git a/pycsw/core/schemas/ogc/gml/3.2.1/geometryPrimitives.xsd b/pycsw/core/schemas/ogc/gml/3.2.1/geometryPrimitives.xsd
new file mode 100644
index 0000000..9cbd52c
--- /dev/null
+++ b/pycsw/core/schemas/ogc/gml/3.2.1/geometryPrimitives.xsd
@@ -0,0 +1,846 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<schema targetNamespace="http://www.opengis.net/gml/3.2" xmlns="http://www.w3.org/2001/XMLSchema" xmlns:gml="http://www.opengis.net/gml/3.2" xmlns:xlink="http://www.w3.org/1999/xlink" elementFormDefault="qualified" version="3.2.1.2">
+	<annotation>
+		<appinfo source="urn:x-ogc:specification:gml:schema-xsd:geometryPrimitives:3.2.1">geometryPrimitives.xsd</appinfo>
+		<documentation>See ISO/DIS 19136 Clause 11.
+Beside the "simple" geometric primitives specified in the previous Clause, this Clause specifies additional primitives to describe real world situations which require a more expressive geometry model.
+
+GML is an OGC Standard.
+Copyright (c) 2007,2010 Open Geospatial Consortium.
+To obtain additional rights of use, visit http://www.opengeospatial.org/legal/ .
+		</documentation>
+	</annotation>
+	<include schemaLocation="gml.xsd"/>
+	<include schemaLocation="geometryBasic2d.xsd"/>
+	<complexType name="CurveType">
+		<complexContent>
+			<extension base="gml:AbstractCurveType">
+				<sequence>
+					<element ref="gml:segments"/>
+				</sequence>
+			</extension>
+		</complexContent>
+	</complexType>
+	<element name="Curve" type="gml:CurveType" substitutionGroup="gml:AbstractCurve">
+		<annotation>
+			<documentation>A curve is a 1-dimensional primitive. Curves are continuous, connected, and have a measurable length in terms of the coordinate system. 
+A curve is composed of one or more curve segments. Each curve segment within a curve may be defined using a different interpolation method. The curve segments are connected to one another, with the end point of each segment except the last being the start point of the next segment in the segment list.
+The orientation of the curve is positive.
+The element segments encapsulates the segments of the curve.</documentation>
+		</annotation>
+	</element>
+	<complexType name="OrientableCurveType">
+		<complexContent>
+			<extension base="gml:AbstractCurveType">
+				<sequence>
+					<element ref="gml:baseCurve"/>
+				</sequence>
+				<attribute name="orientation" type="gml:SignType" default="+"/>
+			</extension>
+		</complexContent>
+	</complexType>
+	<element name="baseCurve" type="gml:CurvePropertyType">
+		<annotation>
+			<documentation>The property baseCurve references or contains the base curve, i.e. it either references the base curve via the XLink-attributes or contains the curve element. A curve element is any element which is substitutable for AbstractCurve. The base curve has positive orientation.</documentation>
+		</annotation>
+	</element>
+	<element name="OrientableCurve" type="gml:OrientableCurveType" substitutionGroup="gml:AbstractCurve">
+		<annotation>
+			<documentation>OrientableCurve consists of a curve and an orientation. If the orientation is "+", then the OrientableCurve is identical to the baseCurve. If the orientation is "-", then the OrientableCurve is related to another AbstractCurve with a parameterization that reverses the sense of the curve traversal.</documentation>
+		</annotation>
+	</element>
+	<complexType name="AbstractCurveSegmentType" abstract="true">
+		<attribute name="numDerivativesAtStart" type="integer" default="0"/>
+		<attribute name="numDerivativesAtEnd" type="integer" default="0"/>
+		<attribute name="numDerivativeInterior" type="integer" default="0"/>
+	</complexType>
+	<element name="AbstractCurveSegment" type="gml:AbstractCurveSegmentType" abstract="true" substitutionGroup="gml:AbstractObject">
+		<annotation>
+			<documentation>A curve segment defines a homogeneous segment of a curve.
+The attributes numDerivativesAtStart, numDerivativesAtEnd and numDerivativesInterior specify the type of continuity as specified in ISO 19107:2003, 6.4.9.3.
+The AbstractCurveSegment element is the abstract head of the substituition group for all curve segment elements, i.e. continuous segments of the same interpolation mechanism.
+All curve segments shall have an attribute interpolation with type gml:CurveInterpolationType specifying the curve interpolation mechanism used for this segment. This mechanism uses the control points and control parameters to determine the position of this curve segment.</documentation>
+		</annotation>
+	</element>
+	<complexType name="CurveSegmentArrayPropertyType">
+		<annotation>
+			<documentation>gml:CurveSegmentArrayPropertyType is a container for an array of curve segments.</documentation>
+		</annotation>
+		<sequence minOccurs="0" maxOccurs="unbounded">
+			<element ref="gml:AbstractCurveSegment"/>
+		</sequence>
+	</complexType>
+	<element name="segments" type="gml:CurveSegmentArrayPropertyType">
+		<annotation>
+			<documentation>This property element contains a list of curve segments. The order of the elements is significant and shall be preserved when processing the array.</documentation>
+		</annotation>
+	</element>
+	<simpleType name="CurveInterpolationType">
+		<annotation>
+			<documentation>gml:CurveInterpolationType is a list of codes that may be used to identify the interpolation mechanisms specified by an application schema.</documentation>
+		</annotation>
+		<restriction base="string">
+			<enumeration value="linear"/>
+			<enumeration value="geodesic"/>
+			<enumeration value="circularArc3Points"/>
+			<enumeration value="circularArc2PointWithBulge"/>
+			<enumeration value="circularArcCenterPointWithRadius"/>
+			<enumeration value="elliptical"/>
+			<enumeration value="clothoid"/>
+			<enumeration value="conic"/>
+			<enumeration value="polynomialSpline"/>
+			<enumeration value="cubicSpline"/>
+			<enumeration value="rationalSpline"/>
+		</restriction>
+	</simpleType>
+	<complexType name="LineStringSegmentType">
+		<complexContent>
+			<extension base="gml:AbstractCurveSegmentType">
+				<sequence>
+					<choice>
+						<choice minOccurs="2" maxOccurs="unbounded">
+							<element ref="gml:pos"/>
+							<element ref="gml:pointProperty"/>
+							<element ref="gml:pointRep"/>
+						</choice>
+						<element ref="gml:posList"/>
+						<element ref="gml:coordinates"/>
+					</choice>
+				</sequence>
+				<attribute name="interpolation" type="gml:CurveInterpolationType" fixed="linear"/>
+			</extension>
+		</complexContent>
+	</complexType>
+	<element name="LineStringSegment" type="gml:LineStringSegmentType" substitutionGroup="gml:AbstractCurveSegment">
+		<annotation>
+			<documentation>A LineStringSegment is a curve segment that is defined by two or more control points including the start and end point, with linear interpolation between them.
+The content model follows the general pattern for the encoding of curve segments.</documentation>
+		</annotation>
+	</element>
+	<complexType name="ArcStringType">
+		<complexContent>
+			<extension base="gml:AbstractCurveSegmentType">
+				<sequence>
+					<choice>
+						<choice minOccurs="3" maxOccurs="unbounded">
+							<element ref="gml:pos"/>
+							<element ref="gml:pointProperty"/>
+							<element ref="gml:pointRep"/>
+						</choice>
+						<element ref="gml:posList"/>
+						<element ref="gml:coordinates"/>
+					</choice>
+				</sequence>
+				<attribute name="interpolation" type="gml:CurveInterpolationType" fixed="circularArc3Points"/>
+				<attribute name="numArc" type="integer"/>
+			</extension>
+		</complexContent>
+	</complexType>
+	<element name="ArcString" type="gml:ArcStringType" substitutionGroup="gml:AbstractCurveSegment">
+		<annotation>
+			<documentation>An ArcString is a curve segment that uses three-point circular arc interpolation ("circularArc3Points"). The number of arcs in the arc string may be explicitly stated in the attribute numArc. The number of control points in the arc string shall be 2 * numArc + 1.
+The content model follows the general pattern for the encoding of curve segments.</documentation>
+		</annotation>
+	</element>
+	<complexType name="ArcType">
+		<complexContent>
+			<restriction base="gml:ArcStringType">
+				<sequence>
+					<choice>
+						<choice minOccurs="3" maxOccurs="3">
+							<element ref="gml:pos"/>
+							<element ref="gml:pointProperty"/>
+							<element ref="gml:pointRep"/>
+						</choice>
+						<element ref="gml:posList"/>
+						<element ref="gml:coordinates"/>
+					</choice>
+				</sequence>
+				<attribute name="numArc" type="integer" fixed="1"/>
+			</restriction>
+		</complexContent>
+	</complexType>
+	<element name="Arc" type="gml:ArcType" substitutionGroup="gml:ArcString">
+		<annotation>
+			<documentation>An Arc is an arc string with only one arc unit, i.e. three control points including the start and end point. As arc is an arc string consisting of a single arc, the attribute "numArc" is fixed to "1".</documentation>
+		</annotation>
+	</element>
+	<complexType name="CircleType">
+		<complexContent>
+			<extension base="gml:ArcType"/>
+		</complexContent>
+	</complexType>
+	<element name="Circle" type="gml:CircleType" substitutionGroup="gml:Arc">
+		<annotation>
+			<documentation>A Circle is an arc whose ends coincide to form a simple closed loop. The three control points shall be distinct non-co-linear points for the circle to be unambiguously defined. The arc is simply extended past the third control point until the first control point is encountered.</documentation>
+		</annotation>
+	</element>
+	<complexType name="ArcStringByBulgeType">
+		<complexContent>
+			<extension base="gml:AbstractCurveSegmentType">
+				<sequence>
+					<choice>
+						<choice minOccurs="2" maxOccurs="unbounded">
+							<element ref="gml:pos"/>
+							<element ref="gml:pointProperty"/>
+							<element ref="gml:pointRep"/>
+						</choice>
+						<element ref="gml:posList"/>
+						<element ref="gml:coordinates"/>
+					</choice>
+					<element name="bulge" type="double" maxOccurs="unbounded"/>
+					<element name="normal" type="gml:VectorType" maxOccurs="unbounded"/>
+				</sequence>
+				<attribute name="interpolation" type="gml:CurveInterpolationType" fixed="circularArc2PointWithBulge"/>
+				<attribute name="numArc" type="integer"/>
+			</extension>
+		</complexContent>
+	</complexType>
+	<element name="ArcStringByBulge" type="gml:ArcStringByBulgeType" substitutionGroup="gml:AbstractCurveSegment">
+		<annotation>
+			<documentation>This variant of the arc computes the mid points of the arcs instead of storing the coordinates directly. The control point sequence consists of the start and end points of each arc plus the bulge (see ISO 19107:2003, 6.4.17.2). The normal is a vector normal (perpendicular) to the chord of the arc (see ISO 19107:2003, 6.4.17.4).
+The interpolation is fixed as "circularArc2PointWithBulge".
+The number of arcs in the arc string may be explicitly stated in the attribute numArc. The number of control points in the arc string shall be numArc + 1.
+The content model follows the general pattern for the encoding of curve segments.</documentation>
+		</annotation>
+	</element>
+	<complexType name="ArcByBulgeType">
+		<complexContent>
+			<restriction base="gml:ArcStringByBulgeType">
+				<sequence>
+					<choice>
+						<choice minOccurs="2" maxOccurs="2">
+							<element ref="gml:pos"/>
+							<element ref="gml:pointProperty"/>
+							<element ref="gml:pointRep"/>
+						</choice>
+						<element ref="gml:posList"/>
+						<element ref="gml:coordinates"/>
+					</choice>
+					<element name="bulge" type="double"/>
+					<element name="normal" type="gml:VectorType"/>
+				</sequence>
+				<attribute name="numArc" type="integer" fixed="1"/>
+			</restriction>
+		</complexContent>
+	</complexType>
+	<element name="ArcByBulge" type="gml:ArcByBulgeType" substitutionGroup="gml:ArcStringByBulge">
+		<annotation>
+			<documentation>An ArcByBulge is an arc string with only one arc unit, i.e. two control points, one bulge and one normal vector.
+As arc is an arc string consisting of a single arc, the attribute "numArc" is fixed to "1".</documentation>
+		</annotation>
+	</element>
+	<complexType name="ArcByCenterPointType">
+		<complexContent>
+			<extension base="gml:AbstractCurveSegmentType">
+				<sequence>
+					<choice>
+						<choice>
+							<element ref="gml:pos"/>
+							<element ref="gml:pointProperty"/>
+							<element ref="gml:pointRep"/>
+						</choice>
+						<element ref="gml:posList"/>
+						<element ref="gml:coordinates"/>
+					</choice>
+					<element name="radius" type="gml:LengthType"/>
+					<element name="startAngle" type="gml:AngleType" minOccurs="0"/>
+					<element name="endAngle" type="gml:AngleType" minOccurs="0"/>
+				</sequence>
+				<attribute name="interpolation" type="gml:CurveInterpolationType" fixed="circularArcCenterPointWithRadius"/>
+				<attribute name="numArc" type="integer" use="required" fixed="1"/>
+			</extension>
+		</complexContent>
+	</complexType>
+	<element name="ArcByCenterPoint" type="gml:ArcByCenterPointType" substitutionGroup="gml:AbstractCurveSegment">
+		<annotation>
+			<documentation>This variant of the arc requires that the points on the arc shall be computed instead of storing the coordinates directly. The single control point is the center point of the arc plus the radius and the bearing at start and end. This representation can be used only in 2D.
+The element radius specifies the radius of the arc.
+The element startAngle specifies the bearing of the arc at the start.
+The element endAngle specifies the bearing of the arc at the end.
+The interpolation is fixed as "circularArcCenterPointWithRadius".
+Since this type describes always a single arc, the attribute "numArc" is fixed to "1".
+The content model follows the general pattern for the encoding of curve segments.</documentation>
+		</annotation>
+	</element>
+	<complexType name="CircleByCenterPointType">
+		<complexContent>
+			<restriction base="gml:ArcByCenterPointType">
+				<sequence>
+					<choice>
+						<choice>
+							<element ref="gml:pos"/>
+							<element ref="gml:pointProperty"/>
+							<element ref="gml:pointRep"/>
+						</choice>
+						<element ref="gml:posList"/>
+						<element ref="gml:coordinates"/>
+					</choice>
+					<element name="radius" type="gml:LengthType"/>
+				</sequence>
+			</restriction>
+		</complexContent>
+	</complexType>
+	<element name="CircleByCenterPoint" type="gml:CircleByCenterPointType" substitutionGroup="gml:ArcByCenterPoint">
+		<annotation>
+			<documentation>A gml:CircleByCenterPoint is an gml:ArcByCenterPoint with identical start and end angle to form a full circle. Again, this representation can be used only in 2D.</documentation>
+		</annotation>
+	</element>
+	<complexType name="CubicSplineType">
+		<complexContent>
+			<extension base="gml:AbstractCurveSegmentType">
+				<sequence>
+					<choice>
+						<choice minOccurs="2" maxOccurs="unbounded">
+							<element ref="gml:pos"/>
+							<element ref="gml:pointProperty"/>
+							<element ref="gml:pointRep"/>
+						</choice>
+						<element ref="gml:posList"/>
+						<element ref="gml:coordinates"/>
+					</choice>
+					<element name="vectorAtStart" type="gml:VectorType"/>
+					<element name="vectorAtEnd" type="gml:VectorType"/>
+				</sequence>
+				<attribute name="interpolation" type="gml:CurveInterpolationType" fixed="cubicSpline"/>
+				<attribute name="degree" type="integer" fixed="3"/>
+			</extension>
+		</complexContent>
+	</complexType>
+	<element name="CubicSpline" type="gml:CubicSplineType" substitutionGroup="gml:AbstractCurveSegment">
+		<annotation>
+			<documentation>The number of control points shall be at least three.
+vectorAtStart is the unit tangent vector at the start point of the spline. vectorAtEnd is the unit tangent vector at the end point of the spline. Only the direction of the vectors shall be used to determine the shape of the cubic spline, not their length.
+interpolation is fixed as "cubicSpline".
+degree shall be the degree of the polynomial used for the interpolation in this spline. Therefore the degree for a cubic spline is fixed to "3".
+The content model follows the general pattern for the encoding of curve segments.</documentation>
+		</annotation>
+	</element>
+	<complexType name="BSplineType">
+		<complexContent>
+			<extension base="gml:AbstractCurveSegmentType">
+				<sequence>
+					<choice>
+						<choice minOccurs="0" maxOccurs="unbounded">
+							<element ref="gml:pos"/>
+							<element ref="gml:pointProperty"/>
+							<element ref="gml:pointRep"/>
+						</choice>
+						<element ref="gml:posList"/>
+						<element ref="gml:coordinates"/>
+					</choice>
+					<element name="degree" type="nonNegativeInteger"/>
+					<element name="knot" type="gml:KnotPropertyType" minOccurs="2" maxOccurs="unbounded"/>
+				</sequence>
+				<attribute name="interpolation" type="gml:CurveInterpolationType" default="polynomialSpline"/>
+				<attribute name="isPolynomial" type="boolean"/>
+				<attribute name="knotType" type="gml:KnotTypesType"/>
+			</extension>
+		</complexContent>
+	</complexType>
+	<element name="BSpline" type="gml:BSplineType" substitutionGroup="gml:AbstractCurveSegment">
+		<annotation>
+			<documentation>A B-Spline is a piecewise parametric polynomial or rational curve described in terms of control points and basis functions as specified in ISO 19107:2003, 6.4.30. Therefore, interpolation may be either "polynomialSpline" or "rationalSpline" depending on the interpolation type; default is "polynomialSpline".
+degree shall be the degree of the polynomial used for interpolation in this spline.
+knot shall be the sequence of distinct knots used to define the spline basis functions (see ISO 19107:2003, 6.4.26.2).
+The attribute isPolynomial shall be set to "true" if this is a polynomial spline (see ISO 19107:2003, 6.4.30.5).
+The attribute knotType shall provide the type of knot distribution used in defining this spline (see ISO 19107:2003, 6.4.30.4).
+The content model follows the general pattern for the encoding of curve segments.</documentation>
+		</annotation>
+	</element>
+	<complexType name="KnotType">
+		<sequence>
+			<element name="value" type="double"/>
+			<element name="multiplicity" type="nonNegativeInteger"/>
+			<element name="weight" type="double"/>
+		</sequence>
+	</complexType>
+	<complexType name="KnotPropertyType">
+		<annotation>
+			<documentation>gml:KnotPropertyType encapsulates a knot to use it in a geometric type.</documentation>
+		</annotation>
+		<sequence>
+			<element name="Knot" type="gml:KnotType">
+				<annotation>
+					<documentation>A knot is a breakpoint on a piecewise spline curve.
+value is the value of the parameter at the knot of the spline (see ISO 19107:2003, 6.4.24.2).
+multiplicity is the multiplicity of this knot used in the definition of the spline (with the same weight).
+weight is the value of the averaging weight used for this knot of the spline.</documentation>
+				</annotation>
+			</element>
+		</sequence>
+	</complexType>
+	<simpleType name="KnotTypesType">
+		<annotation>
+			<documentation>This enumeration type specifies values for the knots' type (see ISO 19107:2003, 6.4.25).</documentation>
+		</annotation>
+		<restriction base="string">
+			<enumeration value="uniform"/>
+			<enumeration value="quasiUniform"/>
+			<enumeration value="piecewiseBezier"/>
+		</restriction>
+	</simpleType>
+	<complexType name="BezierType">
+		<complexContent>
+			<restriction base="gml:BSplineType">
+				<sequence>
+					<choice>
+						<choice minOccurs="0" maxOccurs="unbounded">
+							<element ref="gml:pos"/>
+							<element ref="gml:pointProperty"/>
+							<element ref="gml:pointRep"/>
+						</choice>
+						<element ref="gml:posList"/>
+						<element ref="gml:coordinates"/>
+					</choice>
+					<element name="degree" type="nonNegativeInteger"/>
+					<element name="knot" type="gml:KnotPropertyType" minOccurs="2" maxOccurs="2"/>
+				</sequence>
+				<attribute name="interpolation" type="gml:CurveInterpolationType" fixed="polynomialSpline"/>
+				<attribute name="isPolynomial" type="boolean" fixed="true"/>
+				<attribute name="knotType" type="gml:KnotTypesType" use="prohibited"/>
+			</restriction>
+		</complexContent>
+	</complexType>
+	<element name="Bezier" type="gml:BezierType" substitutionGroup="gml:BSpline">
+		<annotation>
+			<documentation>Bezier curves are polynomial splines that use Bezier or Bernstein polynomials for interpolation purposes. It is a special case of the B-Spline curve with two knots.
+degree shall be the degree of the polynomial used for interpolation in this spline.
+knot shall be the sequence of distinct knots used to define the spline basis functions.
+interpolation is fixed as "polynomialSpline".
+isPolynomial is fixed as "true".
+knotType is not relevant for Bezier curve segments.
+</documentation>
+		</annotation>
+	</element>
+	<complexType name="OffsetCurveType">
+		<complexContent>
+			<extension base="gml:AbstractCurveSegmentType">
+				<sequence>
+					<element name="offsetBase" type="gml:CurvePropertyType"/>
+					<element name="distance" type="gml:LengthType"/>
+					<element name="refDirection" type="gml:VectorType" minOccurs="0"/>
+				</sequence>
+			</extension>
+		</complexContent>
+	</complexType>
+	<element name="OffsetCurve" type="gml:OffsetCurveType" substitutionGroup="gml:AbstractCurveSegment">
+		<annotation>
+			<documentation>An offset curve is a curve at a constant distance from the basis curve. offsetBase is the base curve from which this curve is defined as an offset. distance and refDirection have the same meaning as specified in ISO 19107:2003, 6.4.23.
+The content model follows the general pattern for the encoding of curve segments.</documentation>
+		</annotation>
+	</element>
+	<complexType name="AffinePlacementType">
+		<sequence>
+			<element name="location" type="gml:DirectPositionType"/>
+			<element name="refDirection" type="gml:VectorType" maxOccurs="unbounded"/>
+			<element name="inDimension" type="positiveInteger"/>
+			<element name="outDimension" type="positiveInteger"/>
+		</sequence>
+	</complexType>
+	<element name="AffinePlacement" type="gml:AffinePlacementType" substitutionGroup="gml:AbstractObject">
+		<annotation>
+			<documentation>location, refDirection, inDimension and outDimension have the same meaning as specified in ISO 19107:2003, 6.4.21.</documentation>
+		</annotation>
+	</element>
+	<complexType name="ClothoidType">
+		<complexContent>
+			<extension base="gml:AbstractCurveSegmentType">
+				<sequence>
+					<element name="refLocation">
+						<complexType>
+							<sequence>
+								<element ref="gml:AffinePlacement"/>
+							</sequence>
+						</complexType>
+					</element>
+					<element name="scaleFactor" type="decimal"/>
+					<element name="startParameter" type="double"/>
+					<element name="endParameter" type="double"/>
+				</sequence>
+				<attribute name="interpolation" type="gml:CurveInterpolationType" fixed="clothoid"/>
+			</extension>
+		</complexContent>
+	</complexType>
+	<element name="Clothoid" type="gml:ClothoidType" substitutionGroup="gml:AbstractCurveSegment">
+		<annotation>
+			<documentation>A clothoid, or Cornu's spiral, is plane curve whose curvature is a fixed function of its length.
+refLocation, startParameter, endParameter and scaleFactor have the same meaning as specified in ISO 19107:2003, 6.4.22.
+interpolation is fixed as "clothoid".
+The content model follows the general pattern for the encoding of curve segments.</documentation>
+		</annotation>
+	</element>
+	<complexType name="GeodesicStringType">
+		<complexContent>
+			<extension base="gml:AbstractCurveSegmentType">
+				<choice>
+					<element ref="gml:posList"/>
+					<group ref="gml:geometricPositionGroup" minOccurs="2" maxOccurs="unbounded"/>
+				</choice>
+				<attribute name="interpolation" type="gml:CurveInterpolationType" fixed="geodesic"/>
+			</extension>
+		</complexContent>
+	</complexType>
+	<element name="GeodesicString" type="gml:GeodesicStringType" substitutionGroup="gml:AbstractCurveSegment">
+		<annotation>
+			<documentation>A sequence of geodesic segments. 
+The number of control points shall be at least two.
+interpolation is fixed as "geodesic".
+The content model follows the general pattern for the encoding of curve segments.</documentation>
+		</annotation>
+	</element>
+	<complexType name="GeodesicType">
+		<complexContent>
+			<extension base="gml:GeodesicStringType"/>
+		</complexContent>
+	</complexType>
+	<element name="Geodesic" type="gml:GeodesicType" substitutionGroup="gml:GeodesicString"/>
+	<complexType name="SurfaceType">
+		<complexContent>
+			<extension base="gml:AbstractSurfaceType">
+				<sequence>
+					<element ref="gml:patches"/>
+				</sequence>
+			</extension>
+		</complexContent>
+	</complexType>
+	<element name="Surface" type="gml:SurfaceType" substitutionGroup="gml:AbstractSurface">
+		<annotation>
+			<documentation>A Surface is a 2-dimensional primitive and is composed of one or more surface patches as specified in ISO 19107:2003, 6.3.17.1. The surface patches are connected to one another.
+patches encapsulates the patches of the surface.</documentation>
+		</annotation>
+	</element>
+	<complexType name="OrientableSurfaceType">
+		<complexContent>
+			<extension base="gml:AbstractSurfaceType">
+				<sequence>
+					<element ref="gml:baseSurface"/>
+				</sequence>
+				<attribute name="orientation" type="gml:SignType" default="+"/>
+			</extension>
+		</complexContent>
+	</complexType>
+	<element name="baseSurface" type="gml:SurfacePropertyType">
+		<annotation>
+			<documentation>The property baseSurface references or contains the base surface. The property baseSurface either references the base surface via the XLink-attributes or contains the surface element. A surface element is any element which is substitutable for gml:AbstractSurface. The base surface has positive orientation.</documentation>
+		</annotation>
+	</element>
+	<element name="OrientableSurface" type="gml:OrientableSurfaceType" substitutionGroup="gml:AbstractSurface">
+		<annotation>
+			<documentation>OrientableSurface consists of a surface and an orientation. If the orientation is "+", then the OrientableSurface is identical to the baseSurface. If the orientation is "-", then the OrientableSurface is a reference to a gml:AbstractSurface with an up-normal that reverses the direction for this OrientableSurface, the sense of "the top of the surface".</documentation>
+		</annotation>
+	</element>
+	<complexType name="AbstractSurfacePatchType" abstract="true"/>
+	<element name="AbstractSurfacePatch" type="gml:AbstractSurfacePatchType" abstract="true">
+		<annotation>
+			<documentation>A surface patch defines a homogenuous portion of a surface. 
+The AbstractSurfacePatch element is the abstract head of the substituition group for all surface patch elements describing a continuous portion of a surface.
+All surface patches shall have an attribute interpolation (declared in the types derived from gml:AbstractSurfacePatchType) specifying the interpolation mechanism used for the patch using gml:SurfaceInterpolationType.</documentation>
+		</annotation>
+	</element>
+	<complexType name="SurfacePatchArrayPropertyType">
+		<annotation>
+			<documentation>gml:SurfacePatchArrayPropertyType is a container for a sequence of surface patches.</documentation>
+		</annotation>
+		<sequence minOccurs="0" maxOccurs="unbounded">
+			<element ref="gml:AbstractSurfacePatch"/>
+		</sequence>
+	</complexType>
+	<element name="patches" type="gml:SurfacePatchArrayPropertyType">
+		<annotation>
+			<documentation>The patches property element contains the sequence of surface patches. The order of the elements is significant and shall be preserved when processing the array.</documentation>
+		</annotation>
+	</element>
+	<simpleType name="SurfaceInterpolationType">
+		<annotation>
+			<documentation>gml:SurfaceInterpolationType is a list of codes that may be used to identify the interpolation mechanisms specified by an application schema.</documentation>
+		</annotation>
+		<restriction base="string">
+			<enumeration value="none"/>
+			<enumeration value="planar"/>
+			<enumeration value="spherical"/>
+			<enumeration value="elliptical"/>
+			<enumeration value="conic"/>
+			<enumeration value="tin"/>
+			<enumeration value="parametricCurve"/>
+			<enumeration value="polynomialSpline"/>
+			<enumeration value="rationalSpline"/>
+			<enumeration value="triangulatedSpline"/>
+		</restriction>
+	</simpleType>
+	<complexType name="PolygonPatchType">
+		<complexContent>
+			<extension base="gml:AbstractSurfacePatchType">
+				<sequence>
+					<element ref="gml:exterior" minOccurs="0"/>
+					<element ref="gml:interior" minOccurs="0" maxOccurs="unbounded"/>
+				</sequence>
+				<attribute name="interpolation" type="gml:SurfaceInterpolationType" fixed="planar"/>
+			</extension>
+		</complexContent>
+	</complexType>
+	<element name="PolygonPatch" type="gml:PolygonPatchType" substitutionGroup="gml:AbstractSurfacePatch">
+		<annotation>
+			<documentation>A gml:PolygonPatch is a surface patch that is defined by a set of boundary curves and an underlying surface to which these curves adhere. The curves shall be coplanar and the polygon uses planar interpolation in its interior. 
+interpolation is fixed to "planar", i.e. an interpolation shall return points on a single plane. The boundary of the patch shall be contained within that plane.</documentation>
+		</annotation>
+	</element>
+	<complexType name="TriangleType">
+		<complexContent>
+			<extension base="gml:AbstractSurfacePatchType">
+				<sequence>
+					<element ref="gml:exterior"/>
+				</sequence>
+				<attribute name="interpolation" type="gml:SurfaceInterpolationType" fixed="planar"/>
+			</extension>
+		</complexContent>
+	</complexType>
+	<element name="Triangle" type="gml:TriangleType" substitutionGroup="gml:AbstractSurfacePatch">
+		<annotation>
+			<documentation>gml:Triangle represents a triangle as a surface patch with an outer boundary consisting of a linear ring. Note that this is a polygon (subtype) with no inner boundaries. The number of points in the linear ring shall be four.
+The ring (element exterior) shall be a gml:LinearRing and shall form a triangle, the first and the last position shall be coincident.
+interpolation is fixed to "planar", i.e. an interpolation shall return points on a single plane. The boundary of the patch shall be contained within that plane.</documentation>
+		</annotation>
+	</element>
+	<complexType name="RectangleType">
+		<complexContent>
+			<extension base="gml:AbstractSurfacePatchType">
+				<sequence>
+					<element ref="gml:exterior"/>
+				</sequence>
+				<attribute name="interpolation" type="gml:SurfaceInterpolationType" fixed="planar"/>
+			</extension>
+		</complexContent>
+	</complexType>
+	<element name="Rectangle" type="gml:RectangleType" substitutionGroup="gml:AbstractSurfacePatch">
+		<annotation>
+			<documentation>gml:Rectangle represents a rectangle as a surface patch with an outer boundary consisting of a linear ring. Note that this is a polygon (subtype) with no inner boundaries. The number of points in the linear ring shall be five.
+The ring (element exterior) shall be a gml:LinearRing and shall form a rectangle; the first and the last position shall be coincident.
+interpolation is fixed to "planar", i.e. an interpolation shall return points on a single plane. The boundary of the patch shall be contained within that plane.</documentation>
+		</annotation>
+	</element>
+	<complexType name="RingType">
+		<complexContent>
+			<extension base="gml:AbstractRingType">
+				<sequence>
+					<element ref="gml:curveMember" maxOccurs="unbounded"/>
+				</sequence>
+				<attributeGroup ref="gml:AggregationAttributeGroup"/>
+			</extension>
+		</complexContent>
+	</complexType>
+	<element name="Ring" type="gml:RingType" substitutionGroup="gml:AbstractRing">
+		<annotation>
+			<documentation>A ring is used to represent a single connected component of a surface boundary as specified in ISO 19107:2003, 6.3.6.
+Every gml:curveMember references or contains one curve, i.e. any element which is substitutable for gml:AbstractCurve. In the context of a ring, the curves describe the boundary of the surface. The sequence of curves shall be contiguous and connected in a cycle.
+If provided, the aggregationType attribute shall have the value "sequence".</documentation>
+		</annotation>
+	</element>
+	<element name="curveMember" type="gml:CurvePropertyType"/>
+	<complexType name="RingPropertyType">
+		<annotation>
+			<documentation>A property with the content model of gml:RingPropertyType encapsulates a ring to represent a component of a surface boundary.</documentation>
+		</annotation>
+		<sequence>
+			<element ref="gml:Ring"/>
+		</sequence>
+	</complexType>
+	<group name="PointGrid">
+		<annotation>
+			<documentation>A gml:PointGrid group contains or references points or positions which are organised into sequences or grids. All rows shall have the same number of positions (columns).</documentation>
+		</annotation>
+		<sequence>
+			<element name="rows">
+				<complexType>
+					<sequence>
+						<element name="Row" maxOccurs="unbounded">
+							<complexType>
+								<group ref="gml:geometricPositionListGroup"/>
+							</complexType>
+						</element>
+					</sequence>
+				</complexType>
+			</element>
+		</sequence>
+	</group>
+	<complexType name="AbstractParametricCurveSurfaceType" abstract="true">
+		<complexContent>
+			<extension base="gml:AbstractSurfacePatchType">
+				<attributeGroup ref="gml:AggregationAttributeGroup"/>
+			</extension>
+		</complexContent>
+	</complexType>
+	<element name="AbstractParametricCurveSurface" type="gml:AbstractParametricCurveSurfaceType" abstract="true" substitutionGroup="gml:AbstractSurfacePatch">
+		<annotation>
+			<documentation>The element provides a substitution group head for the surface patches based on parametric curves. All properties are specified in the derived subtypes. All derived subtypes shall conform to the constraints specified in ISO 19107:2003, 6.4.40.
+If provided, the aggregationType attribute shall have the value "set".</documentation>
+		</annotation>
+	</element>
+	<complexType name="AbstractGriddedSurfaceType" abstract="true">
+		<complexContent>
+			<extension base="gml:AbstractParametricCurveSurfaceType">
+				<sequence>
+					<group ref="gml:PointGrid"/>
+				</sequence>
+				<attribute name="rows" type="integer"/>
+				<attribute name="columns" type="integer"/>
+			</extension>
+		</complexContent>
+	</complexType>
+	<element name="AbstractGriddedSurface" type="gml:AbstractGriddedSurfaceType" abstract="true" substitutionGroup="gml:AbstractParametricCurveSurface">
+		<annotation>
+			<documentation>if provided, rows gives the number of rows, columns the number of columns in the parameter grid. The parameter grid is represented by an instance of the gml:PointGrid group.
+The element provides a substitution group head for the surface patches based on a grid. All derived subtypes shall conform to the constraints specified in ISO 19107:2003, 6.4.41.</documentation>
+		</annotation>
+	</element>
+	<complexType name="ConeType">
+		<complexContent>
+			<extension base="gml:AbstractGriddedSurfaceType">
+				<attribute name="horizontalCurveType" type="gml:CurveInterpolationType" fixed="circularArc3Points"/>
+				<attribute name="verticalCurveType" type="gml:CurveInterpolationType" fixed="linear"/>
+			</extension>
+		</complexContent>
+	</complexType>
+	<element name="Cone" type="gml:ConeType" substitutionGroup="gml:AbstractGriddedSurface"/>
+	<complexType name="CylinderType">
+		<complexContent>
+			<extension base="gml:AbstractGriddedSurfaceType">
+				<attribute name="horizontalCurveType" type="gml:CurveInterpolationType" fixed="circularArc3Points"/>
+				<attribute name="verticalCurveType" type="gml:CurveInterpolationType" fixed="linear"/>
+			</extension>
+		</complexContent>
+	</complexType>
+	<element name="Cylinder" type="gml:CylinderType" substitutionGroup="gml:AbstractGriddedSurface"/>
+	<complexType name="SphereType">
+		<complexContent>
+			<extension base="gml:AbstractGriddedSurfaceType">
+				<attribute name="horizontalCurveType" type="gml:CurveInterpolationType" fixed="circularArc3Points"/>
+				<attribute name="verticalCurveType" type="gml:CurveInterpolationType" fixed="circularArc3Points"/>
+			</extension>
+		</complexContent>
+	</complexType>
+	<element name="Sphere" type="gml:SphereType" substitutionGroup="gml:AbstractGriddedSurface"/>
+	<element name="PolyhedralSurface" type="gml:SurfaceType" substitutionGroup="gml:Surface">
+		<annotation>
+			<documentation>A polyhedral surface is a surface composed of polygon patches connected along their common boundary curves. This differs from the surface type only in the restriction on the types of surface patches acceptable.
+polygonPatches encapsulates the polygon patches of the polyhedral surface.</documentation>
+		</annotation>
+	</element>
+	<element name="TriangulatedSurface" type="gml:SurfaceType" substitutionGroup="gml:Surface">
+		<annotation>
+			<documentation>A triangulated surface is a polyhedral surface that is composed only of triangles. There is no restriction on how the triangulation is derived.
+trianglePatches encapsulates the triangles of the triangulated surface.</documentation>
+		</annotation>
+	</element>
+	<complexType name="TinType">
+		<complexContent>
+			<extension base="gml:SurfaceType">
+				<sequence>
+					<element name="stopLines" type="gml:LineStringSegmentArrayPropertyType" minOccurs="0" maxOccurs="unbounded"/>
+					<element name="breakLines" type="gml:LineStringSegmentArrayPropertyType" minOccurs="0" maxOccurs="unbounded"/>
+					<element name="maxLength" type="gml:LengthType"/>
+					<element name="controlPoint">
+						<complexType>
+							<choice>
+								<element ref="gml:posList"/>
+								<group ref="gml:geometricPositionGroup" minOccurs="3" maxOccurs="unbounded"/>
+							</choice>
+						</complexType>
+					</element>
+				</sequence>
+			</extension>
+		</complexContent>
+	</complexType>
+	<element name="Tin" type="gml:TinType" substitutionGroup="gml:TriangulatedSurface">
+		<annotation>
+			<documentation>A tin is a triangulated surface that uses the Delauny algorithm or a similar algorithm complemented with consideration of stoplines (stopLines), breaklines (breakLines), and maximum length of triangle sides (maxLength). controlPoint shall contain a set of the positions (three or more) used as posts for this TIN (corners of the triangles in the TIN). See ISO 19107:2003, 6.4.39 for details.</documentation>
+		</annotation>
+	</element>
+	<complexType name="LineStringSegmentArrayPropertyType">
+		<annotation>
+			<documentation>gml:LineStringSegmentArrayPropertyType provides a container for line strings.</documentation>
+		</annotation>
+		<sequence minOccurs="0" maxOccurs="unbounded">
+			<element ref="gml:LineStringSegment"/>
+		</sequence>
+	</complexType>
+	<complexType name="AbstractSolidType">
+		<annotation>
+			<documentation>gml:AbstractSolidType is an abstraction of a solid to support the different levels of complexity. The solid may always be viewed as a geometric primitive, i.e. is contiguous.</documentation>
+		</annotation>
+		<complexContent>
+			<extension base="gml:AbstractGeometricPrimitiveType"/>
+		</complexContent>
+	</complexType>
+	<element name="AbstractSolid" type="gml:AbstractSolidType" abstract="true" substitutionGroup="gml:AbstractGeometricPrimitive">
+		<annotation>
+			<documentation>The AbstractSolid element is the abstract head of the substituition group for all (continuous) solid elements.</documentation>
+		</annotation>
+	</element>
+	<complexType name="SolidPropertyType">
+		<annotation>
+			<documentation>A property that has a solid as its value domain may either be an appropriate geometry element encapsulated in an element of this type or an XLink reference to a remote geometry element (where remote includes geometry elements located elsewhere in the same document). Either the reference or the contained element shall be given, but neither both nor none.</documentation>
+		</annotation>
+		<sequence minOccurs="0">
+			<element ref="gml:AbstractSolid"/>
+		</sequence>
+		<attributeGroup ref="gml:AssociationAttributeGroup"/>
+		<attributeGroup ref="gml:OwnershipAttributeGroup"/>
+	</complexType>
+	<element name="solidProperty" type="gml:SolidPropertyType">
+		<annotation>
+			<documentation>This property element either references a solid via the XLink-attributes or contains the solid element. solidProperty is the predefined property which may be used by GML Application Schemas whenever a GML feature has a property with a value that is substitutable for AbstractSolid.</documentation>
+		</annotation>
+	</element>
+	<complexType name="SolidArrayPropertyType">
+		<annotation>
+			<documentation>gml:SolidArrayPropertyType is a container for an array of solids. The elements are always contained in the array property, referencing geometry elements or arrays of geometry elements is not supported.</documentation>
+		</annotation>
+		<sequence minOccurs="0" maxOccurs="unbounded">
+			<element ref="gml:AbstractSolid"/>
+		</sequence>
+		<attributeGroup ref="gml:OwnershipAttributeGroup"/>
+	</complexType>
+	<complexType name="SolidType">
+		<complexContent>
+			<extension base="gml:AbstractSolidType">
+				<sequence>
+					<element name="exterior" type="gml:ShellPropertyType" minOccurs="0"/>
+					<element name="interior" type="gml:ShellPropertyType" minOccurs="0" maxOccurs="unbounded"/>
+				</sequence>
+			</extension>
+		</complexContent>
+	</complexType>
+	<element name="Solid" type="gml:SolidType" substitutionGroup="gml:AbstractSolid">
+		<annotation>
+			<documentation>A solid is the basis for 3-dimensional geometry. The extent of a solid is defined by the boundary surfaces as specified in ISO 19107:2003, 6.3.18. exterior specifies the outer boundary, interior the inner boundary of the solid.</documentation>
+		</annotation>
+	</element>
+	<complexType name="ShellType">
+		<sequence>
+			<element ref="gml:surfaceMember" maxOccurs="unbounded"/>
+		</sequence>
+		<attributeGroup ref="gml:AggregationAttributeGroup"/>
+	</complexType>
+	<element name="Shell" type="gml:ShellType" substitutionGroup="gml:AbstractObject">
+		<annotation>
+			<documentation>A shell is used to represent a single connected component of a solid boundary as specified in ISO 19107:2003, 6.3.8.
+Every gml:surfaceMember references or contains one surface, i.e. any element which is substitutable for gml:AbstractSurface. In the context of a shell, the surfaces describe the boundary of the solid. 
+If provided, the aggregationType attribute shall have the value "set".
+</documentation>
+		</annotation>
+	</element>
+	<element name="surfaceMember" type="gml:SurfacePropertyType">
+		<annotation>
+			<documentation>This property element either references a surface via the XLink-attributes or contains the surface element. A surface element is any element, which is substitutable for gml:AbstractSurface.</documentation>
+		</annotation>
+	</element>
+	<complexType name="ShellPropertyType">
+		<annotation>
+			<documentation>A property with the content model of gml:ShellPropertyType encapsulates a shell to represent a component of a solid boundary.</documentation>
+		</annotation>
+		<sequence>
+			<element ref="gml:Shell"/>
+		</sequence>
+	</complexType>
+</schema>
diff --git a/pycsw/schemas/ogc/gml/3.1.1/base/gml.xsd b/pycsw/core/schemas/ogc/gml/3.2.1/gml.xsd
similarity index 50%
rename from pycsw/schemas/ogc/gml/3.1.1/base/gml.xsd
rename to pycsw/core/schemas/ogc/gml/3.2.1/gml.xsd
index 47e4c78..b319a19 100644
--- a/pycsw/schemas/ogc/gml/3.1.1/base/gml.xsd
+++ b/pycsw/core/schemas/ogc/gml/3.2.1/gml.xsd
@@ -1,12 +1,10 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<schema targetNamespace="http://www.opengis.net/gml" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://www.w3.org/2001/XMLSchema" xmlns:sch="http://www.ascc.net/xml/schematron" xmlns:gml="http://www.opengis.net/gml"
-        xmlns:xlink="http://www.w3.org/1999/xlink" elementFormDefault="qualified" attributeFormDefault="unqualified" version="3.1.1 2010-01-28">
+<schema targetNamespace="http://www.opengis.net/gml/3.2" xmlns:gml="http://www.opengis.net/gml/3.2" xmlns="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" version="3.2.1.2">
 	<annotation>
-		<appinfo source="urn:opengis:specification:gml:schema-xsd:gml:3.1.1">gml.xsd</appinfo>
-		<documentation>Top level GML schema
-			
+		<appinfo source="urn:x-ogc:specification:gml:schema-xsd:gml:3.2.1">gml.xsd</appinfo>
+		<documentation>
 			GML is an OGC Standard.
-			Copyright (c) 2001,2005,2010 Open Geospatial Consortium, Inc. All Rights Reserved.
+			Copyright (c) 2007,2010 Open Geospatial Consortium.
 			To obtain additional rights of use, visit http://www.opengeospatial.org/legal/ .
 		</documentation>
 	</annotation>
@@ -16,7 +14,7 @@
 	<include schemaLocation="coverage.xsd"/>
 	<include schemaLocation="coordinateReferenceSystems.xsd"/>
 	<include schemaLocation="observation.xsd"/>
-	<include schemaLocation="defaultStyle.xsd"/>
 	<include schemaLocation="temporalReferenceSystems.xsd"/>
+	<include schemaLocation="deprecatedTypes.xsd"/>
 	<!-- ====================================================================== -->
-</schema>
\ No newline at end of file
+</schema>
diff --git a/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gml/gmlBase.xsd b/pycsw/core/schemas/ogc/gml/3.2.1/gmlBase.xsd
similarity index 64%
copy from pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gml/gmlBase.xsd
copy to pycsw/core/schemas/ogc/gml/3.2.1/gmlBase.xsd
index ddb0b1c..036a291 100644
--- a/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gml/gmlBase.xsd
+++ b/pycsw/core/schemas/ogc/gml/3.2.1/gmlBase.xsd
@@ -1,28 +1,23 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<schema targetNamespace="http://www.opengis.net/gml" xmlns:gml="http://www.opengis.net/gml" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sch="http://www.ascc.net/xml/schematron" xmlns="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" version="3.2.0">
+<schema targetNamespace="http://www.opengis.net/gml/3.2" xmlns:gml="http://www.opengis.net/gml/3.2" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" version="3.2.1.2">
 	<annotation>
-		<appinfo source="urn:ogc:specification:gml:schema-xsd:gmlBase:3.2.0">gmlBase.xsd</appinfo>
-		<appinfo source="urn:ogc:specification:gml:schema-xsd:gmlBase:3.2.0">
-			<sch:title>Schematron validation</sch:title>
-			<sch:ns prefix="gml" uri="http://www.opengis.net/gml"/>
-			<sch:ns prefix="xlink" uri="http://www.w3.org/1999/xlink"/>
-			<sch:pattern name="Check either href or content not both">
-				<sch:rule abstract="true" id="hrefOrContent">
-					<sch:report test="@xlink:href and (*|text())">Property element may not carry both a reference to an object and contain an object.</sch:report>
-					<sch:assert test="@xlink:href | (*|text())">Property element must either carry a reference to an object or contain an object.</sch:assert>
-				</sch:rule>
-			</sch:pattern>
-		</appinfo>
+		<appinfo source="urn:x-ogc:specification:gml:schema-xsd:gmlBase:3.2.1">gmlBase.xsd</appinfo>
 		<documentation>See ISO/DIS 19136 7.2.
 The gmlBase schema components establish the GML model and syntax, in particular
 -	a root XML type from which XML types for all GML objects should be derived,
 -	a pattern and components for GML properties,
 -	patterns for collections and arrays, and components for generic collections and arrays,
 -	components for associating metadata with GML objects,
--	components for constructing definitions and dictionaries.</documentation>
+-	components for constructing definitions and dictionaries.
+
+GML is an OGC Standard.
+Copyright (c) 2007,2010 Open Geospatial Consortium.
+To obtain additional rights of use, visit http://www.opengeospatial.org/legal/ .
+		</documentation>
 	</annotation>
+	<include schemaLocation="gml.xsd"/>
 	<include schemaLocation="basicTypes.xsd"/>
-	<import namespace="http://www.w3.org/1999/xlink" schemaLocation="../../../../../../../../../../pycsw/schemas/w3c/1999/xlink.xsd"/>
+	<import namespace="http://www.w3.org/1999/xlink" schemaLocation="../../../w3c/1999/xlink.xsd"/>
 	<element name="AbstractObject" abstract="true">
 		<annotation>
 			<documentation>This element has no type defined, and is therefore implicitly (according to the rules of W3C XML Schema) an XML Schema anyType. It is used as the head of an XML Schema substitution group which unifies complex content and certain simple content elements used for datatypes in GML, including the gml:AbstractGML substitution group.</documentation>
@@ -30,7 +25,7 @@ The gmlBase schema components establish the GML model and syntax, in particular
 	</element>
 	<element name="AbstractGML" type="gml:AbstractGMLType" abstract="true" substitutionGroup="gml:AbstractObject">
 		<annotation>
-			<documentation>The abstract element gml:AbstractGML is “any GML object having identity”.   It acts as the head of an XML Schema substitution group, which may include any element which is a GML feature, or other object, with identity.  This is used as a variable in content models in GML core and application schemas.  It is effectively an abstract superclass for all GML objects.</documentation>
+			<documentation>The abstract element gml:AbstractGML is "any GML object having identity".   It acts as the head of an XML Schema substitution group, which may include any element which is a GML feature, or other object, with identity.  This is used as a variable in content models in GML core and application schemas.  It is effectively an abstract superclass for all GML objects.</documentation>
 		</annotation>
 	</element>
 	<complexType name="AbstractGMLType" abstract="true">
@@ -54,32 +49,31 @@ The gmlBase schema components establish the GML model and syntax, in particular
 		</annotation>
 		<attributeGroup ref="xlink:simpleAttrs"/>
 		<attribute name="nilReason" type="gml:NilReasonType"/>
-		<attribute ref="gml:remoteSchema"/>
+		<attribute ref="gml:remoteSchema">
+			<annotation>
+				<appinfo>deprecated</appinfo>
+			</annotation>
+		</attribute>
 	</attributeGroup>
-	<attribute name="remoteSchema" type="anyURI">
-		<annotation>
-			<appinfo>deprecated</appinfo>
-		</annotation>
-	</attribute>
 	<element name="abstractAssociationRole" type="gml:AssociationRoleType" abstract="true">
 		<annotation>
 			<documentation>Applying this pattern shall restrict the multiplicity of objects in a property element using this content model to exactly one. An instance of this type shall contain an element representing an object, or serve as a pointer to a remote object.
 Applying the pattern to define an application schema specific property type allows to restrict
 -	the inline object to specified object types, 
--	the encoding to „by-reference only“ (see 7.2.3.7),
--	the encoding to „inline only“ (see 7.2.3.8).</documentation>
+-	the encoding to "by-reference only" (see 7.2.3.7),
+-	the encoding to "inline only" (see 7.2.3.8).</documentation>
 		</annotation>
 	</element>
 	<complexType name="AssociationRoleType">
 		<sequence minOccurs="0">
-			<element ref="gml:AbstractObject"/>
+			<any namespace="##any"/>
 		</sequence>
 		<attributeGroup ref="gml:OwnershipAttributeGroup"/>
 		<attributeGroup ref="gml:AssociationAttributeGroup"/>
 	</complexType>
 	<attributeGroup name="OwnershipAttributeGroup">
 		<annotation>
-			<documentation>Encoding a GML property inline vs. by-reference shall not imply anything about the “ownership” of the contained or referenced GML Object, i.e. the encoding style shall not imply any “deep-copy” or “deep-delete” semantics. To express ownership over the contained or referenced GML Object, the gml:OwnershipAttributeGroup attribute group may be added to object-valued property elements. If the attribute group is not part of the content model of such a property element, then  [...]
+			<documentation>Encoding a GML property inline vs. by-reference shall not imply anything about the "ownership" of the contained or referenced GML Object, i.e. the encoding style shall not imply any "deep-copy" or "deep-delete" semantics. To express ownership over the contained or referenced GML Object, the gml:OwnershipAttributeGroup attribute group may be added to object-valued property elements. If the attribute group is not part of the content model of such a property element, then  [...]
 When the value of the owns attribute is "true", the existence of inline or referenced object(s) depends upon the existence of the parent object.</documentation>
 		</annotation>
 		<attribute name="owns" type="boolean" default="false"/>
@@ -89,13 +83,6 @@ When the value of the owns attribute is "true", the existence of inline or refer
 			<documentation>This element shows how an element 
 	declaration may include a Schematron constraint to limit the property to act 
 	in either inline or by-reference mode, but not both.</documentation>
-			<appinfo>
-				<sch:pattern name="refAndContent co-occurence prohibited">
-					<sch:rule context="gml:abstractStrictAssociationRole">
-						<sch:extends rule="hrefOrContent"/>
-					</sch:rule>
-				</sch:pattern>
-			</appinfo>
 		</annotation>
 	</element>
 	<element name="abstractReference" type="gml:ReferenceType" abstract="true">
@@ -105,7 +92,7 @@ When the value of the owns attribute is "true", the existence of inline or refer
 	</element>
 	<complexType name="ReferenceType">
 		<annotation>
-			<documentation>gml:ReferenceType is intended to be used in application schemas directly, if a property element shall use a “by-reference only” encoding.</documentation>
+			<documentation>gml:ReferenceType is intended to be used in application schemas directly, if a property element shall use a "by-reference only" encoding.</documentation>
 		</annotation>
 		<sequence/>
 		<attributeGroup ref="gml:OwnershipAttributeGroup"/>
@@ -118,7 +105,7 @@ When the value of the owns attribute is "true", the existence of inline or refer
 	</element>
 	<complexType name="InlinePropertyType">
 		<sequence>
-			<element ref="gml:AbstractObject"/>
+			<any namespace="##any"/>
 		</sequence>
 		<attributeGroup ref="gml:OwnershipAttributeGroup"/>
 	</complexType>
@@ -127,40 +114,6 @@ When the value of the owns attribute is "true", the existence of inline or refer
 			<documentation>If the value of an object property is another object and that object contains also a property for the association between the two objects, then this name of the reverse property may be encoded in a gml:reversePropertyName element in an appinfo annotation of the property element to document the constraint between the two properties. The value of the element shall contain the qualified name of the property element.</documentation>
 		</annotation>
 	</element>
-	<element name="member" type="gml:AssociationRoleType">
-		<annotation>
-			<appinfo>deprecated</appinfo>
-		</annotation>
-	</element>
-	<complexType name="ArrayAssociationType">
-		<annotation>
-			<appinfo>deprecated</appinfo>
-		</annotation>
-		<sequence>
-			<element ref="gml:AbstractObject" minOccurs="0" maxOccurs="unbounded"/>
-		</sequence>
-		<attributeGroup ref="gml:OwnershipAttributeGroup"/>
-	</complexType>
-	<element name="members" type="gml:ArrayAssociationType">
-		<annotation>
-			<appinfo>deprecated</appinfo>
-		</annotation>
-	</element>
-	<complexType name="StringOrRefType">
-		<annotation>
-			<appinfo>deprecated</appinfo>
-		</annotation>
-		<simpleContent>
-			<extension base="string">
-				<attributeGroup ref="gml:AssociationAttributeGroup"/>
-			</extension>
-		</simpleContent>
-	</complexType>
-	<element name="metaDataProperty" type="gml:MetaDataPropertyType">
-		<annotation>
-			<appinfo>deprecated</appinfo>
-		</annotation>
-	</element>
 	<element name="description" type="gml:StringOrRefType">
 		<annotation>
 			<documentation>The value of this property is a text description of the object. gml:description uses gml:StringOrRefType as its content model, so it may contain a simple text string content, or carry a reference to an external description. The use of gml:description to reference an external description has been deprecated and replaced by the gml:descriptionReference property.</documentation>
@@ -214,41 +167,6 @@ The allowed values for the aggregationType attribute are defined by gml:Aggregat
 			<enumeration value="table"/>
 		</restriction>
 	</simpleType>
-	<element name="Bag" type="gml:BagType" substitutionGroup="gml:AbstractGML">
-		<annotation>
-			<appinfo>deprecated</appinfo>
-		</annotation>
-	</element>
-	<complexType name="BagType">
-		<annotation>
-			<appinfo>deprecated</appinfo>
-		</annotation>
-		<complexContent>
-			<extension base="gml:AbstractGMLType">
-				<sequence>
-					<element ref="gml:member" minOccurs="0" maxOccurs="unbounded"/>
-					<element ref="gml:members" minOccurs="0"/>
-				</sequence>
-			</extension>
-		</complexContent>
-	</complexType>
-	<element name="Array" type="gml:ArrayType" substitutionGroup="gml:AbstractGML">
-		<annotation>
-			<appinfo>deprecated</appinfo>
-		</annotation>
-	</element>
-	<complexType name="ArrayType">
-		<annotation>
-			<appinfo>deprecated</appinfo>
-		</annotation>
-		<complexContent>
-			<extension base="gml:AbstractGMLType">
-				<sequence>
-					<element ref="gml:members" minOccurs="0"/>
-				</sequence>
-			</extension>
-		</complexContent>
-	</complexType>
 	<complexType name="AbstractMetadataPropertyType" abstract="true">
 		<annotation>
 			<documentation>To associate metadata described by any XML Schema with a GML object, a property element shall be defined whose content model is derived by extension from gml:AbstractMetadataPropertyType. 
@@ -260,46 +178,8 @@ If metadata following the conceptual model of ISO 19115 is to be encoded in a GM
 		<sequence/>
 		<attributeGroup ref="gml:OwnershipAttributeGroup"/>
 	</complexType>
-	<complexType name="MetaDataPropertyType">
-		<annotation>
-			<appinfo>deprecated</appinfo>
-		</annotation>
-		<sequence minOccurs="0">
-			<element ref="gml:AbstractMetaData"/>
-		</sequence>
-		<attributeGroup ref="gml:AssociationAttributeGroup"/>
-		<attribute name="about" type="anyURI"/>
-	</complexType>
-	<element name="AbstractMetaData" type="gml:AbstractMetaDataType" abstract="true" substitutionGroup="gml:AbstractObject">
-		<annotation>
-			<appinfo>deprecated</appinfo>
-		</annotation>
-	</element>
-	<complexType name="AbstractMetaDataType" abstract="true" mixed="true">
-		<annotation>
-			<appinfo>deprecated</appinfo>
-		</annotation>
-		<sequence/>
-		<attribute ref="gml:id"/>
-	</complexType>
-	<element name="GenericMetaData" type="gml:GenericMetaDataType" substitutionGroup="gml:AbstractMetaData">
-		<annotation>
-			<appinfo>deprecated</appinfo>
-		</annotation>
-	</element>
-	<complexType name="GenericMetaDataType" mixed="true">
-		<annotation>
-			<appinfo>deprecated</appinfo>
-		</annotation>
-		<complexContent mixed="true">
-			<extension base="gml:AbstractMetaDataType">
-				<sequence>
-					<any processContents="lax" minOccurs="0" maxOccurs="unbounded"/>
-				</sequence>
-			</extension>
-		</complexContent>
-	</complexType>
 	<element name="targetElement" type="string"/>
 	<element name="associationName" type="string"/>
 	<element name="defaultCodeSpace" type="anyURI"/>
+	<element name="gmlProfileSchema" type="anyURI"/>
 </schema>
diff --git a/pycsw/core/schemas/ogc/gml/3.2.1/gml_32_geometries.rdf b/pycsw/core/schemas/ogc/gml/3.2.1/gml_32_geometries.rdf
new file mode 100644
index 0000000..51bf90e
--- /dev/null
+++ b/pycsw/core/schemas/ogc/gml/3.2.1/gml_32_geometries.rdf
@@ -0,0 +1,368 @@
+<?xml version="1.0"?>
+<rdf:RDF
+    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+    xmlns:skos="http://www.w3.org/2004/02/skos/core#"
+    xmlns:owl="http://www.w3.org/2002/07/owl#"
+    xmlns:dc="http://purl.org/dc/elements/1.1/"
+    xmlns:xsd="http://www.w3.org/2001/XMLSchema#"
+    xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#"
+    xmlns:geo="http://www.opengis.net/ont/geosparql#"
+    xmlns:gml="http://www.opengis.net/ont/gml#"
+  xml:base="http://www.opengis.net/ont/gml">
+  <!--
+    GeoSPARQL 1.0 is an OGC Standard.
+    Copyright (c) 2012 Open Geospatial Consortium.
+    To obtain additional rights of use, visit http://www.opengeospatial.org/legal/ .
+    
+    Version: 1.0.1
+  -->
+  <owl:Ontology rdf:about="">
+    <owl:imports rdf:resource="http://www.opengis.net/ont/geosparql"/>
+  </owl:Ontology>
+  <owl:Class rdf:ID="Point">
+    <rdfs:subClassOf>
+      <owl:Class rdf:ID="AbstractGeometricPrimitive"/>
+    </rdfs:subClassOf>
+    <rdfs:isDefinedBy rdf:resource=""/>
+    <rdfs:label xml:lang="en">Point</rdfs:label>
+  </owl:Class>
+  <owl:Class rdf:ID="AbstractGriddedSurface">
+    <rdfs:subClassOf>
+      <owl:Class rdf:ID="AbstractParametricCurveSurface"/>
+    </rdfs:subClassOf>
+    <rdfs:isDefinedBy rdf:resource=""/>
+    <rdfs:label xml:lang="en">Abstract Gridded Surface</rdfs:label>
+  </owl:Class>
+  <owl:Class rdf:ID="PolyhedralSurface">
+    <rdfs:subClassOf>
+      <owl:Class rdf:ID="Surface"/>
+    </rdfs:subClassOf>
+    <rdfs:isDefinedBy rdf:resource=""/>
+    <rdfs:label xml:lang="en">Polyhedral Surface</rdfs:label>
+  </owl:Class>
+  <owl:Class rdf:ID="Arc">
+    <rdfs:subClassOf>
+      <owl:Class rdf:ID="ArcString"/>
+    </rdfs:subClassOf>
+    <rdfs:isDefinedBy rdf:resource=""/>
+    <rdfs:label xml:lang="en">Arc</rdfs:label>
+  </owl:Class>
+  <owl:Class rdf:ID="PolynomialSpline">
+    <rdfs:subClassOf>
+      <owl:Class rdf:ID="SplineCurve"/>
+    </rdfs:subClassOf>
+    <rdfs:isDefinedBy rdf:resource=""/>
+    <rdfs:label xml:lang="en">Polynomial Spline</rdfs:label>
+  </owl:Class>
+  <owl:Class rdf:ID="MultiCurve">
+    <rdfs:subClassOf>
+      <owl:Class rdf:ID="MultiGeometry"/>
+    </rdfs:subClassOf>
+    <rdfs:isDefinedBy rdf:resource=""/>
+    <rdfs:label xml:lang="en">Multi-Curve</rdfs:label>
+  </owl:Class>
+  <owl:Class rdf:ID="CompositeSurface">
+    <rdfs:subClassOf>
+      <owl:Class rdf:ID="Composite"/>
+    </rdfs:subClassOf>
+    <rdfs:subClassOf>
+      <owl:Class rdf:ID="OrientableSurface"/>
+    </rdfs:subClassOf>
+    <rdfs:isDefinedBy rdf:resource=""/>
+    <rdfs:label xml:lang="en">Composite Surface</rdfs:label>
+  </owl:Class>
+  <owl:Class rdf:about="#ArcString">
+    <rdfs:subClassOf>
+      <owl:Class rdf:ID="AbstractCurveSegment"/>
+    </rdfs:subClassOf>
+    <rdfs:isDefinedBy rdf:resource=""/>
+    <rdfs:label xml:lang="en">Arc String</rdfs:label>
+  </owl:Class>
+  <owl:Class rdf:ID="Cylinder">
+    <rdfs:subClassOf rdf:resource="#AbstractGriddedSurface"/>
+    <rdfs:isDefinedBy rdf:resource=""/>
+    <rdfs:label xml:lang="en">Cylinder</rdfs:label>
+  </owl:Class>
+  <owl:Class rdf:ID="Shell">
+    <rdfs:subClassOf rdf:resource="#CompositeSurface"/>
+    <rdfs:isDefinedBy rdf:resource=""/>
+    <rdfs:label xml:lang="en">Shell</rdfs:label>
+  </owl:Class>
+  <owl:Class rdf:ID="Polygon">
+    <rdfs:subClassOf>
+      <owl:Class rdf:about="#Surface"/>
+    </rdfs:subClassOf>
+    <rdfs:isDefinedBy rdf:resource=""/>
+    <rdfs:label xml:lang="en">Polygon</rdfs:label>
+  </owl:Class>
+  <owl:Class rdf:ID="Tin">
+    <rdfs:subClassOf>
+      <owl:Class rdf:ID="TriangulatedSurface"/>
+    </rdfs:subClassOf>
+    <rdfs:isDefinedBy rdf:resource=""/>
+    <rdfs:label xml:lang="en">Triangulated Irregular Network</rdfs:label>
+  </owl:Class>
+  <owl:Class rdf:about="#MultiGeometry">
+    <rdfs:subClassOf>
+      <owl:Class rdf:ID="AbstractGeometry"/>
+    </rdfs:subClassOf>
+    <rdfs:isDefinedBy rdf:resource=""/>
+    <rdfs:label xml:lang="en">Multi-Geometry</rdfs:label>
+  </owl:Class>
+  <owl:Class rdf:ID="Bezier">
+    <rdfs:subClassOf>
+      <owl:Class rdf:ID="BSpline"/>
+    </rdfs:subClassOf>
+    <rdfs:isDefinedBy rdf:resource=""/>
+    <rdfs:label xml:lang="en">Bezier</rdfs:label>
+  </owl:Class>
+  <owl:Class rdf:ID="Curve">
+    <rdfs:subClassOf>
+      <owl:Class rdf:about="#AbstractGeometricPrimitive"/>
+    </rdfs:subClassOf>
+    <rdfs:subClassOf>
+      <owl:Class rdf:ID="OrientableCurve"/>
+    </rdfs:subClassOf>
+    <rdfs:isDefinedBy rdf:resource=""/>
+    <rdfs:label xml:lang="en">Curve</rdfs:label>
+  </owl:Class>
+  <owl:Class rdf:about="#BSpline">
+    <rdfs:subClassOf>
+      <owl:Class rdf:about="#SplineCurve"/>
+    </rdfs:subClassOf>
+    <rdfs:isDefinedBy rdf:resource=""/>
+    <rdfs:label xml:lang="en">BSpline</rdfs:label>
+  </owl:Class>
+  <owl:Class rdf:ID="LineStringSegment">
+    <rdfs:subClassOf>
+      <owl:Class rdf:about="#AbstractCurveSegment"/>
+    </rdfs:subClassOf>
+    <rdfs:isDefinedBy rdf:resource=""/>
+    <rdfs:label xml:lang="en">Line String Segment</rdfs:label>
+  </owl:Class>
+  <owl:Class rdf:ID="Geodesic">
+    <rdfs:subClassOf>
+      <owl:Class rdf:ID="GeodesicString"/>
+    </rdfs:subClassOf>
+    <rdfs:isDefinedBy rdf:resource=""/>
+    <rdfs:label xml:lang="en">Geodesic</rdfs:label>
+  </owl:Class>
+  <owl:Class rdf:ID="AbstractSurfacePatch">
+    <rdfs:subClassOf>
+      <rdf:Description rdf:about="http://www.opengis.net/ont/geosparql#Geometry">
+        <rdfs:isDefinedBy rdf:resource=""/>
+      </rdf:Description>
+    </rdfs:subClassOf>
+    <rdfs:isDefinedBy rdf:resource=""/>
+    <rdfs:label xml:lang="en">Abstract Surface Patch</rdfs:label>
+  </owl:Class>
+  <owl:Class rdf:ID="GeometricComplex">
+    <rdfs:subClassOf>
+      <owl:Class rdf:about="#AbstractGeometry"/>
+    </rdfs:subClassOf>
+    <rdfs:isDefinedBy rdf:resource=""/>
+    <rdfs:label xml:lang="en">Geometric Complex</rdfs:label>
+  </owl:Class>
+  <owl:Class rdf:ID="ArcByBulge">
+    <rdfs:subClassOf>
+      <owl:Class rdf:ID="ArcStringByBulge"/>
+    </rdfs:subClassOf>
+    <rdfs:isDefinedBy rdf:resource=""/>
+    <rdfs:label xml:lang="en">Arc by Bulge</rdfs:label>
+  </owl:Class>
+  <owl:Class rdf:ID="CircleByCenterPoint">
+    <rdfs:subClassOf>
+      <owl:Class rdf:ID="ArcByCenterPoint"/>
+    </rdfs:subClassOf>
+    <rdfs:isDefinedBy rdf:resource=""/>
+    <rdfs:label xml:lang="en">CircleByCenterPoint</rdfs:label>
+  </owl:Class>
+  <owl:Class rdf:ID="MultiPoint">
+    <rdfs:subClassOf rdf:resource="#MultiGeometry"/>
+    <rdfs:isDefinedBy rdf:resource=""/>
+    <rdfs:label xml:lang="en">Multi-Point</rdfs:label>
+  </owl:Class>
+  <owl:Class rdf:about="#ArcByCenterPoint">
+    <rdfs:subClassOf>
+      <owl:Class rdf:about="#AbstractCurveSegment"/>
+    </rdfs:subClassOf>
+    <rdfs:isDefinedBy rdf:resource=""/>
+    <rdfs:label xml:lang="en">Arc by Center Point</rdfs:label>
+  </owl:Class>
+  <owl:Class rdf:ID="OffsetCurve">
+    <rdfs:subClassOf>
+      <owl:Class rdf:about="#AbstractCurveSegment"/>
+    </rdfs:subClassOf>
+    <rdfs:isDefinedBy rdf:resource=""/>
+    <rdfs:label xml:lang="en">Offset Curve</rdfs:label>
+  </owl:Class>
+  <owl:Class rdf:about="#SplineCurve">
+    <rdfs:subClassOf>
+      <owl:Class rdf:about="#AbstractCurveSegment"/>
+    </rdfs:subClassOf>
+    <rdfs:isDefinedBy rdf:resource=""/>
+    <rdfs:label xml:lang="en">Spline Curve</rdfs:label>
+  </owl:Class>
+  <owl:Class rdf:about="#Composite">
+    <rdfs:subClassOf rdf:resource="#GeometricComplex"/>
+    <rdfs:isDefinedBy rdf:resource=""/>
+    <rdfs:label xml:lang="en">Composite</rdfs:label>
+  </owl:Class>
+  <owl:Class rdf:ID="LineString">
+    <rdfs:subClassOf rdf:resource="#LineStringSegment"/>
+    <rdfs:isDefinedBy rdf:resource=""/>
+    <rdfs:label xml:lang="en">Line String</rdfs:label>
+  </owl:Class>
+  <owl:Class rdf:ID="Circle">
+    <rdfs:subClassOf rdf:resource="#Arc"/>
+    <rdfs:isDefinedBy rdf:resource=""/>
+    <rdfs:label xml:lang="en">Circle</rdfs:label>
+  </owl:Class>
+  <owl:Class rdf:about="#OrientableCurve">
+    <rdfs:subClassOf>
+      <owl:Class rdf:about="#AbstractGeometricPrimitive"/>
+    </rdfs:subClassOf>
+    <rdfs:isDefinedBy rdf:resource=""/>
+    <rdfs:label xml:lang="en">Orientable Curve</rdfs:label>
+  </owl:Class>
+  <owl:Class rdf:about="#OrientableSurface">
+    <rdfs:subClassOf>
+      <owl:Class rdf:about="#AbstractGeometricPrimitive"/>
+    </rdfs:subClassOf>
+    <rdfs:isDefinedBy rdf:resource=""/>
+    <rdfs:label xml:lang="en">Orientable Surface</rdfs:label>
+  </owl:Class>
+  <owl:Class rdf:ID="Clothoid">
+    <rdfs:subClassOf>
+      <owl:Class rdf:about="#AbstractCurveSegment"/>
+    </rdfs:subClassOf>
+    <rdfs:isDefinedBy rdf:resource=""/>
+    <rdfs:label xml:lang="en">Clothoid</rdfs:label>
+  </owl:Class>
+  <owl:Class rdf:about="#ArcStringByBulge">
+    <rdfs:subClassOf>
+      <owl:Class rdf:about="#AbstractCurveSegment"/>
+    </rdfs:subClassOf>
+    <rdfs:isDefinedBy rdf:resource=""/>
+    <rdfs:label xml:lang="en">Arc String by Bulge</rdfs:label>
+  </owl:Class>
+  <owl:Class rdf:about="#TriangulatedSurface">
+    <rdfs:subClassOf rdf:resource="#PolyhedralSurface"/>
+    <rdfs:isDefinedBy rdf:resource=""/>
+    <rdfs:label xml:lang="en">Triangulated Surface</rdfs:label>
+  </owl:Class>
+  <owl:Class rdf:ID="Triangle">
+    <rdfs:subClassOf>
+      <owl:Class rdf:ID="PolygonPatch"/>
+    </rdfs:subClassOf>
+    <rdfs:isDefinedBy rdf:resource=""/>
+    <rdfs:label xml:lang="en">Triangle</rdfs:label>
+  </owl:Class>
+  <owl:Class rdf:ID="CubicSpline">
+    <rdfs:subClassOf rdf:resource="#PolynomialSpline"/>
+    <rdfs:isDefinedBy rdf:resource=""/>
+    <rdfs:label xml:lang="en">Cubic Spline</rdfs:label>
+  </owl:Class>
+  <owl:Class rdf:about="#AbstractGeometry">
+    <rdfs:subClassOf rdf:resource="http://www.opengis.net/ont/geosparql#Geometry"/>
+    <rdfs:isDefinedBy rdf:resource=""/>
+    <rdfs:label xml:lang="en">Abstract Geometry</rdfs:label>
+  </owl:Class>
+  <owl:Class rdf:ID="Cone">
+    <rdfs:subClassOf rdf:resource="#AbstractGriddedSurface"/>
+    <rdfs:isDefinedBy rdf:resource=""/>
+    <rdfs:label xml:lang="en">Cone</rdfs:label>
+  </owl:Class>
+  <owl:Class rdf:ID="CompositeSolid">
+    <rdfs:subClassOf rdf:resource="#Composite"/>
+    <rdfs:subClassOf>
+      <owl:Class rdf:ID="Solid"/>
+    </rdfs:subClassOf>
+    <rdfs:isDefinedBy rdf:resource=""/>
+    <rdfs:label xml:lang="en">Composite Solid</rdfs:label>
+  </owl:Class>
+  <owl:Class rdf:about="#AbstractGeometricPrimitive">
+    <rdfs:subClassOf rdf:resource="#AbstractGeometry"/>
+    <rdfs:isDefinedBy rdf:resource=""/>
+    <rdfs:label xml:lang="en">Abstract Geometric Primitive</rdfs:label>
+  </owl:Class>
+  <owl:Class rdf:ID="LinearRing">
+    <rdfs:subClassOf>
+      <owl:Class rdf:ID="Ring"/>
+    </rdfs:subClassOf>
+    <rdfs:isDefinedBy rdf:resource=""/>
+    <rdfs:label xml:lang="en">Linear Ring</rdfs:label>
+  </owl:Class>
+  <owl:Class rdf:about="#AbstractParametricCurveSurface">
+    <rdfs:subClassOf rdf:resource="#AbstractSurfacePatch"/>
+    <rdfs:isDefinedBy rdf:resource=""/>
+    <rdfs:label xml:lang="en">Abstract Parametric Curve Surface</rdfs:label>
+  </owl:Class>
+  <owl:Class rdf:about="#GeodesicString">
+    <rdfs:subClassOf>
+      <owl:Class rdf:about="#AbstractCurveSegment"/>
+    </rdfs:subClassOf>
+    <rdfs:isDefinedBy rdf:resource=""/>
+    <rdfs:label xml:lang="en">Geodesic String</rdfs:label>
+  </owl:Class>
+  <owl:Class rdf:ID="MultiSolid">
+    <rdfs:subClassOf rdf:resource="#MultiGeometry"/>
+    <rdfs:isDefinedBy rdf:resource=""/>
+    <rdfs:label xml:lang="en">Multi-Solid</rdfs:label>
+  </owl:Class>
+  <owl:Class rdf:about="#Solid">
+    <rdfs:subClassOf rdf:resource="#AbstractGeometricPrimitive"/>
+    <rdfs:isDefinedBy rdf:resource=""/>
+    <rdfs:label xml:lang="en">Solid</rdfs:label>
+  </owl:Class>
+  <owl:Class rdf:ID="CompositeCurve">
+    <rdfs:subClassOf rdf:resource="#Composite"/>
+    <rdfs:subClassOf rdf:resource="#OrientableCurve"/>
+    <rdfs:isDefinedBy rdf:resource=""/>
+    <rdfs:label xml:lang="en">Composite Curve</rdfs:label>
+  </owl:Class>
+  <owl:Class rdf:ID="Rectangle">
+    <rdfs:subClassOf>
+      <owl:Class rdf:about="#PolygonPatch"/>
+    </rdfs:subClassOf>
+    <rdfs:isDefinedBy rdf:resource=""/>
+    <rdfs:label xml:lang="en">Rectangle</rdfs:label>
+  </owl:Class>
+  <owl:Class rdf:ID="Sphere">
+    <rdfs:subClassOf rdf:resource="#AbstractGriddedSurface"/>
+    <rdfs:isDefinedBy rdf:resource=""/>
+    <rdfs:label xml:lang="en">Sphere</rdfs:label>
+  </owl:Class>
+  <owl:Class rdf:about="#Ring">
+    <rdfs:subClassOf rdf:resource="#CompositeCurve"/>
+    <rdfs:isDefinedBy rdf:resource=""/>
+    <rdfs:label xml:lang="en">Ring</rdfs:label>
+  </owl:Class>
+  <owl:Class rdf:about="#PolygonPatch">
+    <rdfs:subClassOf rdf:resource="#AbstractSurfacePatch"/>
+    <rdfs:isDefinedBy rdf:resource=""/>
+    <rdfs:label xml:lang="en">Polygon Patch</rdfs:label>
+  </owl:Class>
+  <owl:Class rdf:ID="MultiSurface">
+    <rdfs:subClassOf rdf:resource="#MultiGeometry"/>
+    <rdfs:isDefinedBy rdf:resource=""/>
+    <rdfs:label xml:lang="en">Multi-Surface</rdfs:label>
+  </owl:Class>
+  <owl:Class rdf:about="#AbstractCurveSegment">
+    <rdfs:subClassOf rdf:resource="http://www.opengis.net/ont/geosparql#Geometry"/>
+    <rdfs:isDefinedBy rdf:resource=""/>
+    <rdfs:label xml:lang="en">Abstract Curve Segment</rdfs:label>
+  </owl:Class>
+  <owl:Class rdf:about="#Surface">
+    <rdfs:subClassOf rdf:resource="#AbstractGeometricPrimitive"/>
+    <rdfs:subClassOf rdf:resource="#OrientableSurface"/>
+    <rdfs:isDefinedBy rdf:resource=""/>
+    <rdfs:label xml:lang="en">Surface</rdfs:label>
+  </owl:Class>
+  <rdf:Description rdf:about="http://www.opengis.net/ont/geosparql#Feature">
+    <rdfs:isDefinedBy rdf:resource=""/>
+  </rdf:Description>
+  <rdf:Description rdf:about="http://www.opengis.net/ont/geosparql#SpatialObject">
+    <rdfs:isDefinedBy rdf:resource=""/>
+  </rdf:Description>
+</rdf:RDF>
diff --git a/pycsw/core/schemas/ogc/gml/3.2.1/gml_3_2_1-ReadMe.txt b/pycsw/core/schemas/ogc/gml/3.2.1/gml_3_2_1-ReadMe.txt
new file mode 100644
index 0000000..a0a6eb2
--- /dev/null
+++ b/pycsw/core/schemas/ogc/gml/3.2.1/gml_3_2_1-ReadMe.txt
@@ -0,0 +1,58 @@
+OpenGIS(r) GML schema version 3.2.1 / ISO 19136 - ReadMe.txt
+
+The schema has been validated with Xerces-J, Xerces C++ and XSV.
+
+-------------------------------------------------------------------
+
+2012-07-21  Kevin Stegemoller
+
+  * v2.0.0 - v3.2.1 WARNING XLink change is NOT BACKWARD COMPATIBLE.
+  * changed OGC XLink (xlink:simpleLink) to W3C XLink (xlink:simpleAttrs)
+  per an approved TC and PC motion during the Dec. 2011 Brussels meeting.
+  see http://www.opengeospatial.org/blog/1597
+  * implement 11-025: retroactively require/add all leaf documents of an
+  XML namespace shall explicitly <include/> the all-components schema
+  * v3.2.1: updated xsd:schema:@version to 3.2.1.2 (06-135r7 s#13.4)
+
+2007-09-06  Kevin Stegemoller
+
+  GML 3.2.1 (ISO 19136)
+  * Published GML 3.2.1 schemas from OGC 07-036
+  * validated with oXygen 8.2 (xerces-J 2.9.0) - Kevin Stegemoller
+  * validated with Xerces-J, Xerces-C++ and XSV - Clemens Portele
+
+2007-08-17  Kevin Stegemoller
+
+  Changes made to these GML 3.2.1 / ISO 19136 schemas:
+  * added ReadMe.txt
+  * changed gmd.xsd references to "../../iso/19139/20070417/gmd/gmd.xsd"
+  * changed xlink references to be relative to /xlink/1.0.0/xlinks.xsd
+    available from schemas.opengis.net/xlink/1.0.0/xlinks.xsd (REMOVED 2012-07-21).
+  * removed xlinks schema and directory
+
+  Changes made to these ISO 19139 schemas by OGC:
+  * added ReadMe.txt
+  * changed ISO_19136 path to /gml/3.2.1/
+  * changed xlink references to be relative to /xlink/1.0.0/xlinks.xsd
+    available from schemas.opengis.net/xlink/1.0.0/xlinks.xsd (REMOVED 2012-07-21).
+  * removed xlinks schema and directory
+
+OGC GML 3.2.1 / ISO 19136 schemas files will be published at:
+- http://schemas.opengis.net/gml/3.2.1/
+- http://standards.iso.org/ittf/PubliclyAvailableStandards/ISO_19136_Schemas/
+
+Files in the folder "ISO/19139/20070417" are also published at
+- http://standards.iso.org/ittf/PubliclyAvailableStandards/ISO_19139_Schemas/
+
+-------------------------------------------------------------------
+
+The Open Geospatial Consortium, Inc. official schema repository is at
+  http://schemas.opengis.net/ .
+Policies, Procedures, Terms, and Conditions of OGC(r) are available
+  http://www.opengeospatial.org/ogc/policies/ .
+Additional rights of use are described at
+  http://www.opengeospatial.org/legal/ . 
+
+Copyright (c) 2007 Open Geospatial Consortium.
+
+-------------------------------------------------------------------
diff --git a/pycsw/core/schemas/ogc/gml/3.2.1/grids.xsd b/pycsw/core/schemas/ogc/gml/3.2.1/grids.xsd
new file mode 100644
index 0000000..7592e0e
--- /dev/null
+++ b/pycsw/core/schemas/ogc/gml/3.2.1/grids.xsd
@@ -0,0 +1,64 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<schema targetNamespace="http://www.opengis.net/gml/3.2" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2001/XMLSchema" xmlns:gml="http://www.opengis.net/gml/3.2" elementFormDefault="qualified" version="3.2.1.2">
+	<annotation>
+		<appinfo source="urn:x-ogc:specification:gml:schema-xsd:grids:3.2.1">grids.xsd</appinfo>
+		<documentation>See ISO/DIS 19136 20.2.
+An implicit description of geometry is one in which the items of the geometry do not explicitly appear in the encoding.  Instead, a compact notation records a set of parameters, and a set of objects may be generated using a rule with these parameters.  This Clause provides grid geometries that are used in the description of gridded coverages and other applications.
+In GML two grid structures are defined, namely gml:Grid and gml:RectifiedGrid.
+
+GML is an OGC Standard.
+Copyright (c) 2007,2010 Open Geospatial Consortium.
+To obtain additional rights of use, visit http://www.opengeospatial.org/legal/ .
+		</documentation>
+	</annotation>
+	<include schemaLocation="gml.xsd"/>
+	<include schemaLocation="geometryBasic0d1d.xsd"/>
+	<element name="Grid" type="gml:GridType" substitutionGroup="gml:AbstractImplicitGeometry">
+		<annotation>
+			<documentation>The gml:Grid implicitly defines an unrectified grid, which is a network composed of two or more sets of curves in which the members of each set intersect the members of the other sets in an algorithmic way.  The region of interest within the grid is given in terms of its gml:limits, being the grid coordinates of  diagonally opposed corners of a rectangular region.  gml:axisLabels is provided with a list of labels of the axes of the grid (gml:axisName has been deprecated [...]
+The gml:limits element contains a single gml:GridEnvelope. The gml:low and gml:high property elements of the envelope are each integerLists, which are coordinate tuples, the coordinates being measured as offsets from the origin of the grid along each axis, of the diagonally opposing corners of a "rectangular" region of interest.</documentation>
+		</annotation>
+	</element>
+	<element name="AbstractImplicitGeometry" type="gml:AbstractGeometryType" abstract="true" substitutionGroup="gml:AbstractGeometry"/>
+	<complexType name="GridType">
+		<complexContent>
+			<extension base="gml:AbstractGeometryType">
+				<sequence>
+					<element name="limits" type="gml:GridLimitsType"/>
+					<choice>
+						<element name="axisLabels" type="gml:NCNameList"/>
+						<element name="axisName" type="string" maxOccurs="unbounded"/>
+					</choice>
+				</sequence>
+				<attribute name="dimension" type="positiveInteger" use="required"/>
+			</extension>
+		</complexContent>
+	</complexType>
+	<complexType name="GridLimitsType">
+		<sequence>
+			<element name="GridEnvelope" type="gml:GridEnvelopeType"/>
+		</sequence>
+	</complexType>
+	<complexType name="GridEnvelopeType">
+		<sequence>
+			<element name="low" type="gml:integerList"/>
+			<element name="high" type="gml:integerList"/>
+		</sequence>
+	</complexType>
+	<element name="RectifiedGrid" type="gml:RectifiedGridType" substitutionGroup="gml:Grid">
+		<annotation>
+			<documentation>A rectified grid is a grid for which there is an affine transformation between the grid coordinates and the coordinates of an external coordinate reference system. It is defined by specifying the position (in some geometric space) of the grid "origin" and of the vectors that specify the post locations.
+Note that the grid limits (post indexes) and axis name properties are inherited from gml:GridType and that gml:RectifiedGrid adds a gml:origin property (contains or references a gml:Point) and a set of gml:offsetVector properties.</documentation>
+		</annotation>
+	</element>
+	<complexType name="RectifiedGridType">
+		<complexContent>
+			<extension base="gml:GridType">
+				<sequence>
+					<element name="origin" type="gml:PointPropertyType"/>
+					<element name="offsetVector" type="gml:VectorType" maxOccurs="unbounded"/>
+				</sequence>
+			</extension>
+		</complexContent>
+	</complexType>
+</schema>
diff --git a/pycsw/core/schemas/ogc/gml/3.2.1/measures.xsd b/pycsw/core/schemas/ogc/gml/3.2.1/measures.xsd
new file mode 100644
index 0000000..c3a91fb
--- /dev/null
+++ b/pycsw/core/schemas/ogc/gml/3.2.1/measures.xsd
@@ -0,0 +1,68 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<schema targetNamespace="http://www.opengis.net/gml/3.2" xmlns:gml="http://www.opengis.net/gml/3.2" xmlns="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified" xml:lang="en" version="3.2.1.2">
+	<annotation>
+		<appinfo source="urn:x-ogc:specification:gml:schema-xsd:measures:3.2.1">measures.xsd</appinfo>
+		<documentation>See ISO/DIS 19136 17.3.
+gml:MeasureType is defined in the basicTypes schema.  The measure types defined here correspond with a set of convenience measure types described in ISO/TS 19103.  The XML implementation is based on the XML Schema simple type "double" which supports both decimal and scientific notation, and includes an XML attribute "uom" which refers to the units of measure for the value.  Note that, there is no requirement to store values using any particular format, and applications receiving elements [...]
+
+GML is an OGC Standard.
+Copyright (c) 2007,2010 Open Geospatial Consortium.
+To obtain additional rights of use, visit http://www.opengeospatial.org/legal/ .
+		</documentation>
+	</annotation>
+	<include schemaLocation="gml.xsd"/>
+	<include schemaLocation="units.xsd"/>
+	<element name="measure" type="gml:MeasureType">
+		<annotation>
+			<documentation>The value of a physical quantity, together with its unit.</documentation>
+		</annotation>
+	</element>
+	<complexType name="LengthType">
+		<annotation>
+			<documentation>This is a prototypical definition for a specific measure type defined as a vacuous extension (i.e. aliases) of gml:MeasureType. In this case, the content model supports the description of a length (or distance) quantity, with its units. The unit of measure referenced by uom shall be suitable for a length, such as metres or feet.</documentation>
+		</annotation>
+		<simpleContent>
+			<extension base="gml:MeasureType"/>
+		</simpleContent>
+	</complexType>
+	<complexType name="ScaleType">
+		<simpleContent>
+			<extension base="gml:MeasureType"/>
+		</simpleContent>
+	</complexType>
+	<complexType name="TimeType">
+		<simpleContent>
+			<extension base="gml:MeasureType"/>
+		</simpleContent>
+	</complexType>
+	<complexType name="GridLengthType">
+		<simpleContent>
+			<extension base="gml:MeasureType"/>
+		</simpleContent>
+	</complexType>
+	<complexType name="AreaType">
+		<simpleContent>
+			<extension base="gml:MeasureType"/>
+		</simpleContent>
+	</complexType>
+	<complexType name="VolumeType">
+		<simpleContent>
+			<extension base="gml:MeasureType"/>
+		</simpleContent>
+	</complexType>
+	<complexType name="SpeedType">
+		<simpleContent>
+			<extension base="gml:MeasureType"/>
+		</simpleContent>
+	</complexType>
+	<complexType name="AngleType">
+		<simpleContent>
+			<extension base="gml:MeasureType"/>
+		</simpleContent>
+	</complexType>
+	<element name="angle" type="gml:AngleType">
+		<annotation>
+			<documentation>The gml:angle property element is used to record the value of an angle quantity as a single number, with its units.</documentation>
+		</annotation>
+	</element>
+</schema>
diff --git a/pycsw/core/schemas/ogc/gml/3.2.1/observation.xsd b/pycsw/core/schemas/ogc/gml/3.2.1/observation.xsd
new file mode 100644
index 0000000..944c989
--- /dev/null
+++ b/pycsw/core/schemas/ogc/gml/3.2.1/observation.xsd
@@ -0,0 +1,95 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<schema targetNamespace="http://www.opengis.net/gml/3.2" xmlns="http://www.w3.org/2001/XMLSchema" xmlns:gml="http://www.opengis.net/gml/3.2" elementFormDefault="qualified" version="3.2.1.2">
+	<annotation>
+		<appinfo source="urn:x-ogc:specification:gml:schema-xsd:observation:3.2.1">observation.xsd</appinfo>
+		<documentation>See ISO/DIS 19136 Clause 19.
+A GML observation models the act of observing, often with a camera, a person or some form of instrument.  An observation feature describes the "metadata" associated with an information capture event, together with a value for the result of the observation.  This covers a broad range of cases, from a tourist photo (not the photo but the act of taking the photo), to images acquired by space borne sensors or the measurement of a temperature 5 meters below the surfaces of a lake.
+The basic structures introduced in this schema are intended to serve as the foundation for more comprehensive schemas for scientific, technical and engineering measurement schemas.
+
+GML is an OGC Standard.
+Copyright (c) 2007,2010 Open Geospatial Consortium.
+To obtain additional rights of use, visit http://www.opengeospatial.org/legal/ .
+		</documentation>
+	</annotation>
+	<include schemaLocation="gml.xsd"/>
+	<include schemaLocation="feature.xsd"/>
+	<include schemaLocation="direction.xsd"/>
+	<include schemaLocation="valueObjects.xsd"/>
+	<element name="Observation" type="gml:ObservationType" substitutionGroup="gml:AbstractFeature">
+		<annotation>
+			<documentation>The content model is a straightforward extension of gml:AbstractFeatureType; it automatically has the gml:identifier, gml:description, gml:descriptionReference, gml:name, and gml:boundedBy properties. 
+The gml:validTime element describes the time of the observation. Note that this may be a time instant or a time period.
+The gml:using property contains or references a description of a sensor, instrument or procedure used for the observation.
+The gml:target property contains or references the specimen, region or station which is the object of the observation. This property is particularly useful for remote observations, such as photographs, where a generic location property might apply to the location of the camera or the location of the field of view, and thus may be ambiguous.  
+The gml:subject element is provided as a convenient synonym for gml:target. This is the term commonly used in phtotography.  
+The gml:resultOf property indicates the result of the observation.  The value may be inline, or a reference to a value elsewhere.
+</documentation>
+		</annotation>
+	</element>
+	<complexType name="ObservationType">
+		<complexContent>
+			<extension base="gml:AbstractFeatureType">
+				<sequence>
+					<element ref="gml:validTime"/>
+					<element ref="gml:using" minOccurs="0"/>
+					<element ref="gml:target" minOccurs="0"/>
+					<element ref="gml:resultOf"/>
+				</sequence>
+			</extension>
+		</complexContent>
+	</complexType>
+	<element name="using" type="gml:ProcedurePropertyType"/>
+	<complexType name="ProcedurePropertyType">
+		<sequence minOccurs="0">
+			<element ref="gml:AbstractFeature"/>
+		</sequence>
+		<attributeGroup ref="gml:OwnershipAttributeGroup"/>
+		<attributeGroup ref="gml:AssociationAttributeGroup"/>
+	</complexType>
+	<element name="target" type="gml:TargetPropertyType"/>
+	<element name="subject" type="gml:TargetPropertyType" substitutionGroup="gml:target"/>
+	<complexType name="TargetPropertyType">
+		<choice minOccurs="0">
+			<element ref="gml:AbstractFeature"/>
+			<element ref="gml:AbstractGeometry"/>
+		</choice>
+		<attributeGroup ref="gml:OwnershipAttributeGroup"/>
+		<attributeGroup ref="gml:AssociationAttributeGroup"/>
+	</complexType>
+	<element name="resultOf" type="gml:ResultType"/>
+	<complexType name="ResultType">
+		<sequence minOccurs="0">
+			<any namespace="##any"/>
+		</sequence>
+		<attributeGroup ref="gml:OwnershipAttributeGroup"/>
+		<attributeGroup ref="gml:AssociationAttributeGroup"/>
+	</complexType>
+	<element name="DirectedObservation" type="gml:DirectedObservationType" substitutionGroup="gml:Observation">
+		<annotation>
+			<documentation>A gml:DirectedObservation is the same as an observation except that it adds an additional gml:direction property. This is the direction in which the observation was acquired. Clearly this applies only to certain types of observations such as visual observations by people, or observations obtained from terrestrial cameras.</documentation>
+		</annotation>
+	</element>
+	<complexType name="DirectedObservationType">
+		<complexContent>
+			<extension base="gml:ObservationType">
+				<sequence>
+					<element ref="gml:direction"/>
+				</sequence>
+			</extension>
+		</complexContent>
+	</complexType>
+	<element name="DirectedObservationAtDistance" type="gml:DirectedObservationAtDistanceType" substitutionGroup="gml:DirectedObservation">
+		<annotation>
+			<documentation>gml:DirectedObservationAtDistance adds an additional distance property. This is the distance from the observer to the subject of the observation. Clearly this applies only to certain types of observations such as visual observations by people, or observations obtained from terrestrial cameras.</documentation>
+		</annotation>
+	</element>
+	<complexType name="DirectedObservationAtDistanceType">
+		<complexContent>
+			<extension base="gml:DirectedObservationType">
+				<sequence>
+					<element name="distance" type="gml:MeasureType"/>
+				</sequence>
+			</extension>
+		</complexContent>
+	</complexType>
+</schema>
diff --git a/pycsw/core/schemas/ogc/gml/3.2.1/referenceSystems.xsd b/pycsw/core/schemas/ogc/gml/3.2.1/referenceSystems.xsd
new file mode 100644
index 0000000..a193b18
--- /dev/null
+++ b/pycsw/core/schemas/ogc/gml/3.2.1/referenceSystems.xsd
@@ -0,0 +1,70 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<schema targetNamespace="http://www.opengis.net/gml/3.2" elementFormDefault="qualified" xml:lang="en" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml/3.2" xmlns="http://www.w3.org/2001/XMLSchema" version="3.2.1.2">
+	<annotation>
+		<appinfo source="urn:x-ogc:specification:gml:schema-xsd:referenceSystems:3.2.1">referenceSystems.xsd</appinfo>
+		<documentation>See ISO/DIS 19136 13.2.
+The reference systems schema components have two logical parts, which define elements and types for XML encoding of the definitions of:
+-	Identified Object, inherited by the ten types of GML objects used for coordinate reference systems and coordinate operations
+-	High-level part of the definitions of coordinate reference systems
+This schema encodes the Identified Object and Reference System packages of the UML Model for ISO 19111.
+
+GML is an OGC Standard.
+Copyright (c) 2007,2010 Open Geospatial Consortium.
+To obtain additional rights of use, visit http://www.opengeospatial.org/legal/ .
+		</documentation>
+	</annotation>
+	<include schemaLocation="gml.xsd"/>
+	<include schemaLocation="dictionary.xsd"/>
+	<import namespace="http://www.isotc211.org/2005/gmd" schemaLocation="../../../../../plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gmd/gmd.xsd"/>
+	<complexType name="IdentifiedObjectType" abstract="true">
+		<annotation>
+			<documentation>gml:IdentifiedObjectType provides identification properties of a CRS-related object. In gml:DefinitionType, the gml:identifier element shall be the primary name by which this object is identified, encoding the "name" attribute in the UML model.
+Zero or more of the gml:name elements can be an unordered set of "identifiers", encoding the "identifier" attribute in the UML model. Each of these gml:name elements can reference elsewhere the object's defining information or be an identifier by which this object can be referenced.
+Zero or more other gml:name elements can be an unordered set of "alias" alternative names by which this CRS related object is identified, encoding the "alias" attributes in the UML model. An object may have several aliases, typically used in different contexts. The context for an alias is indicated by the value of its (optional) codeSpace attribute.
+Any needed version information shall be included in the codeSpace attribute of a gml:identifier and gml:name elements. In this use, the gml:remarks element in the gml:DefinitionType shall contain comments on or information about this object, including data source information.</documentation>
+		</annotation>
+		<complexContent>
+			<extension base="gml:DefinitionType"/>
+		</complexContent>
+	</complexType>
+	<element name="AbstractCRS" type="gml:AbstractCRSType" abstract="true" substitutionGroup="gml:Definition">
+		<annotation>
+			<documentation>gml:AbstractCRS specifies a coordinate reference system which is usually single but may be compound. This abstract complex type shall not be used, extended, or restricted, in a GML Application Schema, to define a concrete subtype with a meaning equivalent to a concrete subtype specified in this document.</documentation>
+		</annotation>
+	</element>
+	<complexType name="AbstractCRSType" abstract="true">
+		<complexContent>
+			<extension base="gml:IdentifiedObjectType">
+				<sequence>
+					<element ref="gml:domainOfValidity" minOccurs="0" maxOccurs="unbounded"/>
+					<element ref="gml:scope" maxOccurs="unbounded"/>
+				</sequence>
+			</extension>
+		</complexContent>
+	</complexType>
+	<element name="domainOfValidity">
+		<annotation>
+			<documentation>The gml:domainOfValidity property implements an association role to an EX_Extent object as encoded in ISO/TS 19139, either referencing or containing the definition of that extent.</documentation>
+		</annotation>
+		<complexType>
+			<sequence minOccurs="0">
+				<element ref="gmd:EX_Extent"/>
+			</sequence>
+			<attributeGroup ref="gml:AssociationAttributeGroup"/>
+		</complexType>
+	</element>
+	<element name="scope" type="string">
+		<annotation>
+			<documentation>The gml:scope property provides a description of the usage, or limitations of usage, for which this CRS-related object is valid. If unknown, enter "not known".</documentation>
+		</annotation>
+	</element>
+	<complexType name="CRSPropertyType">
+		<annotation>
+			<documentation>gml:CRSPropertyType is a property type for association roles to a CRS abstract coordinate reference system, either referencing or containing the definition of that CRS.</documentation>
+		</annotation>
+		<sequence minOccurs="0">
+			<element ref="gml:AbstractCRS"/>
+		</sequence>
+		<attributeGroup ref="gml:AssociationAttributeGroup"/>
+	</complexType>
+</schema>
diff --git a/pycsw/core/schemas/ogc/gml/3.2.1/temporal.xsd b/pycsw/core/schemas/ogc/gml/3.2.1/temporal.xsd
new file mode 100644
index 0000000..11c4ae3
--- /dev/null
+++ b/pycsw/core/schemas/ogc/gml/3.2.1/temporal.xsd
@@ -0,0 +1,269 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<schema targetNamespace="http://www.opengis.net/gml/3.2" xmlns="http://www.w3.org/2001/XMLSchema" xmlns:gml="http://www.opengis.net/gml/3.2" elementFormDefault="qualified" version="3.2.1.2">
+	<annotation>
+		<appinfo source="urn:x-ogc:specification:gml:schema-xsd:temporal:3.2.1">temporal.xsd</appinfo>
+		<documentation>See ISO/DIS 19136 15.2.
+The GML temporal schemas include components for describing temporal geometry and topology, temporal reference systems, and the temporal characteristics of geographic data. The model underlying the representation constitutes a profile of the conceptual schema described in ISO 19108. The underlying spatiotemporal model strives to accommodate both feature-level and attribute-level time stamping; basic support for tracking moving objects is also included. 
+Time is measured on two types of scales: interval and ordinal.  An interval scale offers a basis for measuring duration, an ordinal scale provides information only about relative position in time.
+Two other ISO standards are relevant to describing temporal objects:  ISO 8601 describes encodings for time instants and time periods, as text strings with particular structure and punctuation; ISO 11404 provides a detailed description of time intervals as part of a general discussion of language independent datatypes.  
+The temporal schemas cover two interrelated topics and provide basic schema components for representing temporal instants and periods, temporal topology, and reference systems; more specialized schema components defines components used for dynamic features. Instances of temporal geometric types are used as values for the temporal properties of geographic features.
+
+GML is an OGC Standard.
+Copyright (c) 2007,2010 Open Geospatial Consortium.
+To obtain additional rights of use, visit http://www.opengeospatial.org/legal/ .
+		</documentation>
+	</annotation>
+	<include schemaLocation="gml.xsd"/>
+	<include schemaLocation="gmlBase.xsd"/>
+	<element name="AbstractTimeObject" type="gml:AbstractTimeObjectType" abstract="true" substitutionGroup="gml:AbstractGML">
+		<annotation>
+			<documentation>gml:AbstractTimeObject acts as the head of a substitution group for all temporal primitives and complexes.</documentation>
+		</annotation>
+	</element>
+	<complexType name="AbstractTimeObjectType" abstract="true">
+		<complexContent>
+			<extension base="gml:AbstractGMLType"/>
+		</complexContent>
+	</complexType>
+	<element name="AbstractTimePrimitive" type="gml:AbstractTimePrimitiveType" abstract="true" substitutionGroup="gml:AbstractTimeObject">
+		<annotation>
+			<documentation>gml:AbstractTimePrimitive acts as the head of a substitution group for geometric and topological temporal primitives.</documentation>
+		</annotation>
+	</element>
+	<complexType name="AbstractTimePrimitiveType" abstract="true">
+		<complexContent>
+			<extension base="gml:AbstractTimeObjectType">
+				<sequence>
+					<element name="relatedTime" type="gml:RelatedTimeType" minOccurs="0" maxOccurs="unbounded"/>
+				</sequence>
+			</extension>
+		</complexContent>
+	</complexType>
+	<complexType name="TimePrimitivePropertyType">
+		<annotation>
+			<documentation>gml:TimePrimitivePropertyType provides a standard content model for associations between an arbitrary member of the substitution group whose head is gml:AbstractTimePrimitive and another object.</documentation>
+		</annotation>
+		<sequence minOccurs="0">
+			<element ref="gml:AbstractTimePrimitive"/>
+		</sequence>
+		<attributeGroup ref="gml:AssociationAttributeGroup"/>
+		<attributeGroup ref="gml:OwnershipAttributeGroup"/>
+	</complexType>
+	<element name="validTime" type="gml:TimePrimitivePropertyType">
+		<annotation>
+			<documentation>gml:validTime is a convenience property element.</documentation>
+		</annotation>
+	</element>
+	<complexType name="RelatedTimeType">
+		<annotation>
+			<documentation>gml:RelatedTimeType provides a content model for indicating the relative position of an arbitrary member of the substitution group whose head is gml:AbstractTimePrimitive. It extends the generic gml:TimePrimitivePropertyType with an XML attribute relativePosition, whose value is selected from the set of 13 temporal relationships identified by Allen (1983)</documentation>
+		</annotation>
+		<complexContent>
+			<extension base="gml:TimePrimitivePropertyType">
+				<attribute name="relativePosition">
+					<simpleType>
+						<restriction base="string">
+							<enumeration value="Before"/>
+							<enumeration value="After"/>
+							<enumeration value="Begins"/>
+							<enumeration value="Ends"/>
+							<enumeration value="During"/>
+							<enumeration value="Equals"/>
+							<enumeration value="Contains"/>
+							<enumeration value="Overlaps"/>
+							<enumeration value="Meets"/>
+							<enumeration value="OverlappedBy"/>
+							<enumeration value="MetBy"/>
+							<enumeration value="BegunBy"/>
+							<enumeration value="EndedBy"/>
+						</restriction>
+					</simpleType>
+				</attribute>
+			</extension>
+		</complexContent>
+	</complexType>
+	<element name="AbstractTimeComplex" type="gml:AbstractTimeComplexType" abstract="true" substitutionGroup="gml:AbstractTimeObject">
+		<annotation>
+			<documentation>gml:AbstractTimeComplex is an aggregation of temporal primitives and acts as the head of a substitution group for temporal complexes.</documentation>
+		</annotation>
+	</element>
+	<complexType name="AbstractTimeComplexType" abstract="true">
+		<complexContent>
+			<extension base="gml:AbstractTimeObjectType"/>
+		</complexContent>
+	</complexType>
+	<element name="AbstractTimeGeometricPrimitive" type="gml:AbstractTimeGeometricPrimitiveType" abstract="true" substitutionGroup="gml:AbstractTimePrimitive">
+		<annotation>
+			<documentation>gml:TimeGeometricPrimitive acts as the head of a substitution group for geometric temporal primitives.
+A temporal geometry shall be associated with a temporal reference system through the frame attribute that provides a URI reference that identifies a description of the reference system. Following ISO 19108, the Gregorian calendar with UTC is the default reference system, but others may also be used. The GPS calendar is an alternative reference systems in common use.
+The two geometric primitives in the temporal dimension are the instant and the period. GML components are defined to support these as follows.</documentation>
+		</annotation>
+	</element>
+	<complexType name="AbstractTimeGeometricPrimitiveType" abstract="true">
+		<complexContent>
+			<extension base="gml:AbstractTimePrimitiveType">
+				<attribute name="frame" type="anyURI" default="#ISO-8601"/>
+			</extension>
+		</complexContent>
+	</complexType>
+	<element name="TimeInstant" type="gml:TimeInstantType" substitutionGroup="gml:AbstractTimeGeometricPrimitive">
+		<annotation>
+			<documentation>gml:TimeInstant acts as a zero-dimensional geometric primitive that represents an identifiable position in time.</documentation>
+		</annotation>
+	</element>
+	<complexType name="TimeInstantType" final="#all">
+		<complexContent>
+			<extension base="gml:AbstractTimeGeometricPrimitiveType">
+				<sequence>
+					<element ref="gml:timePosition"/>
+				</sequence>
+			</extension>
+		</complexContent>
+	</complexType>
+	<complexType name="TimeInstantPropertyType">
+		<annotation>
+			<documentation>gml:TimeInstantPropertyType provides for associating a gml:TimeInstant with an object.</documentation>
+		</annotation>
+		<sequence minOccurs="0">
+			<element ref="gml:TimeInstant"/>
+		</sequence>
+		<attributeGroup ref="gml:AssociationAttributeGroup"/>
+		<attributeGroup ref="gml:OwnershipAttributeGroup"/>
+	</complexType>
+	<element name="TimePeriod" type="gml:TimePeriodType" substitutionGroup="gml:AbstractTimeGeometricPrimitive">
+		<annotation>
+			<documentation>gml:TimePeriod acts as a one-dimensional geometric primitive that represents an identifiable extent in time.
+The location in of a gml:TimePeriod is described by the temporal positions of the instants at which it begins and ends. The length of the period is equal to the temporal distance between the two bounding temporal positions. 
+Both beginning and end may be described in terms of their direct position using gml:TimePositionType which is an XML Schema simple content type, or by reference to an indentifiable time instant using gml:TimeInstantPropertyType.
+Alternatively a limit of a gml:TimePeriod may use the conventional GML property model to make a reference to a time instant described elsewhere, or a limit may be indicated as a direct position.</documentation>
+		</annotation>
+	</element>
+	<complexType name="TimePeriodType">
+		<complexContent>
+			<extension base="gml:AbstractTimeGeometricPrimitiveType">
+				<sequence>
+					<choice>
+						<element name="beginPosition" type="gml:TimePositionType"/>
+						<element name="begin" type="gml:TimeInstantPropertyType"/>
+					</choice>
+					<choice>
+						<element name="endPosition" type="gml:TimePositionType"/>
+						<element name="end" type="gml:TimeInstantPropertyType"/>
+					</choice>
+					<group ref="gml:timeLength" minOccurs="0"/>
+				</sequence>
+			</extension>
+		</complexContent>
+	</complexType>
+	<complexType name="TimePeriodPropertyType">
+		<annotation>
+			<documentation>gml:TimePeriodPropertyType provides for associating a gml:TimePeriod with an object.</documentation>
+		</annotation>
+		<sequence minOccurs="0">
+			<element ref="gml:TimePeriod"/>
+		</sequence>
+		<attributeGroup ref="gml:AssociationAttributeGroup"/>
+		<attributeGroup ref="gml:OwnershipAttributeGroup"/>
+	</complexType>
+	<complexType name="TimePositionType" final="#all">
+		<annotation>
+			<documentation>The method for identifying a temporal position is specific to each temporal reference system.  gml:TimePositionType supports the description of temporal position according to the subtypes described in ISO 19108.
+Values based on calendars and clocks use lexical formats that are based on ISO 8601, as described in XML Schema Part 2:2001. A decimal value may be used with coordinate systems such as GPS time or UNIX time. A URI may be used to provide a reference to some era in an ordinal reference system . 
+In common with many of the components modelled as data types in the ISO 19100 series of International Standards, the corresponding GML component has simple content. However, the content model gml:TimePositionType is defined in several steps.
+Three XML attributes appear on gml:TimePositionType:
+A time value shall be associated with a temporal reference system through the frame attribute that provides a URI reference that identifies a description of the reference system. Following ISO 19108, the Gregorian calendar with UTC is the default reference system, but others may also be used. Components for describing temporal reference systems are described in 14.4, but it is not required that the reference system be described in this, as the reference may refer to anything that may be  [...]
+For time values using a calendar containing more than one era, the (optional) calendarEraName attribute provides the name of the calendar era.  
+Inexact temporal positions may be expressed using the optional indeterminatePosition attribute.  This takes a value from an enumeration.</documentation>
+		</annotation>
+		<simpleContent>
+			<extension base="gml:TimePositionUnion">
+				<attribute name="frame" type="anyURI" default="#ISO-8601"/>
+				<attribute name="calendarEraName" type="string"/>
+				<attribute name="indeterminatePosition" type="gml:TimeIndeterminateValueType"/>
+			</extension>
+		</simpleContent>
+	</complexType>
+	<simpleType name="TimeIndeterminateValueType">
+		<annotation>
+			<documentation>These values are interpreted as follows: 
+-	"unknown" indicates that no specific value for temporal position is provided.
+-	"now" indicates that the specified value shall be replaced with the current temporal position whenever the value is accessed.
+-	"before" indicates that the actual temporal position is unknown, but it is known to be before the specified value.
+-	"after" indicates that the actual temporal position is unknown, but it is known to be after the specified value.
+A value for indeterminatePosition may 
+-	be used either alone, or 
+-	qualify a specific value for temporal position.</documentation>
+		</annotation>
+		<restriction base="string">
+			<enumeration value="after"/>
+			<enumeration value="before"/>
+			<enumeration value="now"/>
+			<enumeration value="unknown"/>
+		</restriction>
+	</simpleType>
+	<simpleType name="TimePositionUnion">
+		<annotation>
+			<documentation>The simple type gml:TimePositionUnion is a union of XML Schema simple types which instantiate the subtypes for temporal position described in ISO 19108.
+ An ordinal era may be referenced via URI.  A decimal value may be used to indicate the distance from the scale origin .  time is used for a position that recurs daily (see ISO 19108:2002 5.4.4.2).
+ Finally, calendar and clock forms that support the representation of time in systems based on years, months, days, hours, minutes and seconds, in a notation following ISO 8601, are assembled by gml:CalDate</documentation>
+		</annotation>
+		<union memberTypes="gml:CalDate time dateTime anyURI decimal"/>
+	</simpleType>
+	<simpleType name="CalDate">
+		<union memberTypes="date gYearMonth gYear"/>
+	</simpleType>
+	<element name="timePosition" type="gml:TimePositionType">
+		<annotation>
+			<documentation>This element is used directly as a property of gml:TimeInstant (see 15.2.2.3), and may also be used in application schemas.</documentation>
+		</annotation>
+	</element>
+	<group name="timeLength">
+		<annotation>
+			<documentation>The length of a time period.</documentation>
+		</annotation>
+		<choice>
+			<element ref="gml:duration"/>
+			<element ref="gml:timeInterval"/>
+		</choice>
+	</group>
+	<element name="duration" type="duration">
+		<annotation>
+			<documentation>gml:duration conforms to the ISO 8601 syntax for temporal length as implemented by the XML Schema duration type.</documentation>
+		</annotation>
+	</element>
+	<element name="timeInterval" type="gml:TimeIntervalLengthType">
+		<annotation>
+			<documentation> gml:timeInterval conforms to ISO 11404 which is based on floating point values for temporal length.
+ISO 11404 syntax specifies the use of a positiveInteger together with appropriate values for radix and factor. The resolution of the time interval is to one radix ^(-factor) of the specified time unit.
+The value of the unit is either selected from the units for time intervals from ISO 31-1:1992, or is another suitable unit.  The encoding is defined for GML in gml:TimeUnitType. The second component of this union type provides a method for indicating time units other than the six standard units given in the enumeration.</documentation>
+		</annotation>
+	</element>
+	<complexType name="TimeIntervalLengthType" final="#all">
+		<simpleContent>
+			<extension base="decimal">
+				<attribute name="unit" type="gml:TimeUnitType" use="required"/>
+				<attribute name="radix" type="positiveInteger"/>
+				<attribute name="factor" type="integer"/>
+			</extension>
+		</simpleContent>
+	</complexType>
+	<simpleType name="TimeUnitType">
+		<union>
+			<simpleType>
+				<restriction base="string">
+					<enumeration value="year"/>
+					<enumeration value="month"/>
+					<enumeration value="day"/>
+					<enumeration value="hour"/>
+					<enumeration value="minute"/>
+					<enumeration value="second"/>
+				</restriction>
+			</simpleType>
+			<simpleType>
+				<restriction base="string">
+					<pattern value="other:\w{2,}"/>
+				</restriction>
+			</simpleType>
+		</union>
+	</simpleType>
+</schema>
diff --git a/pycsw/core/schemas/ogc/gml/3.2.1/temporalReferenceSystems.xsd b/pycsw/core/schemas/ogc/gml/3.2.1/temporalReferenceSystems.xsd
new file mode 100644
index 0000000..88f610b
--- /dev/null
+++ b/pycsw/core/schemas/ogc/gml/3.2.1/temporalReferenceSystems.xsd
@@ -0,0 +1,189 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<schema targetNamespace="http://www.opengis.net/gml/3.2" xmlns:gml="http://www.opengis.net/gml/3.2" xmlns="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" version="3.2.1.2">
+	<annotation>
+		<appinfo source="urn:x-ogc:specification:gml:schema-xsd:temporalReferenceSystems:3.2.1">temporalReferenceSystems.xsd</appinfo>
+		<documentation>See ISO/DIS 19136 15.5.
+A value in the time domain is measured relative to a temporal reference system. Common types of reference systems include calendars, ordinal temporal reference systems, and temporal coordinate systems (time elapsed since some epoch).  The primary temporal reference system for use with geographic information is the Gregorian Calendar and 24 hour local or Coordinated Universal Time (UTC), but special applications may entail the use of alternative reference systems.  The Julian day numberin [...]
+In GML seven concrete elements are used to describe temporal reference systems: gml:TimeReferenceSystem, gml:TimeCoordinateSystem, gml:TimeCalendar, gml:TimeCalendarEra, gml:TimeClock, gml:TimeOrdinalReferenceSystem, and gml:TimeOrdinalEra.
+
+GML is an OGC Standard.
+Copyright (c) 2007,2010 Open Geospatial Consortium.
+To obtain additional rights of use, visit http://www.opengeospatial.org/legal/ .
+		</documentation>
+	</annotation>
+	<include schemaLocation="gml.xsd"/>
+	<include schemaLocation="temporalTopology.xsd"/>
+	<include schemaLocation="dictionary.xsd"/>
+	<element name="TimeReferenceSystem" type="gml:TimeReferenceSystemType" substitutionGroup="gml:Definition">
+		<annotation>
+			<documentation>A reference system is characterized in terms of its domain of validity: the spatial and temporal extent over which it is applicable. The basic GML element for temporal reference systems is gml:TimeReferenceSystem.  Its content model extends gml:DefinitionType with one additional property, gml:domainOfValidity.</documentation>
+		</annotation>
+	</element>
+	<complexType name="TimeReferenceSystemType">
+		<complexContent>
+			<extension base="gml:DefinitionType">
+				<sequence>
+					<element name="domainOfValidity" type="string"/>
+				</sequence>
+			</extension>
+		</complexContent>
+	</complexType>
+	<element name="TimeCoordinateSystem" type="gml:TimeCoordinateSystemType" substitutionGroup="gml:TimeReferenceSystem">
+		<annotation>
+			<documentation>A temporal coordinate system shall be based on a continuous interval scale defined in terms of a single time interval.
+The differences to ISO 19108 TM_CoordinateSystem are:
+-	the origin is specified either using the property gml:originPosition whose value is a direct time position, or using the property gml:origin whose model is gml:TimeInstantPropertyType; this permits more flexibility in representation and also supports referring to a value fixed elsewhere;
+-	the interval uses gml:TimeIntervalLengthType.
+</documentation>
+		</annotation>
+	</element>
+	<complexType name="TimeCoordinateSystemType">
+		<complexContent>
+			<extension base="gml:TimeReferenceSystemType">
+				<sequence>
+					<choice>
+						<element name="originPosition" type="gml:TimePositionType"/>
+						<element name="origin" type="gml:TimeInstantPropertyType"/>
+					</choice>
+					<element name="interval" type="gml:TimeIntervalLengthType"/>
+				</sequence>
+			</extension>
+		</complexContent>
+	</complexType>
+	<element name="TimeCalendar" type="gml:TimeCalendarType" substitutionGroup="gml:TimeReferenceSystem">
+		<annotation>
+			<documentation>A calendar is a discrete temporal reference system that provides a basis for defining temporal position to a resolution of one day.
+gml:TimeCalendar adds one property to those inherited from gml:TimeReferenceSystem. A gml:referenceFrame provides a link to a gml:TimeCalendarEra that it uses. A  gml:TimeCalendar may reference more than one calendar era. 
+The referenceFrame element follows the standard GML property model, allowing the association to be instantiated either using an inline description using the gml:TimeCalendarEra element, or a link to a gml:TimeCalendarEra which is explicit elsewhere.</documentation>
+		</annotation>
+	</element>
+	<complexType name="TimeCalendarType">
+		<complexContent>
+			<extension base="gml:TimeReferenceSystemType">
+				<sequence>
+					<element name="referenceFrame" type="gml:TimeCalendarEraPropertyType" maxOccurs="unbounded"/>
+				</sequence>
+			</extension>
+		</complexContent>
+	</complexType>
+	<element name="TimeCalendarEra" type="gml:TimeCalendarEraType">
+		<annotation>
+			<documentation>gml:TimeCalendarEra inherits basic properties from gml:DefinitionType and has the following additional properties:
+-	gml:referenceEvent is the name or description of a mythical or historic event which fixes the position of the base scale of the calendar era.  This is given as text or using a link to description held elsewhere.
+-	gml:referenceDate specifies the date of the referenceEvent expressed as a date in the given calendar.  In most calendars, this date is the origin (i.e., the first day) of the scale, but this is not always true.
+-	gml:julianReference specifies the Julian date that corresponds to the reference date.  The Julian day number is an integer value; the Julian date is a decimal value that allows greater resolution.  Transforming calendar dates to and from Julian dates provides a relatively simple basis for transforming dates from one calendar to another.
+-	gml:epochOfUse is the period for which the calendar era was used as a basis for dating.</documentation>
+		</annotation>
+	</element>
+	<complexType name="TimeCalendarEraType">
+		<complexContent>
+			<extension base="gml:DefinitionType">
+				<sequence>
+					<element name="referenceEvent" type="gml:StringOrRefType"/>
+					<element name="referenceDate" type="gml:CalDate"/>
+					<element name="julianReference" type="decimal"/>
+					<element name="epochOfUse" type="gml:TimePeriodPropertyType"/>
+				</sequence>
+			</extension>
+		</complexContent>
+	</complexType>
+	<complexType name="TimeCalendarPropertyType">
+		<annotation>
+			<documentation>gml:TimeCalendarPropertyType provides for associating a gml:TimeCalendar with an object.</documentation>
+		</annotation>
+		<sequence minOccurs="0">
+			<element ref="gml:TimeCalendar"/>
+		</sequence>
+		<attributeGroup ref="gml:OwnershipAttributeGroup"/>
+		<attributeGroup ref="gml:AssociationAttributeGroup"/>
+	</complexType>
+	<complexType name="TimeCalendarEraPropertyType">
+		<annotation>
+			<documentation>gml:TimeCalendarEraPropertyType provides for associating a gml:TimeCalendarEra with an object.</documentation>
+		</annotation>
+		<sequence minOccurs="0">
+			<element ref="gml:TimeCalendarEra"/>
+		</sequence>
+		<attributeGroup ref="gml:OwnershipAttributeGroup"/>
+		<attributeGroup ref="gml:AssociationAttributeGroup"/>
+	</complexType>
+	<element name="TimeClock" type="gml:TimeClockType" substitutionGroup="gml:TimeReferenceSystem">
+		<annotation>
+			<documentation>A clock provides a basis for defining temporal position within a day. A clock shall be used with a calendar in order to provide a complete description of a temporal position within a specific day.
+gml:TimeClock adds the following properties to those inherited from gml:TimeReferenceSystemType:
+-	gml:referenceEvent is the name or description of an event, such as solar noon or sunrise, which fixes the position of the base scale of the clock.
+-	gml:referenceTime specifies the time of day associated with the reference event expressed as a time of day in the given clock. The reference time is usually the origin of the clock scale. 
+-	gml:utcReference specifies the 24 hour local or UTC time that corresponds to the reference time.
+-	gml:dateBasis contains or references the calendars that use this clock.</documentation>
+		</annotation>
+	</element>
+	<complexType name="TimeClockType" final="#all">
+		<complexContent>
+			<extension base="gml:TimeReferenceSystemType">
+				<sequence>
+					<element name="referenceEvent" type="gml:StringOrRefType"/>
+					<element name="referenceTime" type="time"/>
+					<element name="utcReference" type="time"/>
+					<element name="dateBasis" type="gml:TimeCalendarPropertyType" minOccurs="0" maxOccurs="unbounded"/>
+				</sequence>
+			</extension>
+		</complexContent>
+	</complexType>
+	<complexType name="TimeClockPropertyType">
+		<annotation>
+			<documentation>gml:TimeClockPropertyType provides for associating a gml:TimeClock with an object.</documentation>
+		</annotation>
+		<sequence minOccurs="0">
+			<element ref="gml:TimeClock"/>
+		</sequence>
+		<attributeGroup ref="gml:OwnershipAttributeGroup"/>
+		<attributeGroup ref="gml:AssociationAttributeGroup"/>
+	</complexType>
+	<element name="TimeOrdinalReferenceSystem" type="gml:TimeOrdinalReferenceSystemType" substitutionGroup="gml:TimeReferenceSystem">
+		<annotation>
+			<documentation>In some applications of geographic information — such as geology and archaeology — relative position in time is known more precisely than absolute time or duration. The order of events in time can be well established, but the magnitude of the intervals between them cannot be accurately determined; in such cases, the use of an ordinal temporal reference system is appropriate. An ordinal temporal reference system is composed of a sequence of named coterminous eras, which  [...]
+An ordinal temporal reference system whose component eras are not further subdivided is effectively a temporal topological complex constrained to be a linear graph. An ordinal temporal reference system some or all of whose component eras are subdivided is effectively a temporal topological complex with the constraint that parallel branches may only be constructed in pairs where one is a single temporal ordinal era and the other is a sequence of temporal ordinal eras that are called "memb [...]
+The positions of the beginning and end of a given era may calibrate the relative time scale.
+gml:TimeOrdinalReferenceSystem adds one or more gml:component properties to the generic temporal reference system model.</documentation>
+		</annotation>
+	</element>
+	<complexType name="TimeOrdinalReferenceSystemType">
+		<complexContent>
+			<extension base="gml:TimeReferenceSystemType">
+				<sequence>
+					<element name="component" type="gml:TimeOrdinalEraPropertyType" maxOccurs="unbounded"/>
+				</sequence>
+			</extension>
+		</complexContent>
+	</complexType>
+	<element name="TimeOrdinalEra" type="gml:TimeOrdinalEraType">
+		<annotation>
+			<documentation>Its content model follows the pattern of gml:TimeEdge, inheriting standard properties from gml:DefinitionType, and adding gml:start, gml:end and gml:extent properties, a set of gml:member properties which indicate ordered gml:TimeOrdinalEra elements, and a gml:group property which points to the parent era.
+The recursive inclusion of gml:TimeOrdinalEra elements allow the construction of an arbitrary depth hierarchical ordinal reference schema, such that an ordinal era at a given level of the hierarchy includes a sequence of shorter, coterminous ordinal eras.</documentation>
+		</annotation>
+	</element>
+	<complexType name="TimeOrdinalEraType">
+		<complexContent>
+			<extension base="gml:DefinitionType">
+				<sequence>
+					<element name="relatedTime" type="gml:RelatedTimeType" minOccurs="0" maxOccurs="unbounded"/>
+					<element name="start" type="gml:TimeNodePropertyType" minOccurs="0"/>
+					<element name="end" type="gml:TimeNodePropertyType" minOccurs="0"/>
+					<element name="extent" type="gml:TimePeriodPropertyType" minOccurs="0"/>
+					<element name="member" type="gml:TimeOrdinalEraPropertyType" minOccurs="0" maxOccurs="unbounded"/>
+					<element name="group" type="gml:ReferenceType" minOccurs="0"/>
+				</sequence>
+			</extension>
+		</complexContent>
+	</complexType>
+	<complexType name="TimeOrdinalEraPropertyType">
+		<annotation>
+			<documentation>gml:TimeOrdinalEraPropertyType provides for associating a gml:TimeOrdinalEra with an object.</documentation>
+		</annotation>
+		<sequence minOccurs="0">
+			<element ref="gml:TimeOrdinalEra"/>
+		</sequence>
+		<attributeGroup ref="gml:OwnershipAttributeGroup"/>
+		<attributeGroup ref="gml:AssociationAttributeGroup"/>
+	</complexType>
+</schema>
diff --git a/pycsw/core/schemas/ogc/gml/3.2.1/temporalTopology.xsd b/pycsw/core/schemas/ogc/gml/3.2.1/temporalTopology.xsd
new file mode 100644
index 0000000..b38392c
--- /dev/null
+++ b/pycsw/core/schemas/ogc/gml/3.2.1/temporalTopology.xsd
@@ -0,0 +1,119 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<schema targetNamespace="http://www.opengis.net/gml/3.2" xmlns:gml="http://www.opengis.net/gml/3.2" xmlns="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" version="3.2.1.2">
+	<annotation>
+		<appinfo source="urn:x-ogc:specification:gml:schema-xsd:temporalTopology:3.2.1">temporalTopology.xsd</appinfo>
+		<documentation>See ISO/DIS 19136 15.3.
+Temporal topology is described in terms of time complexes, nodes, and edges, and the connectivity between these. Temporal topology does not directly provide information about temporal position. It is used in the case of describing a lineage or a history (e.g. a family tree expressing evolution of species, an ecological cycle, a lineage of lands or buildings, or a history of separation and merger of administrative boundaries). The following Subclauses specifies the temporal topology as te [...]
+
+GML is an OGC Standard.
+Copyright (c) 2007,2010 Open Geospatial Consortium.
+To obtain additional rights of use, visit http://www.opengeospatial.org/legal/ .
+		</documentation>
+	</annotation>
+	<include schemaLocation="gml.xsd"/>
+	<include schemaLocation="temporal.xsd"/>
+	<element name="AbstractTimeTopologyPrimitive" type="gml:AbstractTimeTopologyPrimitiveType" abstract="true" substitutionGroup="gml:AbstractTimePrimitive">
+		<annotation>
+			<documentation>gml:TimeTopologyPrimitive acts as the head of a substitution group for topological temporal primitives.
+Temporal topology primitives shall imply the ordering information between features or feature properties. The temporal connection of features can be examined if they have temporal topology primitives as values of their properties. Usually, an instantaneous feature associates with a time node, and a static feature associates with a time edge.  A feature with both modes associates with the temporal topology primitive: a supertype of time nodes and time edges.
+A topological primitive is always connected to one or more other topological primitives, and is, therefore, always a member of a topological complex. In a GML instance, this will often be indicated by the primitives being described by elements that are descendents of an element describing a complex. However, in order to support the case where a temporal topological primitive is described in another context, the optional complex property is provided, which carries a reference to the paren [...]
+		</annotation>
+	</element>
+	<complexType name="AbstractTimeTopologyPrimitiveType" abstract="true">
+		<complexContent>
+			<extension base="gml:AbstractTimePrimitiveType">
+				<sequence>
+					<element name="complex" type="gml:ReferenceType" minOccurs="0"/>
+				</sequence>
+			</extension>
+		</complexContent>
+	</complexType>
+	<complexType name="TimeTopologyPrimitivePropertyType">
+		<annotation>
+			<documentation>gml:TimeTopologyPrimitivePropertyType provides for associating a gml:AbstractTimeTopologyPrimitive with an object.</documentation>
+		</annotation>
+		<sequence minOccurs="0">
+			<element ref="gml:AbstractTimeTopologyPrimitive"/>
+		</sequence>
+		<attributeGroup ref="gml:AssociationAttributeGroup"/>
+		<attributeGroup ref="gml:OwnershipAttributeGroup"/>
+	</complexType>
+	<element name="TimeTopologyComplex" type="gml:TimeTopologyComplexType" substitutionGroup="gml:AbstractTimeComplex">
+		<annotation>
+			<documentation>A temporal topology complex shall be the connected acyclic directed graph composed of temporal topological primitives, i.e. time nodes and time edges. Because a time edge may not exist without two time nodes on its boundaries, static features have time edges from a temporal topology complex as the values of their temporal properties, regardless of explicit declarations.
+A temporal topology complex expresses a linear or a non-linear graph. A temporal linear graph, composed of a sequence of time edges, provides a lineage described only by "substitution" of feature instances or feature element values. A time node as the start or the end of the graph connects with at least one time edge. A time node other than the start and the end shall connect to at least two time edges: one of starting from the node, and another ending at the node.
+A temporal topological complex is a set of connected temporal topological primitives. The member primtives are indicated, either by reference or by value, using the primitive property.</documentation>
+		</annotation>
+	</element>
+	<complexType name="TimeTopologyComplexType" abstract="true">
+		<complexContent>
+			<extension base="gml:AbstractTimeComplexType">
+				<sequence>
+					<element name="primitive" type="gml:TimeTopologyPrimitivePropertyType" maxOccurs="unbounded"/>
+				</sequence>
+			</extension>
+		</complexContent>
+	</complexType>
+	<complexType name="TimeTopologyComplexPropertyType">
+		<annotation>
+			<documentation>gml:TimeTopologyComplexPropertyType provides for associating a gml:TimeTopologyComplex with an object.</documentation>
+		</annotation>
+		<sequence minOccurs="0">
+			<element ref="gml:TimeTopologyComplex"/>
+		</sequence>
+		<attributeGroup ref="gml:AssociationAttributeGroup"/>
+		<attributeGroup ref="gml:OwnershipAttributeGroup"/>
+	</complexType>
+	<element name="TimeNode" type="gml:TimeNodeType" substitutionGroup="gml:AbstractTimeTopologyPrimitive">
+		<annotation>
+			<documentation>A time node is a zero-dimensional topological primitive that represents an identifiable node in time (it is equivalent to a point in space). A node may act as the termination or initiation of any number of time edges. A time node may be realised as a geometry, its position, whose value is a time instant.</documentation>
+		</annotation>
+	</element>
+	<complexType name="TimeNodeType">
+		<complexContent>
+			<extension base="gml:AbstractTimeTopologyPrimitiveType">
+				<sequence>
+					<element name="previousEdge" type="gml:TimeEdgePropertyType" minOccurs="0" maxOccurs="unbounded"/>
+					<element name="nextEdge" type="gml:TimeEdgePropertyType" minOccurs="0" maxOccurs="unbounded"/>
+					<element name="position" type="gml:TimeInstantPropertyType" minOccurs="0"/>
+				</sequence>
+			</extension>
+		</complexContent>
+	</complexType>
+	<complexType name="TimeNodePropertyType">
+		<annotation>
+			<documentation>gml:TimeNodePropertyType provides for associating a gml:TimeNode with an object</documentation>
+		</annotation>
+		<sequence minOccurs="0">
+			<element ref="gml:TimeNode"/>
+		</sequence>
+		<attributeGroup ref="gml:AssociationAttributeGroup"/>
+		<attributeGroup ref="gml:OwnershipAttributeGroup"/>
+	</complexType>
+	<element name="TimeEdge" type="gml:TimeEdgeType" substitutionGroup="gml:AbstractTimeTopologyPrimitive">
+		<annotation>
+			<documentation>A time edge is a one-dimensional topological primitive. It is an open interval that starts and ends at a node. The edge may be realised as a geometry whose value is a time period.</documentation>
+		</annotation>
+	</element>
+	<complexType name="TimeEdgeType">
+		<complexContent>
+			<extension base="gml:AbstractTimeTopologyPrimitiveType">
+				<sequence>
+					<element name="start" type="gml:TimeNodePropertyType"/>
+					<element name="end" type="gml:TimeNodePropertyType"/>
+					<element name="extent" type="gml:TimePeriodPropertyType" minOccurs="0"/>
+				</sequence>
+			</extension>
+		</complexContent>
+	</complexType>
+	<complexType name="TimeEdgePropertyType">
+		<annotation>
+			<documentation>gml:TimeEdgePropertyType provides for associating a gml:TimeEdge with an object.</documentation>
+		</annotation>
+		<sequence minOccurs="0">
+			<element ref="gml:TimeEdge"/>
+		</sequence>
+		<attributeGroup ref="gml:AssociationAttributeGroup"/>
+		<attributeGroup ref="gml:OwnershipAttributeGroup"/>
+	</complexType>
+</schema>
diff --git a/pycsw/core/schemas/ogc/gml/3.2.1/topology.xsd b/pycsw/core/schemas/ogc/gml/3.2.1/topology.xsd
new file mode 100644
index 0000000..c528e6c
--- /dev/null
+++ b/pycsw/core/schemas/ogc/gml/3.2.1/topology.xsd
@@ -0,0 +1,386 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<schema targetNamespace="http://www.opengis.net/gml/3.2" xmlns:gml="http://www.opengis.net/gml/3.2" xmlns="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" version="3.2.1.2">
+	<annotation>
+		<appinfo source="urn:x-ogc:specification:gml:schema-xsd:topology:3.2.1">topology.xsd</appinfo>
+		<documentation>See ISO/DIS 19136 Clause 14.
+Topology is the branch of mathematics describing the properties of objects which are invariant under continuous deformation. For example, a circle is topologically equivalent to an ellipse because one can be transformed into the other by stretching. In geographic modelling, the foremost use of topology is in accelerating computational geometry. The constructs of topology allow characterisation of the spatial relationships between objects using simple combinatorial or algebraic algorithms [...]
+There are four instantiable classes of primitive topology objects, one for each dimension up to 3D. In addition, topological complexes are supported, too. 
+There is strong symmetry in the (topological boundary and coboundary) relationships between topology primitives of adjacent dimensions. Topology primitives are bounded by directed primitives of one lower dimension. The coboundary of each topology primitive is formed from directed topology primitives of one higher dimension.
+
+GML is an OGC Standard.
+Copyright (c) 2007,2010 Open Geospatial Consortium.
+To obtain additional rights of use, visit http://www.opengeospatial.org/legal/ .
+		</documentation>
+	</annotation>
+  <include schemaLocation="gml.xsd"/>
+  <include schemaLocation="geometryComplexes.xsd"/>
+  <complexType name="AbstractTopologyType" abstract="true">
+    <annotation>
+      <documentation>This abstract type supplies the root or base type for all topological elements including primitives and complexes. It inherits AbstractGMLType and hence can be identified using the gml:id attribute.</documentation>
+    </annotation>
+    <complexContent>
+      <extension base="gml:AbstractGMLType"/>
+    </complexContent>
+  </complexType>
+  <element name="AbstractTopology" type="gml:AbstractTopologyType" abstract="true" substitutionGroup="gml:AbstractGML"/>
+  <complexType name="AbstractTopoPrimitiveType" abstract="true">
+    <complexContent>
+      <extension base="gml:AbstractTopologyType"/>
+    </complexContent>
+  </complexType>
+  <element name="AbstractTopoPrimitive" type="gml:AbstractTopoPrimitiveType" abstract="true" substitutionGroup="gml:AbstractTopology">
+    <annotation>
+      <documentation>gml:AbstractTopoPrimitive acts as the base type for all topological primitives. Topology primitives are the atomic (smallest possible) units of a topology complex. 
+Each topology primitive may contain references to other topology primitives of codimension 2 or more (gml:isolated). Conversely, nodes may have faces as containers and nodes and edges may have solids as containers (gml:container).</documentation>
+    </annotation>
+  </element>
+  <complexType name="NodeOrEdgePropertyType">
+    <choice minOccurs="0">
+      <element ref="gml:Node"/>
+      <element ref="gml:Edge"/>
+    </choice>
+    <attributeGroup ref="gml:AssociationAttributeGroup"/>
+    <attributeGroup ref="gml:OwnershipAttributeGroup"/>
+  </complexType>
+  <complexType name="NodePropertyType">
+    <choice minOccurs="0">
+      <element ref="gml:Node"/>
+    </choice>
+    <attributeGroup ref="gml:AssociationAttributeGroup"/>
+    <attributeGroup ref="gml:OwnershipAttributeGroup"/>
+  </complexType>
+  <complexType name="FaceOrTopoSolidPropertyType">
+    <choice minOccurs="0">
+      <element ref="gml:Face"/>
+      <element ref="gml:TopoSolid"/>
+    </choice>
+    <attributeGroup ref="gml:AssociationAttributeGroup"/>
+    <attributeGroup ref="gml:OwnershipAttributeGroup"/>
+  </complexType>
+  <complexType name="TopoSolidPropertyType">
+    <choice minOccurs="0">
+      <element ref="gml:TopoSolid"/>
+    </choice>
+    <attributeGroup ref="gml:AssociationAttributeGroup"/>
+    <attributeGroup ref="gml:OwnershipAttributeGroup"/>
+  </complexType>
+  <complexType name="NodeType">
+    <complexContent>
+      <extension base="gml:AbstractTopoPrimitiveType">
+        <sequence>
+          <element name="container" type="gml:FaceOrTopoSolidPropertyType" minOccurs="0"/>
+          <element ref="gml:directedEdge" minOccurs="0" maxOccurs="unbounded">
+            <annotation>
+              <documentation>In the case of planar topology, a gml:Node must have a clockwise sequence of gml:directedEdge properties, to ensure a lossless topology representation as defined by Kuijpers, et. al. (see OGC 05-102 Topology IPR).</documentation>
+            </annotation>
+          </element>
+          <element ref="gml:pointProperty" minOccurs="0"/>
+        </sequence>
+        <attributeGroup ref="gml:AggregationAttributeGroup"/>
+      </extension>
+    </complexContent>
+  </complexType>
+  <element name="Node" type="gml:NodeType" substitutionGroup="gml:AbstractTopoPrimitive">
+    <annotation>
+      <documentation>gml:Node represents the 0-dimensional primitive.
+The optional coboundary of a node (gml:directedEdge) is a sequence of directed edges which are incident on this node. Edges emanating from this node appear in the node coboundary with a negative orientation. 
+If provided, the aggregationType attribute shall have the value "sequence".
+A node may optionally be realised by a 0-dimensional geometric primitive (gml:pointProperty).</documentation>
+    </annotation>
+  </element>
+  <element name="directedNode" type="gml:DirectedNodePropertyType">
+    <annotation>
+      <documentation>A gml:directedNode property element describes the boundary of topology edges and is used in the support of topological point features via the gml:TopoPoint expression, see below. The orientation attribute of type gml:SignType expresses the sense in which the included node is used: start ("-") or end ("+") node.</documentation>
+    </annotation>
+  </element>
+  <complexType name="DirectedNodePropertyType">
+    <sequence minOccurs="0">
+      <element ref="gml:Node"/>
+    </sequence>
+    <attribute name="orientation" type="gml:SignType" default="+"/>
+    <attributeGroup ref="gml:AssociationAttributeGroup"/>
+    <attributeGroup ref="gml:OwnershipAttributeGroup"/>
+  </complexType>
+  <complexType name="EdgeType">
+    <complexContent>
+      <extension base="gml:AbstractTopoPrimitiveType">
+        <sequence>
+          <element name="container" type="gml:TopoSolidPropertyType" minOccurs="0"/>
+          <element ref="gml:directedNode" minOccurs="2" maxOccurs="2"/>
+          <element ref="gml:directedFace" minOccurs="0" maxOccurs="unbounded"/>
+          <element ref="gml:curveProperty" minOccurs="0"/>
+        </sequence>
+        <attributeGroup ref="gml:AggregationAttributeGroup"/>
+      </extension>
+    </complexContent>
+  </complexType>
+  <element name="Edge" type="gml:EdgeType" substitutionGroup="gml:AbstractTopoPrimitive">
+    <annotation>
+      <documentation>gml:Edge represents the 1-dimensional primitive.
+The topological boundary of an Edge (gml:directedNode) consists of a negatively directed start Node and a positively directed end Node.   
+The optional coboundary of an edge (gml:directedFace) is a circular sequence of directed faces which are incident on this edge in document order. In the 2D case, the orientation of the face on the left of the edge is "+"; the orientation of the face on the right on its right is "-". 
+If provided, the aggregationType attribute shall have the value "sequence".
+An edge may optionally be realised by a 1-dimensional geometric primitive (gml:curveProperty).</documentation>
+    </annotation>
+  </element>
+  <element name="directedEdge" type="gml:DirectedEdgePropertyType">
+    <annotation>
+      <documentation>A gml:directedEdge property element describes the boundary of topology faces, the coBoundary of topology nodes and is used in the support of topological line features via the gml:TopoCurve expression, see below. The orientation attribute of type gml:SignType expresses the sense in which the included edge is used, i.e. forward or reverse.</documentation>
+    </annotation>
+  </element>
+  <complexType name="DirectedEdgePropertyType">
+    <sequence minOccurs="0">
+      <element ref="gml:Edge"/>
+    </sequence>
+    <attribute name="orientation" type="gml:SignType" default="+"/>
+    <attributeGroup ref="gml:AssociationAttributeGroup"/>
+    <attributeGroup ref="gml:OwnershipAttributeGroup"/>
+  </complexType>
+  <complexType name="FaceType">
+    <complexContent>
+      <extension base="gml:AbstractTopoPrimitiveType">
+        <sequence>
+          <element name="isolated" type="gml:NodePropertyType" minOccurs="0" maxOccurs="unbounded"/>
+          <element ref="gml:directedEdge" maxOccurs="unbounded"/>
+          <element ref="gml:directedTopoSolid" minOccurs="0" maxOccurs="2"/>
+          <element ref="gml:surfaceProperty" minOccurs="0"/>
+        </sequence>
+        <attributeGroup ref="gml:AggregationAttributeGroup"/>
+        <attribute name="universal" type="boolean" use="optional" default="false">
+          <annotation>
+            <documentation>If the topological representation exists an unbounded manifold (e.g. Euclidean plane), a gml:Face must indicate whether it is a universal face or not, to ensure a lossless topology representation as defined by Kuijpers, et. al. (see OGC 05-102 Topology IPR). The optional universal attribute of type boolean is used to indicate this. NOTE The universal face is normally not part of any feature, and is used to represent the unbounded portion of the data set. Its in [...]
+          </annotation>
+        </attribute>
+      </extension>
+    </complexContent>
+  </complexType>
+  <element name="Face" type="gml:FaceType" substitutionGroup="gml:AbstractTopoPrimitive">
+    <annotation>
+      <documentation>gml:Face represents the 2-dimensional topology primitive.
+The topological boundary of a face (gml:directedEdge) consists of a sequence of directed edges. If provided, the aggregationType attribute shall have the value "sequence".
+The optional coboundary of a face (gml:directedTopoSolid) is a pair of directed solids which are bounded by this face. A positively directed solid corresponds to a solid which lies in the direction of the negatively directed normal to the face in any geometric realisation. 
+A face may optionally be realised by a 2-dimensional geometric primitive (gml:surfaceProperty).</documentation>
+    </annotation>
+  </element>
+  <element name="directedFace" type="gml:DirectedFacePropertyType">
+    <annotation>
+      <documentation>The gml:directedFace property element describes the boundary of topology solids, in the coBoundary of topology edges and is used in the support of surface features via the gml:TopoSurface expression, see below. The orientation attribute of type gml:SignType expresses the sense in which the included face is used i.e. inward or outward with respect to the surface normal in any geometric realisation.</documentation>
+    </annotation>
+  </element>
+  <complexType name="DirectedFacePropertyType">
+    <sequence minOccurs="0">
+      <element ref="gml:Face"/>
+    </sequence>
+    <attribute name="orientation" type="gml:SignType" default="+"/>
+    <attributeGroup ref="gml:AssociationAttributeGroup"/>
+    <attributeGroup ref="gml:OwnershipAttributeGroup"/>
+  </complexType>
+  <complexType name="TopoSolidType">
+    <complexContent>
+      <extension base="gml:AbstractTopoPrimitiveType">
+        <sequence>
+          <element name="isolated" type="gml:NodeOrEdgePropertyType" minOccurs="0" maxOccurs="unbounded"/>
+          <element ref="gml:directedFace" maxOccurs="unbounded"/>
+          <element ref="gml:solidProperty" minOccurs="0"/>
+        </sequence>
+        <attributeGroup ref="gml:AggregationAttributeGroup"/>
+        <attribute name="universal" type="boolean" use="optional" default="false">
+          <annotation>
+            <documentation>A gml:TopoSolid must indicate whether it is a universal topo-solid or not, to ensure a lossless topology representation as defined by Kuijpers, et. al. (see OGC 05-102 Topology IPR). The optional universal attribute of type boolean is used to indicate this and the default is fault. NOTE The universal topo-solid is normally not part of any feature, and is used to represent the unbounded portion of the data set. Its interior boundary (it has no exterior boundary) [...]
+          </annotation>
+        </attribute>
+      </extension>
+    </complexContent>
+  </complexType>
+  <element name="TopoSolid" type="gml:TopoSolidType" substitutionGroup="gml:AbstractTopoPrimitive">
+    <annotation>
+      <documentation>gml:TopoSolid represents the 3-dimensional topology primitive. 
+The topological boundary of a solid (gml:directedFace) consists of a set of directed faces.
+A solid may optionally be realised by a 3-dimensional geometric primitive (gml:solidProperty).</documentation>
+    </annotation>
+  </element>
+  <element name="directedTopoSolid" type="gml:DirectedTopoSolidPropertyType">
+    <annotation>
+      <documentation>The gml:directedSolid property element describes the coBoundary of topology faces and is used in the support of volume features via the gml:TopoVolume expression, see below. The orientation attribute of type gml:SignType expresses the sense in which the included solid appears in the face coboundary. In the context of a gml:TopoVolume the orientation attribute has no meaning.</documentation>
+    </annotation>
+  </element>
+  <complexType name="DirectedTopoSolidPropertyType">
+    <sequence minOccurs="0">
+      <element ref="gml:TopoSolid"/>
+    </sequence>
+    <attribute name="orientation" type="gml:SignType" default="+"/>
+    <attributeGroup ref="gml:AssociationAttributeGroup"/>
+    <attributeGroup ref="gml:OwnershipAttributeGroup"/>
+  </complexType>
+  <complexType name="TopoPointType">
+    <complexContent>
+      <extension base="gml:AbstractTopologyType">
+        <sequence>
+          <element ref="gml:directedNode"/>
+        </sequence>
+      </extension>
+    </complexContent>
+  </complexType>
+  <element name="TopoPoint" type="gml:TopoPointType">
+    <annotation>
+      <documentation>The intended use of gml:TopoPoint is to appear within a point feature to express the structural and possibly geometric relationships of this feature to other features via shared node definitions.</documentation>
+    </annotation>
+  </element>
+  <complexType name="TopoPointPropertyType">
+    <sequence>
+      <element ref="gml:TopoPoint"/>
+    </sequence>
+    <attributeGroup ref="gml:OwnershipAttributeGroup"/>
+  </complexType>
+  <element name="topoPointProperty" type="gml:TopoPointPropertyType">
+    <annotation>
+      <documentation>The gml:topoPointProperty property element may be used in features to express their relationship to the referenced topology node.</documentation>
+    </annotation>
+  </element>
+  <complexType name="TopoCurveType">
+    <complexContent>
+      <extension base="gml:AbstractTopologyType">
+        <sequence>
+          <element ref="gml:directedEdge" maxOccurs="unbounded"/>
+        </sequence>
+        <attributeGroup ref="gml:AggregationAttributeGroup"/>
+      </extension>
+    </complexContent>
+  </complexType>
+  <element name="TopoCurve" type="gml:TopoCurveType">
+    <annotation>
+      <documentation>gml:TopoCurve represents a homogeneous topological expression, a sequence of directed edges, which if realised are isomorphic to a geometric curve primitive. The intended use of gml:TopoCurve is to appear within a line feature to express the structural and geometric relationships of this feature to other features via the shared edge definitions.
+If provided, the aggregationType attribute shall have the value "sequence".</documentation>
+    </annotation>
+  </element>
+  <complexType name="TopoCurvePropertyType">
+    <sequence>
+      <element ref="gml:TopoCurve"/>
+    </sequence>
+    <attributeGroup ref="gml:OwnershipAttributeGroup"/>
+  </complexType>
+  <element name="topoCurveProperty" type="gml:TopoCurvePropertyType">
+    <annotation>
+      <documentation>The gml:topoCurveProperty property element may be used in features to express their relationship to the referenced topology edges.</documentation>
+    </annotation>
+  </element>
+  <complexType name="TopoSurfaceType">
+    <complexContent>
+      <extension base="gml:AbstractTopologyType">
+        <sequence>
+          <element ref="gml:directedFace" maxOccurs="unbounded"/>
+        </sequence>
+        <attributeGroup ref="gml:AggregationAttributeGroup"/>
+      </extension>
+    </complexContent>
+  </complexType>
+  <element name="TopoSurface" type="gml:TopoSurfaceType">
+    <annotation>
+      <documentation>gml:TopoSurface represents a homogeneous topological expression, a set of directed faces, which if realised are isomorphic to a geometric surface primitive. The intended use of gml:TopoSurface is to appear within a surface feature to express the structural and possibly geometric relationships of this surface feature to other features via the shared face definitions.</documentation>
+    </annotation>
+  </element>
+  <complexType name="TopoSurfacePropertyType">
+    <sequence>
+      <element ref="gml:TopoSurface"/>
+    </sequence>
+    <attributeGroup ref="gml:OwnershipAttributeGroup"/>
+  </complexType>
+  <element name="topoSurfaceProperty" type="gml:TopoSurfacePropertyType">
+    <annotation>
+      <documentation>The gml:topoSurfaceProperty property element may be used in features to express their relationship to the referenced topology faces.</documentation>
+    </annotation>
+  </element>
+  <complexType name="TopoVolumeType">
+    <complexContent>
+      <extension base="gml:AbstractTopologyType">
+        <sequence>
+          <element ref="gml:directedTopoSolid" maxOccurs="unbounded"/>
+        </sequence>
+        <attributeGroup ref="gml:AggregationAttributeGroup"/>
+      </extension>
+    </complexContent>
+  </complexType>
+  <element name="TopoVolume" type="gml:TopoVolumeType">
+    <annotation>
+      <documentation>gml:TopoVolume represents a homogeneous topological expression, a set of directed topologic solids, which if realised are isomorphic to a geometric solid primitive. The intended use of gml:TopoVolume is to appear within a solid feature to express the structural and geometric relationships of this solid feature to other features via the shared solid definitions.</documentation>
+    </annotation>
+  </element>
+  <complexType name="TopoVolumePropertyType">
+    <sequence>
+      <element ref="gml:TopoVolume"/>
+    </sequence>
+    <attributeGroup ref="gml:OwnershipAttributeGroup"/>
+  </complexType>
+  <element name="topoVolumeProperty" type="gml:TopoVolumePropertyType">
+    <annotation>
+      <documentation>The gml:topoVolumeProperty element may be used in features to express their relationship to the referenced topology volume.</documentation>
+    </annotation>
+  </element>
+  <complexType name="TopoComplexType">
+    <complexContent>
+      <extension base="gml:AbstractTopologyType">
+        <sequence>
+          <element ref="gml:maximalComplex"/>
+          <element ref="gml:superComplex" minOccurs="0" maxOccurs="unbounded"/>
+          <element ref="gml:subComplex" minOccurs="0" maxOccurs="unbounded"/>
+          <element ref="gml:topoPrimitiveMember" minOccurs="0" maxOccurs="unbounded"/>
+          <element ref="gml:topoPrimitiveMembers" minOccurs="0"/>
+        </sequence>
+        <attribute name="isMaximal" type="boolean" default="false"/>
+        <attributeGroup ref="gml:AggregationAttributeGroup"/>
+      </extension>
+    </complexContent>
+  </complexType>
+  <element name="TopoComplex" type="gml:TopoComplexType" substitutionGroup="gml:AbstractTopology">
+    <annotation>
+      <documentation>gml:TopoComplex is a collection of topological primitives.
+Each complex holds a reference to its maximal complex (gml:maximalComplex) and optionally to sub- or super-complexes (gml:subComplex, gml:superComplex). 
+A topology complex contains its primitive and sub-complex members.
+</documentation>
+    </annotation>
+  </element>
+  <element name="subComplex" type="gml:TopoComplexPropertyType">
+    <annotation>
+      <documentation>The property elements gml:subComplex, gml:superComplex and gml:maximalComplex provide an encoding for relationships between topology complexes as described for gml:TopoComplex above.</documentation>
+    </annotation>
+  </element>
+  <element name="superComplex" type="gml:TopoComplexPropertyType">
+    <annotation>
+      <documentation>The property elements gml:subComplex, gml:superComplex and gml:maximalComplex provide an encoding for relationships between topology complexes as described for gml:TopoComplex above.</documentation>
+    </annotation>
+  </element>
+  <element name="maximalComplex" type="gml:TopoComplexPropertyType">
+    <annotation>
+      <documentation>The property elements gml:subComplex, gml:superComplex and gml:maximalComplex provide an encoding for relationships between topology complexes as described for gml:TopoComplex above.</documentation>
+    </annotation>
+  </element>
+  <element name="topoPrimitiveMember" type="gml:TopoPrimitiveMemberType">
+    <annotation>
+      <documentation>The gml:topoPrimitiveMember property element encodes for the relationship between a topology complex and a single topology primitive.</documentation>
+    </annotation>
+  </element>
+  <complexType name="TopoPrimitiveMemberType">
+    <sequence minOccurs="0">
+      <element ref="gml:AbstractTopoPrimitive"/>
+    </sequence>
+    <attributeGroup ref="gml:AssociationAttributeGroup"/>
+    <attributeGroup ref="gml:OwnershipAttributeGroup"/>
+  </complexType>
+  <element name="topoPrimitiveMembers" type="gml:TopoPrimitiveArrayAssociationType">
+    <annotation>
+      <documentation>The gml:topoPrimitiveMembers property element encodes the relationship between a topology complex and an arbitrary number of topology primitives.</documentation>
+    </annotation>
+  </element>
+  <complexType name="TopoPrimitiveArrayAssociationType">
+    <sequence minOccurs="0" maxOccurs="unbounded">
+      <element ref="gml:AbstractTopoPrimitive"/>
+    </sequence>
+    <attributeGroup ref="gml:OwnershipAttributeGroup"/>
+  </complexType>
+  <complexType name="TopoComplexPropertyType">
+    <sequence minOccurs="0">
+      <element ref="gml:TopoComplex"/>
+    </sequence>
+    <attributeGroup ref="gml:AssociationAttributeGroup"/>
+  </complexType>
+</schema>
diff --git a/pycsw/core/schemas/ogc/gml/3.2.1/units.xsd b/pycsw/core/schemas/ogc/gml/3.2.1/units.xsd
new file mode 100644
index 0000000..84eca23
--- /dev/null
+++ b/pycsw/core/schemas/ogc/gml/3.2.1/units.xsd
@@ -0,0 +1,162 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<schema targetNamespace="http://www.opengis.net/gml/3.2" xmlns="http://www.w3.org/2001/XMLSchema" xmlns:gml="http://www.opengis.net/gml/3.2" elementFormDefault="qualified" xml:lang="en" version="3.2.1.2">
+	<annotation>
+		<appinfo source="urn:x-ogc:specification:gml:schema-xsd:units:3.2.1">units.xsd</appinfo>
+		<documentation>See ISO/DIS 17.2.
+Several GML Schema components concern or require a reference scale or units of measure.  Units are required for quantities that may occur as values of properties of feature types, as the results of observations, in the range parameters of a coverage, and for measures used in Coordinate Reference System definitions. 
+The basic unit definition is an extension of the general gml:Definition element defined in 16.2.1.  Three specialized elements for unit definition are further derived from this. 
+This model is based on the SI system of units [ISO 1000], which distinguishes between Base Units and Derived Units.  
+-	Base Units are the preferred units for a set of orthogonal fundamental quantities which define the particular system of units, which may not be derived by combination of other base units.  
+-	Derived Units are the preferred units for other quantities in the system, which may be defined by algebraic combination of the base units.  
+In some application areas Conventional units are used, which may be converted to the preferred units using a scaling factor or a formula which defines a re-scaling and offset.  The set of preferred units for all physical quantity types in a particular system of units is composed of the union of its base units and derived units.  
+Unit definitions are substitutable for the gml:Definition element declared as part of the dictionary model.  A dictionary that contains only unit definitions and references to unit definitions is a units dictionary.
+
+GML is an OGC Standard.
+Copyright (c) 2007,2010 Open Geospatial Consortium.
+To obtain additional rights of use, visit http://www.opengeospatial.org/legal/ .
+		</documentation>
+	</annotation>
+	<include schemaLocation="gml.xsd"/>
+	<include schemaLocation="dictionary.xsd"/>
+	<element name="unitOfMeasure" type="gml:UnitOfMeasureType">
+		<annotation>
+			<documentation>The element gml:unitOfMeasure is a property element to refer to a unit of measure. This is an empty element which carries a reference to a unit of measure definition.</documentation>
+		</annotation>
+	</element>
+	<complexType name="UnitOfMeasureType">
+		<sequence/>
+		<attribute name="uom" type="gml:UomIdentifier" use="required"/>
+	</complexType>
+	<element name="UnitDefinition" type="gml:UnitDefinitionType" substitutionGroup="gml:Definition">
+		<annotation>
+			<documentation>A gml:UnitDefinition is a general definition of a unit of measure. This generic element is used only for units for which no relationship with other units or units systems is known.
+The content model of gml:UnitDefinition adds three additional properties to gml:Definition, gml:quantityType, gml:quantityTypeReference and gml:catalogSymbol.  
+The gml:catalogSymbol property optionally gives the short symbol used for this unit. This element is usually used when the relationship of this unit to other units or units systems is unknown.</documentation>
+		</annotation>
+	</element>
+	<complexType name="UnitDefinitionType">
+		<complexContent>
+			<extension base="gml:DefinitionType">
+				<sequence>
+					<element ref="gml:quantityType" minOccurs="0"/>
+					<element ref="gml:quantityTypeReference" minOccurs="0"/>
+					<element ref="gml:catalogSymbol" minOccurs="0"/>
+				</sequence>
+			</extension>
+		</complexContent>
+	</complexType>
+	<element name="quantityType" type="gml:StringOrRefType">
+		<annotation>
+			<documentation>The gml:quantityType property indicates the phenomenon to which the units apply. This element contains an informal description of the phenomenon or type of physical quantity that is measured or observed. When the physical quantity is the result of an observation or measurement, this term is known as observable type or measurand.
+The use of gml:quantityType for references to remote values is deprecated.</documentation>
+		</annotation>
+	</element>
+	<element name="quantityTypeReference" type="gml:ReferenceType">
+		<annotation>
+			<documentation>The gml:quantityTypeReference property indicates the phenomenon to which the units apply. The content is a reference to a remote value.</documentation>
+		</annotation>
+	</element>
+	<element name="catalogSymbol" type="gml:CodeType">
+		<annotation>
+			<documentation>The catalogSymbol is the preferred lexical symbol used for this unit of measure.
+The codeSpace attribute in gml:CodeType identifies a namespace for the catalog symbol value, and might reference the external catalog. The string value in gml:CodeType contains the value of a symbol that should be unique within this catalog namespace. This symbol often appears explicitly in the catalog, but it could be a combination of symbols using a specified algebra of units.</documentation>
+		</annotation>
+	</element>
+	<element name="BaseUnit" type="gml:BaseUnitType" substitutionGroup="gml:UnitDefinition">
+		<annotation>
+			<documentation>A base unit is a unit of measure that cannot be derived by combination of other base units within a particular system of units.  For example, in the SI system of units, the base units are metre, kilogram, second, Ampere, Kelvin, mole, and candela, for the physical quantity types length, mass, time interval, electric current, thermodynamic temperature, amount of substance and luminous intensity, respectively.
+gml:BaseUnit extends generic gml:UnitDefinition with the property gml:unitsSystem, which carries a reference to the units system to which this base unit is asserted to belong.  </documentation>
+		</annotation>
+	</element>
+	<complexType name="BaseUnitType">
+		<complexContent>
+			<extension base="gml:UnitDefinitionType">
+				<sequence>
+					<element name="unitsSystem" type="gml:ReferenceType"/>
+				</sequence>
+			</extension>
+		</complexContent>
+	</complexType>
+	<element name="DerivedUnit" type="gml:DerivedUnitType" substitutionGroup="gml:UnitDefinition">
+		<annotation>
+			<documentation>Derived units are defined by combination of other units.  Derived units are used for quantities other than those corresponding to the base units, such as hertz (s-1) for frequency, Newton (kg.m/s2) for force.  Derived units based directly on base units are usually preferred for quantities other than the fundamental quantities within a system. If a derived unit is not the preferred unit, the gml:ConventionalUnit element should be used instead.
+The gml:DerivedUnit extends gml:UnitDefinition with the property gml:derivationUnitTerms.</documentation>
+		</annotation>
+	</element>
+	<complexType name="DerivedUnitType">
+		<complexContent>
+			<extension base="gml:UnitDefinitionType">
+				<sequence>
+					<element ref="gml:derivationUnitTerm" maxOccurs="unbounded"/>
+				</sequence>
+			</extension>
+		</complexContent>
+	</complexType>
+	<element name="derivationUnitTerm" type="gml:DerivationUnitTermType">
+		<annotation>
+			<documentation>A set of gml:derivationUnitTerm elements describes a derived unit of measure.  Each element carries an integer exponent.  The terms are combined by raising each referenced unit to the power of its exponent and forming the product.
+This unit term references another unit of measure (uom) and provides an integer exponent applied to that unit in defining the compound unit. The exponent may be positive or negative, but not zero.</documentation>
+		</annotation>
+	</element>
+	<complexType name="DerivationUnitTermType">
+		<complexContent>
+			<extension base="gml:UnitOfMeasureType">
+				<attribute name="exponent" type="integer"/>
+			</extension>
+		</complexContent>
+	</complexType>
+	<element name="ConventionalUnit" type="gml:ConventionalUnitType" substitutionGroup="gml:UnitDefinition">
+		<annotation>
+			<documentation>Conventional units that are neither base units nor defined by direct combination of base units are used in many application domains.  For example electronVolt for energy, feet and nautical miles for length.  In most cases there is a known, usually linear, conversion to a preferred unit which is either a base unit or derived by direct combination of base units.
+The gml:ConventionalUnit extends gml:UnitDefinition with a property that describes a conversion to a preferred unit for this physical quantity.  When the conversion is exact, the element gml:conversionToPreferredUnit should be used, or when the conversion is not exact the element gml:roughConversionToPreferredUnit is available. Both of these elements have the same content model.  The gml:derivationUnitTerm property defined above is included to allow a user to optionally record how this u [...]
+		</annotation>
+	</element>
+	<complexType name="ConventionalUnitType">
+		<complexContent>
+			<extension base="gml:UnitDefinitionType">
+				<sequence>
+					<choice>
+						<element ref="gml:conversionToPreferredUnit"/>
+						<element ref="gml:roughConversionToPreferredUnit"/>
+					</choice>
+					<element ref="gml:derivationUnitTerm" minOccurs="0" maxOccurs="unbounded"/>
+				</sequence>
+			</extension>
+		</complexContent>
+	</complexType>
+	<element name="conversionToPreferredUnit" type="gml:ConversionToPreferredUnitType">
+		<annotation>
+			<documentation>The elements gml:conversionToPreferredUnit and gml:roughConversionToPreferredUnit represent parameters used to convert conventional units to preferred units for this physical quantity type.  A preferred unit is either a Base Unit or a Derived Unit that is selected for all values of one physical quantity type.</documentation>
+		</annotation>
+	</element>
+	<element name="roughConversionToPreferredUnit" type="gml:ConversionToPreferredUnitType">
+		<annotation>
+			<documentation>The elements gml:conversionToPreferredUnit and gml:roughConversionToPreferredUnit represent parameters used to convert conventional units to preferred units for this physical quantity type.  A preferred unit is either a Base Unit or a Derived Unit that is selected for all values of one physical quantity type.</documentation>
+		</annotation>
+	</element>
+	<complexType name="ConversionToPreferredUnitType">
+		<annotation>
+			<documentation>The inherited attribute uom references the preferred unit that this conversion applies to. The conversion of a unit to the preferred unit for this physical quantity type is specified by an arithmetic conversion (scaling and/or offset). The content model extends gml:UnitOfMeasureType, which has a mandatory attribute uom which identifies the preferred unit for the physical quantity type that this conversion applies to. The conversion is specified by a choice of 
+-	gml:factor, which defines the scale factor, or
+-	gml:formula, which defines a formula 
+by which a value using the conventional unit of measure can be converted to obtain the corresponding value using the preferred unit of measure.  
+The formula defines the parameters of a simple formula by which a value using the conventional unit of measure can be converted to the corresponding value using the preferred unit of measure. The formula element contains elements a, b, c and d, whose values use the XML Schema type double. These values are used in the formula y = (a + bx) / (c + dx), where x is a value using this unit, and y is the corresponding value using the base unit. The elements a and d are optional, and if values a [...]
+		</annotation>
+		<complexContent>
+			<extension base="gml:UnitOfMeasureType">
+				<choice>
+					<element name="factor" type="double"/>
+					<element name="formula" type="gml:FormulaType"/>
+				</choice>
+			</extension>
+		</complexContent>
+	</complexType>
+	<complexType name="FormulaType">
+		<sequence>
+			<element name="a" type="double" minOccurs="0"/>
+			<element name="b" type="double"/>
+			<element name="c" type="double"/>
+			<element name="d" type="double" minOccurs="0"/>
+		</sequence>
+	</complexType>
+</schema>
diff --git a/pycsw/core/schemas/ogc/gml/3.2.1/valueObjects.xsd b/pycsw/core/schemas/ogc/gml/3.2.1/valueObjects.xsd
new file mode 100644
index 0000000..204bdfd
--- /dev/null
+++ b/pycsw/core/schemas/ogc/gml/3.2.1/valueObjects.xsd
@@ -0,0 +1,205 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<schema targetNamespace="http://www.opengis.net/gml/3.2" xmlns:gml="http://www.opengis.net/gml/3.2" xmlns="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" version="3.2.1.2">
+	<annotation>
+		<appinfo source="urn:x-ogc:specification:gml:schema-xsd:valueObjects:3.2.1">valueObjects.xsd</appinfo>
+		<documentation>See ISO/DIS 19136 17.5.
+The elements declared in this Clause build on other GML schema components, in particular gml:AbstractTimeObject, gml:AbstractGeometry, and the following types:  gml:MeasureType, gml:MeasureListType, gml:CodeType, gml:CodeOrNilReasonListType, gml:BooleanOrNilReasonListType, gml:IntegerOrNilReasonList.  
+Of particular interest are elements that are the heads of substitution groups, and one named choice group. These are the primary reasons for the value objects schema, since they may act as variables in the definition of content models, such as Observations, when it is desired to permit alternative value types to occur some of which may have complex content such as arrays, geometry and time objects, and where it is useful not to prescribe the actual value type in advance. The members of t [...]
+The value objects are defined in a hierarchy. The following relationships are defined:
+-	Concrete elements gml:Quantity, gml:Category, gml:Count and gml:Boolean are substitutable for the abstract element gml:AbstractScalarValue.  
+-	Concrete elements gml:QuantityList, gml:CategoryList, gml:CountList and gml:BooleanList are substitutable for the abstract element gml:AbstractScalarValueList.  
+-	Concrete element gml:ValueArray is substitutable for the concrete element gml:CompositeValue.  
+-	Abstract elements gml:AbstractScalarValue and gml:AbstractScalarValueList, and concrete elements gml:CompositeValue, gml:ValueExtent, gml:CategoryExtent, gml:CountExtent and gml:QuantityExtent are substitutable for abstract element gml:AbstractValue.  
+-	Abstract elements gml:AbstractValue, gml:AbstractTimeObject and gml:AbstractGeometry are all in a choice group named gml:Value, which is used for compositing in gml:CompositeValue and gml:ValueExtent.  
+-	Schemas which need values may use the abstract element gml:AbstractValue in a content model in order to permit any of the gml:AbstractScalarValues, gml:AbstractScalarValueLists, gml:CompositeValue or gml:ValueExtent to occur in an instance, or the named group gml:Value to also permit gml:AbstractTimeObjects, gml:AbstractGeometrys.
+
+GML is an OGC Standard.
+Copyright (c) 2007,2010 Open Geospatial Consortium.
+To obtain additional rights of use, visit http://www.opengeospatial.org/legal/ .
+		</documentation>
+	</annotation>
+	<include schemaLocation="gml.xsd"/>
+	<include schemaLocation="geometryBasic0d1d.xsd"/>
+	<include schemaLocation="temporal.xsd"/>
+	<element name="Boolean" substitutionGroup="gml:AbstractScalarValue" nillable="true">
+		<complexType>
+			<simpleContent>
+				<extension base="boolean">
+					<attribute name="nilReason" type="gml:NilReasonType"/>
+				</extension>
+			</simpleContent>
+		</complexType>
+	</element>
+	<element name="BooleanList" type="gml:booleanOrNilReasonList" substitutionGroup="gml:AbstractScalarValueList"/>
+	<element name="Category" substitutionGroup="gml:AbstractScalarValue" nillable="true">
+		<annotation>
+			<documentation>A gml:Category has an optional XML attribute codeSpace, whose value is a URI which identifies a dictionary, codelist or authority for the term.</documentation>
+		</annotation>
+		<complexType>
+			<simpleContent>
+				<extension base="gml:CodeType">
+					<attribute name="nilReason" type="gml:NilReasonType"/>
+				</extension>
+			</simpleContent>
+		</complexType>
+	</element>
+	<element name="CategoryList" type="gml:CodeOrNilReasonListType" substitutionGroup="gml:AbstractScalarValueList"/>
+	<element name="Count" substitutionGroup="gml:AbstractScalarValue" nillable="true">
+		<complexType>
+			<simpleContent>
+				<extension base="integer">
+					<attribute name="nilReason" type="gml:NilReasonType"/>
+				</extension>
+			</simpleContent>
+		</complexType>
+	</element>
+	<element name="CountList" type="gml:integerOrNilReasonList" substitutionGroup="gml:AbstractScalarValueList"/>
+	<element name="Quantity" substitutionGroup="gml:AbstractScalarValue" nillable="true">
+		<annotation>
+			<documentation>An XML attribute uom ("unit of measure") is required, whose value is a URI which identifies the definition of a ratio scale or units by which the numeric value shall be multiplied, or an interval or position scale on which the value occurs.</documentation>
+		</annotation>
+		<complexType>
+			<simpleContent>
+				<extension base="gml:MeasureType">
+					<attribute name="nilReason" type="gml:NilReasonType"/>
+				</extension>
+			</simpleContent>
+		</complexType>
+	</element>
+	<element name="QuantityList" type="gml:MeasureOrNilReasonListType" substitutionGroup="gml:AbstractScalarValueList"/>
+	<element name="AbstractValue" type="anyType" abstract="true" substitutionGroup="gml:AbstractObject">
+		<annotation>
+			<documentation>gml:AbstractValue is an abstract element which acts as the head of a substitution group which contains gml:AbstractScalarValue, gml:AbstractScalarValueList, gml:CompositeValue and gml:ValueExtent, and (transitively) the elements in their substitution groups.
+These elements may be used in an application schema as variables, so that in an XML instance document any member of its substitution group may occur.</documentation>
+		</annotation>
+	</element>
+	<element name="AbstractScalarValue" type="anyType" abstract="true" substitutionGroup="gml:AbstractValue">
+		<annotation>
+			<documentation>gml:AbstractScalarValue is an abstract element which acts as the head of a substitution group which contains gml:Boolean, gml:Category, gml:Count and gml:Quantity, and (transitively) the elements in their substitution groups.</documentation>
+		</annotation>
+	</element>
+	<element name="AbstractScalarValueList" type="anyType" abstract="true" substitutionGroup="gml:AbstractValue">
+		<annotation>
+			<documentation>gml:AbstractScalarValueList is an abstract element which acts as the head of a substitution group which contains gml:BooleanList, gml:CategoryList, gml:CountList and gml:QuantityList, and (transitively) the elements in their substitution groups.</documentation>
+		</annotation>
+	</element>
+	<group name="Value">
+		<annotation>
+			<documentation>This is a convenience choice group which unifies generic values defined in this Clause with spatial and temporal objects and the measures described above, so that any of these may be used within aggregate values.</documentation>
+		</annotation>
+		<choice>
+			<element ref="gml:AbstractValue"/>
+			<element ref="gml:AbstractGeometry"/>
+			<element ref="gml:AbstractTimeObject"/>
+			<element ref="gml:Null"/>
+		</choice>
+	</group>
+	<element name="valueProperty" type="gml:ValuePropertyType">
+		<annotation>
+			<documentation>Property that refers to, or contains, a Value. Convenience element for general use.</documentation>
+		</annotation>
+	</element>
+	<element name="valueComponent" type="gml:ValuePropertyType">
+		<annotation>
+			<documentation>Property that refers to, or contains, a Value.</documentation>
+		</annotation>
+	</element>
+	<complexType name="ValuePropertyType">
+		<sequence minOccurs="0">
+			<group ref="gml:Value"/>
+		</sequence>
+		<attributeGroup ref="gml:AssociationAttributeGroup"/>
+		<attributeGroup ref="gml:OwnershipAttributeGroup"/>
+	</complexType>
+	<element name="valueComponents" type="gml:ValueArrayPropertyType">
+		<annotation>
+			<documentation>Property that contains Values.</documentation>
+		</annotation>
+	</element>
+	<complexType name="ValueArrayPropertyType">
+		<sequence maxOccurs="unbounded">
+			<group ref="gml:Value"/>
+		</sequence>
+		<attributeGroup ref="gml:OwnershipAttributeGroup"/>
+	</complexType>
+	<element name="CompositeValue" type="gml:CompositeValueType" substitutionGroup="gml:AbstractValue">
+		<annotation>
+			<documentation>gml:CompositeValue is an aggregate value built from other values . It contains zero or an arbitrary number of gml:valueComponent elements, and zero or one gml:valueComponents property elements.  It may be used for strongly coupled aggregates (vectors, tensors) or for arbitrary collections of values.</documentation>
+		</annotation>
+	</element>
+	<complexType name="CompositeValueType">
+		<complexContent>
+			<extension base="gml:AbstractGMLType">
+				<sequence>
+					<element ref="gml:valueComponent" minOccurs="0" maxOccurs="unbounded"/>
+					<element ref="gml:valueComponents" minOccurs="0"/>
+				</sequence>
+				<attributeGroup ref="gml:AggregationAttributeGroup"/>
+			</extension>
+		</complexContent>
+	</complexType>
+	<element name="ValueArray" type="gml:ValueArrayType" substitutionGroup="gml:CompositeValue">
+		<annotation>
+			<documentation>A Value Array is used for homogeneous arrays of primitive and aggregate values.  
+The member values may be scalars, composites, arrays or lists.
+ValueArray has the same content model as CompositeValue, but the member values shall be homogeneous.  The element declaration contains a Schematron constraint which expresses this restriction precisely.  Since the members are homogeneous, the gml:referenceSystem (uom, codeSpace) may be specified on the gml:ValueArray itself and inherited by all the members if desired.</documentation>
+		</annotation>
+	</element>
+	<complexType name="ValueArrayType">
+		<complexContent>
+			<extension base="gml:CompositeValueType">
+				<attributeGroup ref="gml:referenceSystem"/>
+			</extension>
+		</complexContent>
+	</complexType>
+	<attributeGroup name="referenceSystem">
+		<attribute name="codeSpace" type="anyURI"/>
+		<attribute name="uom" type="gml:UomIdentifier"/>
+	</attributeGroup>
+	<element name="CategoryExtent" type="gml:CategoryExtentType" substitutionGroup="gml:AbstractValue"/>
+	<complexType name="CategoryExtentType">
+		<simpleContent>
+			<restriction base="gml:CodeOrNilReasonListType">
+				<length value="2"/>
+			</restriction>
+		</simpleContent>
+	</complexType>
+	<element name="CountExtent" type="gml:CountExtentType" substitutionGroup="gml:AbstractValue"/>
+	<simpleType name="CountExtentType">
+		<restriction base="gml:integerOrNilReasonList">
+			<length value="2"/>
+		</restriction>
+	</simpleType>
+	<element name="QuantityExtent" type="gml:QuantityExtentType" substitutionGroup="gml:AbstractValue"/>
+	<complexType name="QuantityExtentType">
+		<simpleContent>
+			<restriction base="gml:MeasureOrNilReasonListType">
+				<length value="2"/>
+			</restriction>
+		</simpleContent>
+	</complexType>
+	<complexType name="BooleanPropertyType">
+		<sequence minOccurs="0">
+			<element ref="gml:Boolean"/>
+		</sequence>
+		<attributeGroup ref="gml:AssociationAttributeGroup"/>
+	</complexType>
+	<complexType name="CategoryPropertyType">
+		<sequence minOccurs="0">
+			<element ref="gml:Category"/>
+		</sequence>
+		<attributeGroup ref="gml:AssociationAttributeGroup"/>
+	</complexType>
+	<complexType name="QuantityPropertyType">
+		<sequence minOccurs="0">
+			<element ref="gml:Quantity"/>
+		</sequence>
+		<attributeGroup ref="gml:AssociationAttributeGroup"/>
+	</complexType>
+	<complexType name="CountPropertyType">
+		<sequence minOccurs="0">
+			<element ref="gml:Count"/>
+		</sequence>
+		<attributeGroup ref="gml:AssociationAttributeGroup"/>
+	</complexType>
+</schema>
diff --git a/pycsw/schemas/ogc/ows/1.0.0/ows19115subset.xsd b/pycsw/core/schemas/ogc/ows/1.0.0/ows19115subset.xsd
similarity index 100%
copy from pycsw/schemas/ogc/ows/1.0.0/ows19115subset.xsd
copy to pycsw/core/schemas/ogc/ows/1.0.0/ows19115subset.xsd
diff --git a/pycsw/schemas/ogc/ows/1.0.0/owsAll.xsd b/pycsw/core/schemas/ogc/ows/1.0.0/owsAll.xsd
similarity index 100%
copy from pycsw/schemas/ogc/ows/1.0.0/owsAll.xsd
copy to pycsw/core/schemas/ogc/ows/1.0.0/owsAll.xsd
diff --git a/pycsw/schemas/ogc/ows/1.0.0/owsCommon.xsd b/pycsw/core/schemas/ogc/ows/1.0.0/owsCommon.xsd
similarity index 100%
copy from pycsw/schemas/ogc/ows/1.0.0/owsCommon.xsd
copy to pycsw/core/schemas/ogc/ows/1.0.0/owsCommon.xsd
diff --git a/pycsw/schemas/ogc/ows/1.0.0/owsDataIdentification.xsd b/pycsw/core/schemas/ogc/ows/1.0.0/owsDataIdentification.xsd
similarity index 100%
copy from pycsw/schemas/ogc/ows/1.0.0/owsDataIdentification.xsd
copy to pycsw/core/schemas/ogc/ows/1.0.0/owsDataIdentification.xsd
diff --git a/pycsw/schemas/ogc/ows/1.0.0/owsExceptionReport.xsd b/pycsw/core/schemas/ogc/ows/1.0.0/owsExceptionReport.xsd
similarity index 100%
copy from pycsw/schemas/ogc/ows/1.0.0/owsExceptionReport.xsd
copy to pycsw/core/schemas/ogc/ows/1.0.0/owsExceptionReport.xsd
diff --git a/pycsw/schemas/ogc/ows/1.0.0/owsGetCapabilities.xsd b/pycsw/core/schemas/ogc/ows/1.0.0/owsGetCapabilities.xsd
similarity index 100%
copy from pycsw/schemas/ogc/ows/1.0.0/owsGetCapabilities.xsd
copy to pycsw/core/schemas/ogc/ows/1.0.0/owsGetCapabilities.xsd
diff --git a/pycsw/schemas/ogc/ows/1.0.0/owsOperationsMetadata.xsd b/pycsw/core/schemas/ogc/ows/1.0.0/owsOperationsMetadata.xsd
similarity index 100%
copy from pycsw/schemas/ogc/ows/1.0.0/owsOperationsMetadata.xsd
copy to pycsw/core/schemas/ogc/ows/1.0.0/owsOperationsMetadata.xsd
diff --git a/pycsw/schemas/ogc/ows/1.0.0/owsServiceIdentification.xsd b/pycsw/core/schemas/ogc/ows/1.0.0/owsServiceIdentification.xsd
similarity index 100%
copy from pycsw/schemas/ogc/ows/1.0.0/owsServiceIdentification.xsd
copy to pycsw/core/schemas/ogc/ows/1.0.0/owsServiceIdentification.xsd
diff --git a/pycsw/schemas/ogc/ows/1.0.0/owsServiceProvider.xsd b/pycsw/core/schemas/ogc/ows/1.0.0/owsServiceProvider.xsd
similarity index 100%
copy from pycsw/schemas/ogc/ows/1.0.0/owsServiceProvider.xsd
copy to pycsw/core/schemas/ogc/ows/1.0.0/owsServiceProvider.xsd
diff --git a/pycsw/schemas/ogc/ows/1.0.0/ows19115subset.xsd b/pycsw/core/schemas/ogc/ows/1.1.0/ows19115subset.xsd
similarity index 85%
rename from pycsw/schemas/ogc/ows/1.0.0/ows19115subset.xsd
rename to pycsw/core/schemas/ogc/ows/1.1.0/ows19115subset.xsd
index 7f15aed..5e2c697 100644
--- a/pycsw/schemas/ogc/ows/1.0.0/ows19115subset.xsd
+++ b/pycsw/core/schemas/ogc/ows/1.1.0/ows19115subset.xsd
@@ -1,32 +1,45 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<schema targetNamespace="http://www.opengis.net/ows" 
-xmlns:ows="http://www.opengis.net/ows" 
+<schema targetNamespace="http://www.opengis.net/ows/1.1" 
+xmlns:ows="http://www.opengis.net/ows/1.1" 
 xmlns:xlink="http://www.w3.org/1999/xlink" 
 xmlns="http://www.w3.org/2001/XMLSchema" 
-elementFormDefault="qualified" version="1.0.0 2010-01-30" xml:lang="en">
+elementFormDefault="qualified" version="1.1.0.3" xml:lang="en">
 	<annotation>
-		<appinfo>ows19115subset.xsd 2010-01-30</appinfo>
-		<documentation>This XML Schema Document encodes the parts of ISO 19115 used by the common "ServiceIdentification" and "ServiceProvider" sections of the GetCapabilities operation response, known as the service metadata XML document. The parts encoded here are the MD_Keywords, CI_ResponsibleParty, and related classes. This XML Schema largely follows the current draft for ISO 19139, with the addition of documentation text extracted and edited from Annex B of ISO 19115. The UML package pre [...]
+		<appinfo>ows19115subset.xsd</appinfo>
+		<documentation>This XML Schema Document encodes the parts of ISO 19115 used by the common "ServiceIdentification" and "ServiceProvider" sections of the GetCapabilities operation response, known as the service metadata XML document. The parts encoded here are the MD_Keywords, CI_ResponsibleParty, and related classes. The UML package prefixes were omitted from XML names, and the XML element names were all capitalized, for consistency with other OWS Schemas. This document also provides a  [...]
 		
 		OWS is an OGC Standard.
-		Copyright (c) 2005,2010 Open Geospatial Consortium, Inc. All Rights Reserved.
+		Copyright (c) 2006,2010 Open Geospatial Consortium.
 		To obtain additional rights of use, visit http://www.opengeospatial.org/legal/ .
 		</documentation>
 	</annotation>
 	<!-- ==============================================================
 		includes and imports
 	============================================================== -->
+    <include schemaLocation="owsAll.xsd"/>
 	<import namespace="http://www.w3.org/1999/xlink" schemaLocation="../../../w3c/1999/xlink.xsd"/>
+	<import namespace="http://www.w3.org/XML/1998/namespace" schemaLocation="../../../w3c/2001/xml.xsd"/>
 	<!-- ==============================================================
 		elements and types
 	============================================================== -->
-	<element name="Title" type="string">
+	<complexType name="LanguageStringType">
+		<annotation>
+			<documentation>Text string with the language of the string identified as recommended in the XML 1.0 W3C Recommendation, section 2.12. </documentation>
+		</annotation>
+		<simpleContent>
+			<extension base="string">
+				<attribute ref="xml:lang" use="optional"/>
+			</extension>
+		</simpleContent>
+	</complexType>
+	<!-- =========================================================== -->
+	<element name="Title" type="ows:LanguageStringType">
 		<annotation>
 			<documentation>Title of this resource, normally used for display to a human. </documentation>
 		</annotation>
 	</element>
 	<!-- =========================================================== -->
-	<element name="Abstract" type="string">
+	<element name="Abstract" type="ows:LanguageStringType">
 		<annotation>
 			<documentation>Brief narrative description of this resource, normally used for display to a human. </documentation>
 		</annotation>
@@ -36,18 +49,19 @@ elementFormDefault="qualified" version="1.0.0 2010-01-30" xml:lang="en">
 	<!-- =========================================================== -->
 	<complexType name="KeywordsType">
 		<annotation>
-			<documentation>Unordered list of one or more commonly used or formalised word(s) or phrase(s) used to describe the subject. When needed, the optional "type" can name the type of the associated list of keywords that shall all have the same type. Also when needed, the codeSpace attribute of that "type" can reference the type name authority and/or thesaurus. </documentation>
+			<documentation>Unordered list of one or more commonly used or formalised word(s) or phrase(s) used to describe the subject. When needed, the optional "type" can name the type of the associated list of keywords that shall all have the same type. Also when needed, the codeSpace attribute of that "type" can reference the type name authority and/or thesaurus.
+			If the xml:lang attribute is not included in a Keyword element, then no language is specified for that element unless specified by another means.  All Keyword elements in the same Keywords element that share the same xml:lang attribute value represent different keywords in that language. </documentation>
 			<documentation>For OWS use, the optional thesaurusName element was omitted as being complex information that could be referenced by the codeSpace attribute of the Type element. </documentation>
 		</annotation>
 		<sequence>
-			<element name="Keyword" type="string" maxOccurs="unbounded"/>
+			<element name="Keyword" type="ows:LanguageStringType" maxOccurs="unbounded"/>
 			<element name="Type" type="ows:CodeType" minOccurs="0"/>
 		</sequence>
 	</complexType>
 	<!-- =========================================================== -->
 	<complexType name="CodeType">
 		<annotation>
-			<documentation>Name or code with an (optional) authority. If the codeSpace attribute is present, its value should reference a dictionary, thesaurus, or authority for the name or code, such as the organisation who assigned the value, or the dictionary from which it is taken. </documentation>
+			<documentation>Name or code with an (optional) authority. If the codeSpace attribute is present, its value shall reference a dictionary, thesaurus, or authority for the name or code, such as the organisation who assigned the value, or the dictionary from which it is taken. </documentation>
 			<documentation>Type copied from basicTypes.xsd of GML 3 with documentation edited, for possible use outside the ServiceIdentification section of a service metadata document. </documentation>
 		</annotation>
 		<simpleContent>
diff --git a/pycsw/schemas/ogc/ows/1.0.0/owsAll.xsd b/pycsw/core/schemas/ogc/ows/1.1.0/owsAll.xsd
similarity index 58%
rename from pycsw/schemas/ogc/ows/1.0.0/owsAll.xsd
rename to pycsw/core/schemas/ogc/ows/1.1.0/owsAll.xsd
index f7cd634..a2fbd77 100644
--- a/pycsw/schemas/ogc/ows/1.0.0/owsAll.xsd
+++ b/pycsw/core/schemas/ogc/ows/1.1.0/owsAll.xsd
@@ -1,20 +1,23 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<schema targetNamespace="http://www.opengis.net/ows" 
-xmlns:ows="http://www.opengis.net/ows" 
+<schema targetNamespace="http://www.opengis.net/ows/1.1" 
+xmlns:ows="http://www.opengis.net/ows/1.1" 
 xmlns="http://www.w3.org/2001/XMLSchema" 
-elementFormDefault="qualified" version="1.0.0 2010-01-30" xml:lang="en">
+elementFormDefault="qualified" version="1.1.0.3" xml:lang="en">
 	<annotation>
-		<appinfo>owsAll.xsd 2010-01-30</appinfo>
+		<appinfo>owsAll.xsd</appinfo>
 		<documentation>This XML Schema Document includes and imports, directly and indirectly, all the XML Schemas defined by the OWS Common Implemetation Specification.
 		
 		OWS is an OGC Standard.
-		Copyright (c) 2005,2010 Open Geospatial Consortium, Inc. All Rights Reserved.
+		Copyright (c) 2006,2010 Open Geospatial Consortium.
 		To obtain additional rights of use, visit http://www.opengeospatial.org/legal/ .
 		</documentation>
 	</annotation>
 	<!-- ==============================================================
 		includes and imports
 	============================================================== -->
-	<include schemaLocation="owsGetCapabilities.xsd"/>
+	<include schemaLocation="owsGetResourceByID.xsd"/>
 	<include schemaLocation="owsExceptionReport.xsd"/>
+	<include schemaLocation="owsDomainType.xsd"/>
+	<include schemaLocation="owsContents.xsd"/>
+	<include schemaLocation="owsInputOutputData.xsd"/>
 </schema>
diff --git a/pycsw/schemas/ogc/ows/1.0.0/owsCommon.xsd b/pycsw/core/schemas/ogc/ows/1.1.0/owsCommon.xsd
similarity index 96%
rename from pycsw/schemas/ogc/ows/1.0.0/owsCommon.xsd
rename to pycsw/core/schemas/ogc/ows/1.1.0/owsCommon.xsd
index acf1d59..9de773a 100644
--- a/pycsw/schemas/ogc/ows/1.0.0/owsCommon.xsd
+++ b/pycsw/core/schemas/ogc/ows/1.1.0/owsCommon.xsd
@@ -1,21 +1,22 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<schema targetNamespace="http://www.opengis.net/ows" 
-xmlns:ows="http://www.opengis.net/ows" 
+<schema targetNamespace="http://www.opengis.net/ows/1.1" 
+xmlns:ows="http://www.opengis.net/ows/1.1" 
 xmlns:xlink="http://www.w3.org/1999/xlink" 
 xmlns="http://www.w3.org/2001/XMLSchema" 
-elementFormDefault="qualified" version="1.0.0 2010-01-30" xml:lang="en">
+elementFormDefault="qualified" version="1.1.0.3" xml:lang="en">
 	<annotation>
-		<appinfo>owsCommon.xsd 2010-01-30</appinfo>
+		<appinfo>owsCommon.xsd</appinfo>
 		<documentation>This XML Schema Document encodes various parameters and parameter types that can be used in OWS operation requests and responses.
 		
 		OWS is an OGC Standard.
-		Copyright (c) 2005,2010 Open Geospatial Consortium, Inc. All Rights Reserved.
+		Copyright (c) 2006,2010 Open Geospatial Consortium.
 		To obtain additional rights of use, visit http://www.opengeospatial.org/legal/ .
 		</documentation>
 	</annotation>
 	<!-- ==============================================================
 		includes and imports
 	============================================================== -->
+    <include schemaLocation="owsAll.xsd"/>
 	<import namespace="http://www.w3.org/1999/xlink" schemaLocation="../../../w3c/1999/xlink.xsd"/>
 	<!-- ==============================================================
 		elements and types
@@ -33,7 +34,9 @@ elementFormDefault="qualified" version="1.0.0 2010-01-30" xml:lang="en">
 		<annotation>
 			<documentation>Specification version for OWS operation. The string value shall contain one x.y.z "version" value (e.g., "2.1.3"). A version number shall contain three non-negative integers separated by decimal points, in the form "x.y.z". The integers y and z shall not exceed 99. Each version shall be for the Implementation Specification (document) and the associated XML Schemas to which requested operations will conform. An Implementation Specification version normally specifies XML  [...]
 		</annotation>
-		<restriction base="string"/>
+		<restriction base="string">
+			<pattern value="\d+\.\d?\d\.\d?\d"/>
+		</restriction>
 	</simpleType>
 	<!-- ========================================================== -->
 	<element name="Metadata" type="ows:MetadataType"/>
diff --git a/pycsw/core/schemas/ogc/ows/1.1.0/owsContents.xsd b/pycsw/core/schemas/ogc/ows/1.1.0/owsContents.xsd
new file mode 100644
index 0000000..5a1f47b
--- /dev/null
+++ b/pycsw/core/schemas/ogc/ows/1.1.0/owsContents.xsd
@@ -0,0 +1,87 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<schema targetNamespace="http://www.opengis.net/ows/1.1"
+xmlns:ows="http://www.opengis.net/ows/1.1"
+xmlns:xlink="http://www.w3.org/1999/xlink"
+xmlns="http://www.w3.org/2001/XMLSchema"
+elementFormDefault="qualified" version="1.1.0.3" xml:lang="en">
+	<annotation>
+		<appinfo>owsContents.xsd</appinfo>
+		<documentation>This XML Schema  Document encodes the typical Contents section of an OWS service metadata (Capabilities) document. This  Schema can be built upon to define the Contents section for a specific OWS. If the ContentsBaseType in this XML Schema cannot be restricted and extended to define the Contents section for a specific OWS, all other relevant parts defined in owsContents.xsd shall be used by the "ContentsType" in the wxsContents.xsd prepared for the specific OWS.
+		
+		OWS is an OGC Standard.
+		Copyright (c) 2006,2010 Open Geospatial Consortium.
+		To obtain additional rights of use, visit http://www.opengeospatial.org/legal/ .
+		</documentation>
+	</annotation>
+	<!-- ==============================================================
+		includes and imports
+	============================================================== -->
+	<include schemaLocation="owsAll.xsd"/>
+	<include schemaLocation="owsDataIdentification.xsd"/>
+	<!-- ==============================================================
+		elements and types
+	============================================================== -->
+	<complexType name="ContentsBaseType">
+		<annotation>
+			<documentation>Contents of typical Contents section of an OWS service metadata (Capabilities) document. This type shall be extended and/or restricted if needed for specific OWS use to include the specific metadata needed. </documentation>
+		</annotation>
+		<sequence>
+			<element ref="ows:DatasetDescriptionSummary" minOccurs="0" maxOccurs="unbounded">
+				<annotation>
+					<documentation>Unordered set of summary descriptions for the datasets available from this OWS server. This set shall be included unless another source is referenced and all this metadata is available from that source. </documentation>
+				</annotation>
+			</element>
+			<element ref="ows:OtherSource" minOccurs="0" maxOccurs="unbounded">
+				<annotation>
+					<documentation>Unordered set of references to other sources of metadata describing the coverage offerings available from this server. </documentation>
+				</annotation>
+			</element>
+		</sequence>
+	</complexType>
+	<!-- ===========================================================-->
+	<element name="OtherSource" type="ows:MetadataType">
+		<annotation>
+			<documentation>Reference to a source of metadata describing  coverage offerings available from this server. This  parameter can reference a catalogue server from which dataset metadata is available. This ability is expected to be used by servers with thousands or millions of datasets, for which searching a catalogue is more feasible than fetching a long Capabilities XML document. When no DatasetDescriptionSummaries are included, and one or more catalogue servers are referenced, this s [...]
+		</annotation>
+	</element>
+	<!-- ===========================================================-->
+	<element name="DatasetDescriptionSummary" type="ows:DatasetDescriptionSummaryBaseType"/>
+	<!-- ===========================================================-->
+	<complexType name="DatasetDescriptionSummaryBaseType">
+		<annotation>
+			<documentation>Typical dataset metadata in typical Contents section of an OWS service metadata (Capabilities) document. This type shall be extended and/or restricted if needed for specific OWS use, to include the specific Dataset  description metadata needed. </documentation>
+		</annotation>
+		<complexContent>
+			<extension base="ows:DescriptionType">
+				<sequence>
+					<element ref="ows:WGS84BoundingBox" minOccurs="0" maxOccurs="unbounded">
+						<annotation>
+							<documentation>Unordered list of zero or more minimum bounding rectangles surrounding coverage data, using the WGS 84 CRS with decimal degrees and longitude before latitude. If no WGS 84 bounding box is recorded for a coverage, any such bounding boxes recorded for a higher level in a hierarchy of datasets shall apply to this coverage. If WGS 84 bounding box(es) are recorded for a coverage, any such bounding boxes recorded for a higher level in a hierarchy of datasets shall be igno [...]
+						</annotation>
+					</element>
+					<element name="Identifier" type="ows:CodeType">
+						<annotation>
+							<documentation>Unambiguous identifier or name of this coverage, unique for this server. </documentation>
+						</annotation>
+					</element>
+					<element ref="ows:BoundingBox" minOccurs="0" maxOccurs="unbounded">
+						<annotation>
+							<documentation>Unordered list of zero or more minimum bounding rectangles surrounding coverage data, in AvailableCRSs.  Zero or more BoundingBoxes are  allowed in addition to one or more WGS84BoundingBoxes to allow more precise specification of the Dataset area in AvailableCRSs. These Bounding Boxes shall not use any CRS not listed as an AvailableCRS. However, an AvailableCRS can be listed without a corresponding Bounding Box. If no such bounding box is recorded for a coverage, an [...]
+						</annotation>
+					</element>
+					<element ref="ows:Metadata" minOccurs="0" maxOccurs="unbounded">
+						<annotation>
+							<documentation>Optional unordered list of additional metadata about this dataset. A list of optional metadata elements for this dataset description could be specified in the Implementation Specification for this service. </documentation>
+						</annotation>
+					</element>
+					<element ref="ows:DatasetDescriptionSummary" minOccurs="0" maxOccurs="unbounded">
+						<annotation>
+							<documentation>Metadata describing zero or more unordered subsidiary datasets available from this server. </documentation>
+						</annotation>
+					</element>
+				</sequence>
+			</extension>
+		</complexContent>
+	</complexType>
+	<!-- ===========================================================-->
+</schema>
diff --git a/pycsw/schemas/ogc/ows/1.0.0/owsDataIdentification.xsd b/pycsw/core/schemas/ogc/ows/1.1.0/owsDataIdentification.xsd
similarity index 73%
rename from pycsw/schemas/ogc/ows/1.0.0/owsDataIdentification.xsd
rename to pycsw/core/schemas/ogc/ows/1.1.0/owsDataIdentification.xsd
index e927185..b28c4c3 100644
--- a/pycsw/schemas/ogc/ows/1.0.0/owsDataIdentification.xsd
+++ b/pycsw/core/schemas/ogc/ows/1.1.0/owsDataIdentification.xsd
@@ -1,20 +1,22 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<schema targetNamespace="http://www.opengis.net/ows" 
-xmlns:ows="http://www.opengis.net/ows" 
+<schema targetNamespace="http://www.opengis.net/ows/1.1" 
+xmlns:ows="http://www.opengis.net/ows/1.1" 
+xmlns:xlink="http://www.w3.org/1999/xlink" 
 xmlns="http://www.w3.org/2001/XMLSchema" 
-elementFormDefault="qualified" version="1.0.0 2010-01-30" xml:lang="en">
+elementFormDefault="qualified" version="1.1.0.3" xml:lang="en">
 	<annotation>
-		<appinfo>owsDataIdentification.xsd 2010-01-30</appinfo>
-		<documentation>This XML Schema Document encodes the parts of the MD_DataIdentification class of ISO 19115 (OGC Abstract Specification Topic 11) which are expected to be used for most datasets. This Schema also encodes the parts of this class that are expected to be useful for other metadata. Both are expected to be used within the Contents section of OWS service metadata (Capabilities) documents.
+		<appinfo>owsDataIdentification.xsd</appinfo>
+		<documentation>This XML Schema Document encodes the parts of the MD_DataIdentification class of ISO 19115 (OGC Abstract Specification Topic 11) which are expected to be used for most datasets. This Schema also encodes the parts of this class that are expected to be useful for other metadata. Both may be used within the Contents section of OWS service metadata (Capabilities) documents.
 		
 		OWS is an OGC Standard.
-		Copyright (c) 2005,2010 Open Geospatial Consortium, Inc. All Rights Reserved.
+		Copyright (c) 2006,2010 Open Geospatial Consortium.
 		To obtain additional rights of use, visit http://www.opengeospatial.org/legal/ .
 		</documentation>
 	</annotation>
 	<!-- ==============================================================
 		includes and imports
 	============================================================== -->
+	<include schemaLocation="owsAll.xsd"/>
 	<include schemaLocation="owsCommon.xsd"/>
 	<include schemaLocation="ows19115subset.xsd"/>
 	<!-- ==============================================================
@@ -23,18 +25,19 @@ elementFormDefault="qualified" version="1.0.0 2010-01-30" xml:lang="en">
 	<complexType name="DescriptionType">
 		<annotation>
 			<documentation>Human-readable descriptive information for the object it is included within.
-This type shall be extended if needed for specific OWS use to include additional metadata for each type of information. This type shall not be restricted for a specific OWS to change the multiplicity (or optionality) of some elements. </documentation>
+This type shall be extended if needed for specific OWS use to include additional metadata for each type of information. This type shall not be restricted for a specific OWS to change the multiplicity (or optionality) of some elements.
+			If the xml:lang attribute is not included in a Title, Abstract or Keyword element, then no language is specified for that element unless specified by another means.  All Title, Abstract and Keyword elements in the same Description that share the same xml:lang attribute value represent the description of the parent object in that language. Multiple Title or Abstract elements shall not exist in the same Description with the same xml:lang attribute value unless otherwise specified. </doc [...]
 		</annotation>
 		<sequence>
-			<element ref="ows:Title" minOccurs="0"/>
-			<element ref="ows:Abstract" minOccurs="0"/>
+			<element ref="ows:Title" minOccurs="0" maxOccurs="unbounded"/>
+			<element ref="ows:Abstract" minOccurs="0" maxOccurs="unbounded"/>
 			<element ref="ows:Keywords" minOccurs="0" maxOccurs="unbounded"/>
 		</sequence>
 	</complexType>
 	<!-- ========================================================= -->
-	<complexType name="IdentificationType">
+	<complexType name="BasicIdentificationType">
 		<annotation>
-			<documentation>General metadata identifying and describing a set of data. This type shall be extended if needed for each specific OWS to include additional metadata for each type of dataset. If needed, this type should first be restricted for each specific OWS to change the multiplicity (or optionality) of some elements. </documentation>
+			<documentation>Basic metadata identifying and describing a set of data. </documentation>
 		</annotation>
 		<complexContent>
 			<extension base="ows:DescriptionType">
@@ -44,6 +47,23 @@ This type shall be extended if needed for specific OWS use to include additional
 							<documentation>Optional unique identifier or name of this dataset. </documentation>
 						</annotation>
 					</element>
+					<element ref="ows:Metadata" minOccurs="0" maxOccurs="unbounded">
+						<annotation>
+							<documentation>Optional unordered list of additional metadata about this data(set). A list of optional metadata elements for this data identification could be specified in the Implementation Specification for this service. </documentation>
+						</annotation>
+					</element>
+				</sequence>
+			</extension>
+		</complexContent>
+	</complexType>
+	<!-- ========================================================= -->
+	<complexType name="IdentificationType">
+		<annotation>
+			<documentation>Extended metadata identifying and describing a set of data. This type shall be extended if needed for each specific OWS to include additional metadata for each type of dataset. If needed, this type should first be restricted for each specific OWS to change the multiplicity (or optionality) of some elements. </documentation>
+		</annotation>
+		<complexContent>
+			<extension base="ows:BasicIdentificationType">
+				<sequence>
 					<element ref="ows:BoundingBox" minOccurs="0" maxOccurs="unbounded">
 						<annotation>
 							<documentation>Unordered list of zero or more bounding boxes whose union describes the extent of this dataset. </documentation>
@@ -59,11 +79,6 @@ This type shall be extended if needed for specific OWS use to include additional
 							<documentation>Unordered list of zero or more available coordinate reference systems. </documentation>
 						</annotation>
 					</element>
-					<element ref="ows:Metadata" minOccurs="0" maxOccurs="unbounded">
-						<annotation>
-							<documentation>Optional unordered list of additional metadata about this data(set). A list of optional metadata elements for this data identification could be specified in the Implementation Specification for this service. </documentation>
-						</annotation>
-					</element>
 				</sequence>
 			</extension>
 		</complexContent>
@@ -106,7 +121,8 @@ This type shall be extended if needed for specific OWS use to include additional
 	<!-- ========================================================== -->
 	<element name="Language" type="language">
 		<annotation>
-			<documentation>Identifier of a language used by the data(set) contents. This language identifier shall be as specified in IETF RFC 1766. When this element is omitted, the language used is not identified. </documentation>
+			<documentation>Identifier of a language used by the data(set) contents. This language identifier shall be as specified in IETF RFC 4646. When this element is omitted, the language used is not identified. </documentation>
 		</annotation>
 	</element>
+	<!-- ========================================================== -->
 </schema>
diff --git a/pycsw/core/schemas/ogc/ows/1.1.0/owsDomainType.xsd b/pycsw/core/schemas/ogc/ows/1.1.0/owsDomainType.xsd
new file mode 100644
index 0000000..7d9419c
--- /dev/null
+++ b/pycsw/core/schemas/ogc/ows/1.1.0/owsDomainType.xsd
@@ -0,0 +1,280 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<schema targetNamespace="http://www.opengis.net/ows/1.1" 
+xmlns:ows="http://www.opengis.net/ows/1.1" 
+xmlns:xlink="http://www.w3.org/1999/xlink" 
+xmlns="http://www.w3.org/2001/XMLSchema" 
+elementFormDefault="qualified" version="1.1.0.3" xml:lang="en">
+	<annotation>
+		<appinfo>owsDomainType.xsd</appinfo>
+		<documentation>This XML Schema Document encodes the allowed values (or domain) of a quantity, often for an input or output parameter to an OWS. Such a parameter is sometimes called a variable, quantity, literal, or typed literal. Such a parameter can use one of many data types, including double, integer, boolean, string, or URI. The allowed values can also be encoded for a quantity that is not explicit or not transferred, but is constrained by a server implementation.
+		
+		OWS is an OGC Standard.
+		Copyright (c) 2006,2010 Open Geospatial Consortium.
+		To obtain additional rights of use, visit http://www.opengeospatial.org/legal/ .
+		</documentation>
+	</annotation>
+	<!-- ==============================================================
+		includes and imports
+	============================================================== -->
+	<include schemaLocation="owsAll.xsd"/>
+	<include schemaLocation="owsCommon.xsd"></include>
+	<import namespace="http://www.w3.org/1999/xlink" schemaLocation="../../../w3c/1999/xlink.xsd"></import>
+	<!-- ==============================================================
+		elements and types
+	============================================================== -->
+	<complexType name="DomainType">
+		<annotation>
+			<documentation>Valid domain (or allowed set of values) of one quantity, with its name or identifier. </documentation>
+		</annotation>
+		<complexContent>
+			<extension base="ows:UnNamedDomainType">
+				<attribute name="name" type="string" use="required">
+					<annotation>
+						<documentation>Name or identifier of this quantity. </documentation>
+					</annotation>
+				</attribute>
+			</extension>
+		</complexContent>
+	</complexType>
+	<!-- ========================================================== -->
+	<complexType name="UnNamedDomainType">
+		<annotation>
+			<documentation>Valid domain (or allowed set of values) of one quantity, with needed metadata but without a quantity name or identifier. </documentation>
+		</annotation>
+		<sequence>
+			<group ref="ows:PossibleValues"/>
+			<element ref="ows:DefaultValue" minOccurs="0">
+				<annotation>
+					<documentation>Optional default value for this quantity, which should be included when this quantity has a default value. </documentation>
+				</annotation>
+			</element>
+			<element ref="ows:Meaning" minOccurs="0">
+				<annotation>
+					<documentation>Meaning metadata should be referenced or included for each quantity. </documentation>
+				</annotation>
+			</element>
+			<element ref="ows:DataType" minOccurs="0">
+				<annotation>
+					<documentation>This data type metadata should be referenced or included for each quantity. </documentation>
+				</annotation>
+			</element>
+			<group ref="ows:ValuesUnit" minOccurs="0">
+				<annotation>
+					<documentation>Unit of measure, which should be included when this set of PossibleValues has units or a more complete reference system. </documentation>
+				</annotation>
+			</group>
+			<element ref="ows:Metadata" minOccurs="0" maxOccurs="unbounded">
+				<annotation>
+					<documentation>Optional unordered list of other metadata about this quantity. A list of required and optional other metadata elements for this quantity should be specified in the Implementation Specification for this service. </documentation>
+				</annotation>
+			</element>
+		</sequence>
+	</complexType>
+	<!-- ========================================================== -->
+	<group name="PossibleValues">
+		<annotation>
+			<documentation>Specifies the possible values of this quantity. </documentation>
+		</annotation>
+			<choice>
+				<element ref="ows:AllowedValues"/>
+				<element ref="ows:AnyValue"/>
+				<element ref="ows:NoValues"/>
+				<element ref="ows:ValuesReference"/>
+			</choice>
+	</group>
+	<!-- ========================================================== -->
+	<element name="AnyValue">
+		<annotation>
+			<documentation>Specifies that any value is allowed for this parameter.</documentation>
+		</annotation>
+		<complexType></complexType>
+	</element>
+	<!-- ========================================================== -->
+	<element name="NoValues">
+		<annotation>
+			<documentation>Specifies that no values are allowed for this parameter or quantity.</documentation>
+		</annotation>
+		<complexType></complexType>
+	</element>
+	<!-- ========================================================== -->
+	<element name="ValuesReference">
+		<annotation>
+			<documentation>Reference to externally specified list of all the valid values and/or ranges of values for this quantity. (Informative: This element was simplified from the metaDataProperty element in GML 3.0.) </documentation>
+		</annotation>
+		<complexType>
+			<simpleContent>
+				<extension base="string">
+					<annotation>
+						<documentation>Human-readable name of the list of values provided by the referenced document. Can be empty string when this list has no name. </documentation>
+					</annotation>
+					<attribute ref="ows:reference" use="required">
+					</attribute>
+				</extension>
+			</simpleContent>
+		</complexType>
+	</element>
+	<!-- ========================================================== -->
+	<group name="ValuesUnit">
+		<annotation>
+			<documentation>Indicates that this quantity has units or a reference system, and identifies the unit or reference system used by the AllowedValues or ValuesReference. </documentation>
+		</annotation>
+			<choice>
+				<element ref="ows:UOM">
+					<annotation>
+						<documentation>Identifier of unit of measure of this set of values. Should be included then this set of values has units (and not a more complete reference system). </documentation>
+					</annotation>
+				</element>
+				<element ref="ows:ReferenceSystem">
+					<annotation>
+						<documentation>Identifier of reference system used by this set of values. Should be included then this set of values has a reference system (not just units). </documentation>
+					</annotation>
+				</element>
+			</choice>
+	</group>
+	<!-- ========================================================== -->
+	<!-- ========================================================== -->
+	<element name="AllowedValues">
+		<annotation>
+			<documentation>List of all the valid values and/or ranges of values for this quantity. For numeric quantities, signed values should be ordered from negative infinity to positive infinity. </documentation>
+		</annotation>
+		<complexType>
+			<choice maxOccurs="unbounded">
+				<element ref="ows:Value"/>
+				<element ref="ows:Range"/>
+			</choice>
+		</complexType>
+	</element>
+	<!-- ========================================================== -->
+	<element name="Value" type="ows:ValueType"></element>
+	<!-- ========================================================== -->
+	<complexType name="ValueType">
+		<annotation>
+			<documentation>A single value, encoded as a string. This type can be used for one value, for a spacing between allowed values, or for the default value of a parameter. </documentation>
+		</annotation>
+		<simpleContent>
+			<extension base="string"></extension>
+		</simpleContent>
+	</complexType>
+	<!-- ========================================================== -->
+	<element name="DefaultValue" type="ows:ValueType">
+		<annotation>
+			<documentation>The default value for a quantity for which multiple values are allowed. </documentation>
+		</annotation>
+	</element>
+	<!-- ========================================================== -->
+	<element name="Range" type="ows:RangeType"></element>
+	<!-- ========================================================== -->
+	<complexType name="RangeType">
+		<annotation>
+			<documentation>A range of values of a numeric parameter. This range can be continuous or discrete, defined by a fixed spacing between adjacent valid values. If the MinimumValue or MaximumValue is not included, there is no value limit in that direction. Inclusion of the specified minimum and maximum values in the range shall be defined by the rangeClosure. </documentation>
+		</annotation>
+		<sequence>
+			<element ref="ows:MinimumValue" minOccurs="0"></element>
+			<element ref="ows:MaximumValue" minOccurs="0"></element>
+			<element ref="ows:Spacing" minOccurs="0">
+				<annotation>
+					<documentation>Shall be included when the allowed values are NOT continuous in this range. Shall not be included when the allowed values are continuous in this range. </documentation>
+				</annotation>
+			</element>
+		</sequence>
+		<attribute ref="ows:rangeClosure" use="optional">
+			<annotation>
+				<documentation>Shall be included unless the default value applies. </documentation>
+			</annotation>
+		</attribute>
+	</complexType>
+	<!-- ========================================================== -->
+	<element name="MinimumValue" type="ows:ValueType">
+		<annotation>
+			<documentation>Minimum value of this numeric parameter. </documentation>
+		</annotation>
+	</element>
+	<!-- ========================================================== -->
+	<element name="MaximumValue" type="ows:ValueType">
+		<annotation>
+			<documentation>Maximum value of this numeric parameter. </documentation>
+		</annotation>
+	</element>
+	<!-- ========================================================== -->
+	<element name="Spacing" type="ows:ValueType">
+		<annotation>
+			<documentation>The regular distance or spacing between the allowed values in a range. </documentation>
+		</annotation>
+	</element>
+	<!-- ========================================================== -->
+	<attribute name="rangeClosure" default="closed">
+		<annotation>
+			<documentation>Specifies which of the minimum and maximum values are included in the range. Note that plus and minus infinity are considered closed bounds. </documentation>
+		</annotation>
+		<simpleType>
+			<restriction base="NMTOKENS">
+				<enumeration value="closed">
+					<annotation>
+						<documentation>The specified minimum and maximum values are included in this range. </documentation>
+					</annotation>
+				</enumeration>
+				<enumeration value="open">
+					<annotation>
+						<documentation>The specified minimum and maximum values are NOT included in this range. </documentation>
+					</annotation>
+				</enumeration>
+				<enumeration value="open-closed">
+					<annotation>
+						<documentation>The specified minimum value is NOT included in this range, and the specified maximum value IS included in this range. </documentation>
+					</annotation>
+				</enumeration>
+				<enumeration value="closed-open">
+					<annotation>
+						<documentation>The specified minimum value IS included in this range, and the specified maximum value is NOT included in this range. </documentation>
+					</annotation>
+				</enumeration>
+			</restriction>
+		</simpleType>
+	</attribute>
+	<!-- ========================================================== -->
+	<!-- ========================================================== -->
+	<complexType name="DomainMetadataType">
+		<annotation>
+			<documentation>References metadata about a quantity, and provides a name for this metadata. (Informative: This element was simplified from the metaDataProperty element in GML 3.0.) </documentation>
+		</annotation>
+		<simpleContent>
+			<extension base="string">
+				<annotation>
+					<documentation>Human-readable name of the metadata described by associated referenced document. </documentation>
+				</annotation>
+				<attribute ref="ows:reference" use="optional"/>
+			</extension>
+		</simpleContent>
+	</complexType>
+	<!-- ========================================================== -->
+	<attribute name="reference" type="anyURI">
+		<annotation>
+			<documentation>Reference to data or metadata recorded elsewhere, either external to this XML document or within it. Whenever practical, this attribute should be a URL from which this metadata can be electronically retrieved. Alternately, this attribute can reference a URN for well-known metadata. For example, such a URN could be a URN defined in the "ogc" URN namespace. </documentation>
+		</annotation>
+	</attribute>
+	<!-- ========================================================== -->
+	<element name="Meaning" type="ows:DomainMetadataType">
+		<annotation>
+			<documentation>Definition of the meaning or semantics of this set of values. This Meaning can provide more specific, complete, precise, machine accessible, and machine understandable semantics about this quantity, relative to other available semantic information. For example, other semantic information is often provided in "documentation" elements in XML Schemas or "description" elements in GML objects. </documentation>
+		</annotation>
+	</element>
+	<!-- ========================================================== -->
+	<element name="DataType" type="ows:DomainMetadataType">
+		<annotation>
+			<documentation>Definition of the data type of this set of values. In this case, the xlink:href attribute can reference a URN for a well-known data type. For example, such a URN could be a data type identification URN defined in the "ogc" URN namespace. </documentation>
+		</annotation>
+	</element>
+	<!-- ========================================================== -->
+	<element name="ReferenceSystem" type="ows:DomainMetadataType">
+		<annotation>
+			<documentation>Definition of the reference system used by this set of values, including the unit of measure whenever applicable (as is normal). In this case, the xlink:href attribute can reference a URN for a well-known reference system, such as for a coordinate reference system (CRS). For example, such a URN could be a CRS identification URN defined in the "ogc" URN namespace. </documentation>
+		</annotation>
+	</element>
+	<!-- ========================================================== -->
+	<element name="UOM" type="ows:DomainMetadataType">
+		<annotation>
+			<documentation>Definition of the unit of measure of this set of values. In this case, the xlink:href attribute can reference a URN for a well-known unit of measure (uom). For example, such a URN could be a UOM identification URN defined in the "ogc" URN namespace. </documentation>
+		</annotation>
+	</element>
+	<!-- ========================================================== -->
+</schema>
diff --git a/pycsw/schemas/ogc/ows/1.0.0/owsExceptionReport.xsd b/pycsw/core/schemas/ogc/ows/1.1.0/owsExceptionReport.xsd
similarity index 82%
rename from pycsw/schemas/ogc/ows/1.0.0/owsExceptionReport.xsd
rename to pycsw/core/schemas/ogc/ows/1.1.0/owsExceptionReport.xsd
index eda60e4..a0811cf 100644
--- a/pycsw/schemas/ogc/ows/1.0.0/owsExceptionReport.xsd
+++ b/pycsw/core/schemas/ogc/ows/1.1.0/owsExceptionReport.xsd
@@ -1,18 +1,23 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<schema targetNamespace="http://www.opengis.net/ows" 
-xmlns:ows="http://www.opengis.net/ows" 
+<schema targetNamespace="http://www.opengis.net/ows/1.1" 
+xmlns:ows="http://www.opengis.net/ows/1.1" 
 xmlns="http://www.w3.org/2001/XMLSchema" 
-elementFormDefault="qualified" version="1.0.0 2010-01-30" xml:lang="en">
+elementFormDefault="qualified" version="1.1.0 2011-02-07" xml:lang="en">
 	<annotation>
-		<appinfo>owsExceptionReport.xsd 2010-01-30</appinfo>
+		<appinfo>owsExceptionReport.xsd</appinfo>
 		<documentation>This XML Schema Document encodes the Exception Report response to all OWS operations.
 		
 		OWS is an OGC Standard.
-		Copyright (c) 2005,2010 Open Geospatial Consortium, Inc. All Rights Reserved.
+		Copyright (c) 2006,2010 Open Geospatial Consortium.
 		To obtain additional rights of use, visit http://www.opengeospatial.org/legal/ .
 		</documentation>
 	</annotation>
 	<!-- ==============================================================
+		includes and imports
+	============================================================== -->
+	<include schemaLocation="owsAll.xsd"/>
+	<import namespace="http://www.w3.org/XML/1998/namespace" schemaLocation="../../../w3c/2001/xml.xsd"/>
+	<!-- ==============================================================
 		elements and types
 	============================================================== -->
 	<element name="ExceptionReport">
@@ -27,14 +32,19 @@ elementFormDefault="qualified" version="1.0.0 2010-01-30" xml:lang="en">
 					</annotation>
 				</element>
 			</sequence>
-			<attribute name="version" type="string" use="required">
+			<attribute name="version" use="required">
 				<annotation>
 					<documentation>Specification version for OWS operation. The string value shall contain one x.y.z "version" value (e.g., "2.1.3"). A version number shall contain three non-negative integers separated by decimal points, in the form "x.y.z". The integers y and z shall not exceed 99. Each version shall be for the Implementation Specification (document) and the associated XML Schemas to which requested operations will conform. An Implementation Specification version normally specifies XM [...]
 				</annotation>
+				<simpleType>
+					<restriction base="string">
+						<pattern value="\d+\.\d?\d\.\d?\d"/>
+					</restriction>
+				</simpleType>
 			</attribute>
-			<attribute name="language" type="language" use="optional">
+			<attribute ref="xml:lang" use="optional">
 				<annotation>
-					<documentation>Identifier of the language used by all included exception text values. These language identifiers shall be as specified in IETF RFC 1766. When this attribute is omitted, the language used is not identified. </documentation>
+					<documentation>Identifier of the language used by all included exception text values. These language identifiers shall be as specified in IETF RFC 4646. When this attribute is omitted, the language used is not identified. </documentation>
 				</annotation>
 			</attribute>
 		</complexType>
diff --git a/pycsw/schemas/ogc/ows/1.0.0/owsGetCapabilities.xsd b/pycsw/core/schemas/ogc/ows/1.1.0/owsGetCapabilities.xsd
similarity index 90%
rename from pycsw/schemas/ogc/ows/1.0.0/owsGetCapabilities.xsd
rename to pycsw/core/schemas/ogc/ows/1.1.0/owsGetCapabilities.xsd
index aa01b44..4ab69a6 100644
--- a/pycsw/schemas/ogc/ows/1.0.0/owsGetCapabilities.xsd
+++ b/pycsw/core/schemas/ogc/ows/1.1.0/owsGetCapabilities.xsd
@@ -1,20 +1,21 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<schema targetNamespace="http://www.opengis.net/ows" 
-xmlns:ows="http://www.opengis.net/ows" 
+<schema targetNamespace="http://www.opengis.net/ows/1.1" 
+xmlns:ows="http://www.opengis.net/ows/1.1" 
 xmlns="http://www.w3.org/2001/XMLSchema" 
-elementFormDefault="qualified" version="1.0.0 2010-01-30" xml:lang="en">
+elementFormDefault="qualified" version="1.1.0.3" xml:lang="en">
 	<annotation>
-		<appinfo>owsGetCapabilities.xsd 2010-01-30</appinfo>
+		<appinfo>owsGetCapabilities.xsd</appinfo>
 		<documentation>This XML Schema Document defines the GetCapabilities operation request and response XML elements and types, which are common to all OWSs. This XML Schema shall be edited by each OWS, for example, to specify a specific value for the "service" attribute.
 		
 		OWS is an OGC Standard.
-		Copyright (c) 2005,2010 Open Geospatial Consortium, Inc. All Rights Reserved.
+		Copyright (c) 2006,2010 Open Geospatial Consortium.
 		To obtain additional rights of use, visit http://www.opengeospatial.org/legal/ .
 		</documentation>
 	</annotation>
 	<!-- ==============================================================
 		includes and imports
 	============================================================== -->
+	<include schemaLocation="owsAll.xsd"/>
 	<include schemaLocation="owsServiceIdentification.xsd"/>
 	<include schemaLocation="owsServiceProvider.xsd"/>
 	<include schemaLocation="owsOperationsMetadata.xsd"/>
@@ -31,7 +32,11 @@ elementFormDefault="qualified" version="1.0.0 2010-01-30" xml:lang="en">
 			<element ref="ows:OperationsMetadata" minOccurs="0"/>
 		</sequence>
 		<attribute name="version" type="ows:VersionType" use="required"/>
-		<attribute name="updateSequence" type="ows:UpdateSequenceType" use="optional"/>
+		<attribute name="updateSequence" type="ows:UpdateSequenceType" use="optional">
+			<annotation>
+				<documentation>Service metadata document version, having values that are "increased" whenever any change is made in service metadata document. Values are selected by each server, and are always opaque to clients. When not supported by server, server shall not return this attribute. </documentation>
+			</annotation>
+		</attribute>
 	</complexType>
 	<!-- =========================================================== -->
 	<element name="GetCapabilities" type="ows:GetCapabilitiesType"/>
diff --git a/pycsw/core/schemas/ogc/ows/1.1.0/owsGetResourceByID.xsd b/pycsw/core/schemas/ogc/ows/1.1.0/owsGetResourceByID.xsd
new file mode 100644
index 0000000..553601a
--- /dev/null
+++ b/pycsw/core/schemas/ogc/ows/1.1.0/owsGetResourceByID.xsd
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<schema targetNamespace="http://www.opengis.net/ows/1.1" 
+xmlns:ows="http://www.opengis.net/ows/1.1" 
+xmlns="http://www.w3.org/2001/XMLSchema" 
+elementFormDefault="qualified" version="1.1.0.3" xml:lang="en">
+	<annotation>
+		<appinfo>owsGetResourceByID.xsd</appinfo>
+		<documentation>This XML Schema Document encodes the GetResourceByID operation request message. This typical operation is specified as a base for profiling in specific OWS specifications. For information on the allowed changes and limitations in such profiling, see Subclause 9.4.1 of the OWS Common specification.
+		
+		OWS is an OGC Standard.
+		Copyright (c) 2006,2010 Open Geospatial Consortium.
+		To obtain additional rights of use, visit http://www.opengeospatial.org/legal/ .
+		</documentation>
+	</annotation>
+	<!-- ==============================================================
+		includes and imports
+	============================================================== -->
+	<include schemaLocation="owsAll.xsd"/>
+	<include schemaLocation="owsDataIdentification.xsd"></include>
+	<include schemaLocation="owsGetCapabilities.xsd"></include>
+	<!-- ==============================================================
+		elements and types
+	============================================================== -->
+	<element name="Resource">
+		<annotation>
+			<documentation>XML encoded GetResourceByID operation response. The complexType used by this element shall be specified by each specific OWS.  </documentation>
+		</annotation>
+	</element>
+	<!-- =========================================================== -->
+	<element name="GetResourceByID" type="ows:GetResourceByIdType"></element>
+	<!-- =========================================================== -->
+	<complexType name="GetResourceByIdType">
+		<annotation>
+			<documentation>Request to a service to perform the GetResourceByID operation. This operation allows a client to retrieve one or more identified resources, including datasets and resources that describe datasets or parameters. In this XML encoding, no "request" parameter is included, since the element name specifies the specific operation. </documentation>
+		</annotation>
+		<sequence>
+			<element name="ResourceID" type="anyURI" minOccurs="0" maxOccurs="unbounded">
+				<annotation>
+					<documentation>Unordered list of zero or more resource identifiers. These identifiers can be listed in the Contents section of the service metadata (Capabilities) document. For more information on this parameter, see Subclause 9.4.2.1 of the OWS Common specification. </documentation>
+				</annotation>
+			</element>
+			<element ref="ows:OutputFormat" minOccurs="0">
+				<annotation>
+					<documentation>Optional reference to the data format to be used for response to this operation request. This element shall be included when multiple output formats are available for the selected resource(s), and the client desires a format other than the specified default, if any. </documentation>
+				</annotation>
+			</element>
+		</sequence>
+		<attribute name="service" type="ows:ServiceType" use="required"></attribute>
+		<attribute name="version" type="ows:VersionType" use="required"></attribute>
+	</complexType>
+	<!-- =========================================================== -->
+</schema>
diff --git a/pycsw/core/schemas/ogc/ows/1.1.0/owsInputOutputData.xsd b/pycsw/core/schemas/ogc/ows/1.1.0/owsInputOutputData.xsd
new file mode 100644
index 0000000..7bdd52b
--- /dev/null
+++ b/pycsw/core/schemas/ogc/ows/1.1.0/owsInputOutputData.xsd
@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<schema targetNamespace="http://www.opengis.net/ows/1.1" 
+xmlns:ows="http://www.opengis.net/ows/1.1" 
+xmlns="http://www.w3.org/2001/XMLSchema" 
+elementFormDefault="qualified" version="1.1.0.3" xml:lang="en">
+	<annotation>
+		<appinfo>owsInputOutputData.xsd</appinfo>
+		<documentation>This XML Schema Document specifies types and elements for input and output of operation data, allowing including multiple data items with each data item either included or referenced. The contents of each type and element specified here can be restricted and/or extended for each use in a specific OWS specification.
+		
+		OWS is an OGC Standard.
+		Copyright (c) 2006,2010 Open Geospatial Consortium.
+		To obtain additional rights of use, visit http://www.opengeospatial.org/legal/ .
+		</documentation>
+	</annotation>
+	<!-- ==============================================================
+		includes and imports
+	============================================================== -->
+	<include schemaLocation="owsAll.xsd"/>
+	<include schemaLocation="owsManifest.xsd"/>
+	<!-- ==========================================================
+		Types and elements
+	    ========================================================== -->
+	<element name="OperationResponse" type="ows:ManifestType">
+		<annotation>
+			<documentation>Response from an OWS operation, allowing including multiple output data items with each item either included or referenced. This OperationResponse element, or an element using the ManifestType with a more specific element name, shall be used whenever applicable for responses from OWS operations. </documentation>
+			<documentation>This element is specified for use where the ManifestType contents are needed for an operation response, but the Manifest element name is not fully applicable. This element or the ManifestType shall be used instead of using the ows:ReferenceType proposed in OGC 04-105. </documentation>
+		</annotation>
+	</element>
+	<!-- ========================================================== -->
+	<element name="InputData" type="ows:ManifestType">
+		<annotation>
+			<documentation>Input data in a XML-encoded OWS operation request, allowing including multiple data items with each data item either included or referenced. This InputData element, or an element using the ManifestType with a more-specific element name (TBR), shall be used whenever applicable within XML-encoded OWS operation requests. </documentation>
+		</annotation>
+	</element>
+	<!-- ========================================================== -->
+	<element name="ServiceReference" type="ows:ServiceReferenceType" substitutionGroup="ows:Reference"/>
+	<!-- ========================================================== -->
+	<complexType name="ServiceReferenceType">
+		<annotation>
+			<documentation>Complete reference to a remote resource that needs to be retrieved from an OWS using an XML-encoded operation request. This element shall be used, within an InputData or Manifest element that is used for input data, when that input data needs to be retrieved from another web service using a XML-encoded OWS operation request. This element shall not be used for local payload input data or for requesting the resource from a web server using HTTP Get. </documentation>
+		</annotation>
+		<complexContent>
+			<extension base="ows:ReferenceType">
+				<choice>
+					<element name="RequestMessage" type="anyType">
+						<annotation>
+							<documentation>The XML-encoded operation request message to be sent to request this input data from another web server using HTTP Post. </documentation>
+						</annotation>
+					</element>
+					<element name="RequestMessageReference" type="anyURI">
+						<annotation>
+							<documentation>Reference to the XML-encoded operation request message to be sent to request this input data from another web server using HTTP Post. The referenced message shall be attached to the same message (using the cid scheme), or be accessible using a URL. </documentation>
+						</annotation>
+					</element>
+				</choice>
+			</extension>
+		</complexContent>
+	</complexType>
+	<!-- ========================================================== -->
+</schema>
diff --git a/pycsw/core/schemas/ogc/ows/1.1.0/owsManifest.xsd b/pycsw/core/schemas/ogc/ows/1.1.0/owsManifest.xsd
new file mode 100644
index 0000000..15942e6
--- /dev/null
+++ b/pycsw/core/schemas/ogc/ows/1.1.0/owsManifest.xsd
@@ -0,0 +1,125 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<schema targetNamespace="http://www.opengis.net/ows/1.1" 
+xmlns:ows="http://www.opengis.net/ows/1.1" 
+xmlns:xlink="http://www.w3.org/1999/xlink" 
+xmlns="http://www.w3.org/2001/XMLSchema" 
+elementFormDefault="qualified" version="1.1.0.3" xml:lang="en">
+	<annotation>
+		<appinfo>owsManifest.xsd</appinfo>
+		<documentation>This XML Schema Document specifies types and elements for document or resource references and for package manifests that contain multiple references. The contents of each type and element specified here can be restricted and/or extended for each use in a specific OWS specification.
+		
+		OWS is an OGC Standard.
+		Copyright (c) 2006,2010 Open Geospatial Consortium.
+		To obtain additional rights of use, visit http://www.opengeospatial.org/legal/ .
+		</documentation>
+	</annotation>
+	<!-- ==============================================================
+		includes and imports
+	============================================================== -->
+	<include schemaLocation="owsDataIdentification.xsd"/>
+	<import namespace="http://www.w3.org/1999/xlink" schemaLocation="../../../w3c/1999/xlink.xsd"/>
+	<!-- ==========================================================
+		Types and elements
+	    ========================================================== -->
+	<element name="AbstractReferenceBase" type="ows:AbstractReferenceBaseType" abstract="true"/>
+	<!-- ========================================================== -->
+	<complexType name="AbstractReferenceBaseType">
+		<annotation>
+			<documentation> Base for a reference to a remote or local resource. </documentation>
+			<documentation>This type contains only a restricted and annotated set of the attributes from the xlink:simpleAttrs attributeGroup. </documentation>
+		</annotation>
+		<attribute name="type" type="string" fixed="simple" form="qualified"/>
+		<attribute ref="xlink:href" use="required">
+				<annotation>
+					<documentation>Reference to a remote resource or local payload. A remote resource is typically addressed by a URL. For a local payload (such as a multipart mime message), the xlink:href must start with the prefix cid:. </documentation>
+			</annotation>
+		</attribute>
+		<attribute ref="xlink:role" use="optional">
+			<annotation>
+				<documentation>Reference to a resource that describes the role of this reference. When no value is supplied, no particular role value is to be inferred. </documentation>
+			</annotation>
+		</attribute>
+		<attribute ref="xlink:arcrole" use="optional">
+			<annotation>
+				<documentation>Although allowed, this attribute is not expected to be useful in this application of xlink:simpleAttrs. </documentation>
+			</annotation>
+		</attribute>
+		<attribute ref="xlink:title" use="optional">
+			<annotation>
+				<documentation>Describes the meaning of the referenced resource in a human-readable fashion. </documentation>
+			</annotation>
+		</attribute>
+		<attribute ref="xlink:show" use="optional">
+			<annotation>
+				<documentation>Although allowed, this attribute is not expected to be useful in this application of xlink:simpleAttrs. </documentation>
+			</annotation>
+		</attribute>
+		<attribute ref="xlink:actuate" use="optional">
+			<annotation>
+				<documentation>Although allowed, this attribute is not expected to be useful in this application of xlink:simpleAttrs. </documentation>
+			</annotation>
+		</attribute>
+	</complexType>
+	<!-- ========================================================== -->
+	<element name="Reference" type="ows:ReferenceType" substitutionGroup="ows:AbstractReferenceBase"/>
+	<!-- ========================================================== -->
+	<complexType name="ReferenceType">
+		<annotation>
+			<documentation>Complete reference to a remote or local resource, allowing including metadata about that resource. </documentation>
+		</annotation>
+		<complexContent>
+			<extension base="ows:AbstractReferenceBaseType">
+				<sequence>
+					<element ref="ows:Identifier" minOccurs="0">
+						<annotation>
+							<documentation>Optional unique identifier of the referenced resource. </documentation>
+						</annotation>
+					</element>
+					<element ref="ows:Abstract" minOccurs="0" maxOccurs="unbounded"/>
+					<element name="Format" type="ows:MimeType" minOccurs="0">
+						<annotation>
+							<documentation>The format of the referenced resource. This element is omitted when the mime type is indicated in the http header of the reference. </documentation>
+						</annotation>
+					</element>
+					<element ref="ows:Metadata" minOccurs="0" maxOccurs="unbounded">
+						<annotation>
+							<documentation>Optional unordered list of additional metadata about this resource. A list of optional metadata elements for this ReferenceType could be specified in the Implementation Specification for each use of this type in a specific OWS. </documentation>
+						</annotation>
+					</element>
+				</sequence>
+			</extension>
+		</complexContent>
+	</complexType>
+	<!-- =========================================================== -->
+	<!-- =========================================================== -->
+	<element name="ReferenceGroup" type="ows:ReferenceGroupType"/>
+	<!-- =========================================================== -->
+	<complexType name="ReferenceGroupType">
+		<annotation>
+			<documentation>Logical group of one or more references to remote and/or local resources, allowing including metadata about that group. A Group can be used instead of a Manifest that can only contain one group. </documentation>
+		</annotation>
+		<complexContent>
+			<extension base="ows:BasicIdentificationType">
+				<sequence>
+					<element ref="ows:AbstractReferenceBase" maxOccurs="unbounded"/>
+				</sequence>
+			</extension>
+		</complexContent>
+	</complexType>
+	<!-- =========================================================== -->
+	<element name="Manifest" type="ows:ManifestType"/>
+	<!-- =========================================================== -->
+	<complexType name="ManifestType">
+		<annotation>
+			<documentation>Unordered list of one or more groups of references to remote and/or local resources. </documentation>
+		</annotation>
+		<complexContent>
+			<extension base="ows:BasicIdentificationType">
+				<sequence>
+					<element ref="ows:ReferenceGroup" maxOccurs="unbounded"/>
+				</sequence>
+			</extension>
+		</complexContent>
+	</complexType>
+	<!-- ========================================================== -->
+</schema>
diff --git a/pycsw/schemas/ogc/ows/1.0.0/owsOperationsMetadata.xsd b/pycsw/core/schemas/ogc/ows/1.1.0/owsOperationsMetadata.xsd
similarity index 79%
rename from pycsw/schemas/ogc/ows/1.0.0/owsOperationsMetadata.xsd
rename to pycsw/core/schemas/ogc/ows/1.1.0/owsOperationsMetadata.xsd
index b7dcc88..4861a90 100644
--- a/pycsw/schemas/ogc/ows/1.0.0/owsOperationsMetadata.xsd
+++ b/pycsw/core/schemas/ogc/ows/1.1.0/owsOperationsMetadata.xsd
@@ -1,22 +1,24 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<schema targetNamespace="http://www.opengis.net/ows" 
-xmlns:ows="http://www.opengis.net/ows" 
+<schema targetNamespace="http://www.opengis.net/ows/1.1" 
+xmlns:ows="http://www.opengis.net/ows/1.1" 
 xmlns="http://www.w3.org/2001/XMLSchema" 
-elementFormDefault="qualified" version="1.0.0 2010-01-30" xml:lang="en">
+elementFormDefault="qualified" version="1.1.0.3" xml:lang="en">
 	<annotation>
-		<appinfo>owsOperationsMetadata.xsd 2010-01-30</appinfo>
+		<appinfo>owsOperationsMetadata.xsd</appinfo>
 		<documentation>This XML Schema Document encodes the basic contents of the "OperationsMetadata" section of the GetCapabilities operation response, also known as the Capabilities XML document.
-		
-		OWS is an OGC Standard.
-		Copyright (c) 2005,2010 Open Geospatial Consortium, Inc. All Rights Reserved.
-		To obtain additional rights of use, visit http://www.opengeospatial.org/legal/ .
+			
+			OWS is an OGC Standard.
+			Copyright (c) 2006,2010 Open Geospatial Consortium.
+			To obtain additional rights of use, visit http://www.opengeospatial.org/legal/ .
 		</documentation>
 	</annotation>
 	<!-- ==============================================================
 		includes and imports
 	============================================================== -->
+	<include schemaLocation="owsAll.xsd"/>
 	<include schemaLocation="owsCommon.xsd"/>
 	<include schemaLocation="ows19115subset.xsd"/>
+	<include schemaLocation="owsDomainType.xsd"/>
 	<!-- ==============================================================
 		elements and types
 	============================================================== -->
@@ -136,26 +138,4 @@ elementFormDefault="qualified" version="1.0.0 2010-01-30" xml:lang="en">
 		</complexContent>
 	</complexType>
 	<!-- ========================================================== -->
-	<complexType name="DomainType">
-		<annotation>
-			<documentation>Valid domain (or set of values) of one parameter or other quantity used by this server. A non-parameter quantity may not be explicitly represented in the server software. (Informative: An example is the outputFormat parameter of a WFS. Each WFS server should provide a Parameter element for the outputFormat parameter that lists the supported output formats, such as GML2, GML3, etc. as the allowed "Value" elements.) </documentation>
-		</annotation>
-		<sequence>
-			<element name="Value" type="string" maxOccurs="unbounded">
-				<annotation>
-					<documentation>Unordered list of all the valid values for this parameter or other quantity. For those parameters that contain a list or sequence of values, these values shall be for individual values in the list. The allowed set of values and the allowed server restrictions on that set of values shall be specified in the Implementation Specification for this service. </documentation>
-				</annotation>
-			</element>
-			<element ref="ows:Metadata" minOccurs="0" maxOccurs="unbounded">
-				<annotation>
-					<documentation>Optional unordered list of additional metadata about this parameter. A list of required and optional metadata elements for this domain should be specified in the Implementation Specification for this service. (Informative: This metadata might specify the meanings of the valid values.) </documentation>
-				</annotation>
-			</element>
-		</sequence>
-		<attribute name="name" type="string" use="required">
-			<annotation>
-				<documentation>Name or identifier of this parameter or other quantity. </documentation>
-			</annotation>
-		</attribute>
-	</complexType>
 </schema>
diff --git a/pycsw/schemas/ogc/ows/1.0.0/owsServiceIdentification.xsd b/pycsw/core/schemas/ogc/ows/1.1.0/owsServiceIdentification.xsd
similarity index 74%
rename from pycsw/schemas/ogc/ows/1.0.0/owsServiceIdentification.xsd
rename to pycsw/core/schemas/ogc/ows/1.1.0/owsServiceIdentification.xsd
index 9c91c81..c15fcfa 100644
--- a/pycsw/schemas/ogc/ows/1.0.0/owsServiceIdentification.xsd
+++ b/pycsw/core/schemas/ogc/ows/1.1.0/owsServiceIdentification.xsd
@@ -1,20 +1,21 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<schema targetNamespace="http://www.opengis.net/ows" 
-xmlns:ows="http://www.opengis.net/ows" 
+<schema targetNamespace="http://www.opengis.net/ows/1.1" 
+xmlns:ows="http://www.opengis.net/ows/1.1" 
 xmlns="http://www.w3.org/2001/XMLSchema" 
-elementFormDefault="qualified" version="1.0.0 2010-01-30" xml:lang="en">
+elementFormDefault="qualified" version="1.1.0.3" xml:lang="en">
 	<annotation>
-		<appinfo>owsServiceIdentification.xsd 2010-01-30</appinfo>
-		<documentation>This XML Schema Document encodes the common "ServiceIdentification" section of the GetCapabilities operation response, known as the Capabilities XML document. This section encodes the SV_ServiceIdentification class of ISO 19119 (OGC Abstract Specification Topic 12).
+		<appinfo>owsServiceIdentification.xsd</appinfo>
+		<documentation>This XML Schema Document encodes the common "ServiceIdentification" section of the GetCapabilities operation response, known as the Capabilities XML document. This section encodes the SV_ServiceIdentification class of ISO 19119 (OGC Abstract Specification Topic 12). 
 		
 		OWS is an OGC Standard.
-		Copyright (c) 2005,2010 Open Geospatial Consortium, Inc. All Rights Reserved.
+		Copyright (c) 2006,2010 Open Geospatial Consortium.
 		To obtain additional rights of use, visit http://www.opengeospatial.org/legal/ .
 		</documentation>
 	</annotation>
 	<!-- ==============================================================
 		includes and imports
 	============================================================== -->
+	<include schemaLocation="owsAll.xsd"/>
 	<include schemaLocation="owsDataIdentification.xsd"/>
 	<!-- ==============================================================
 		elements and types
@@ -37,6 +38,11 @@ elementFormDefault="qualified" version="1.0.0 2010-01-30" xml:lang="en">
 								<documentation>Unordered list of one or more versions of this service type implemented by this server. This information is not adequate for version negotiation, and shall not be used for that purpose. </documentation>
 							</annotation>
 						</element>
+						<element name="Profile" type="anyURI" minOccurs="0" maxOccurs="unbounded">
+							<annotation>
+								<documentation>Unordered list of identifiers of Application Profiles that are implemented by this server. This element should be included for each specified application profile implemented by this server. The identifier value should be specified by each Application Profile. If this element is omitted, no meaning is implied. </documentation>
+							</annotation>
+						</element>
 						<element ref="ows:Fees" minOccurs="0">
 							<annotation>
 								<documentation>If this element is omitted, no meaning is implied. </documentation>
@@ -44,7 +50,7 @@ elementFormDefault="qualified" version="1.0.0 2010-01-30" xml:lang="en">
 						</element>
 						<element ref="ows:AccessConstraints" minOccurs="0" maxOccurs="unbounded">
 							<annotation>
-								<documentation>Unordered list of access constraints applied to assure the protection of privacy or intellectual property, and any other restrictions on retrieving or using data from or otherwise using this server. The reserved value NONE (case insensitive) shall be used to mean no access constraints are imposed. If this element is omitted, no meaning is implied. </documentation>
+								<documentation>Unordered list of access constraints applied to assure the protection of privacy or intellectual property, and any other restrictions on retrieving or using data from or otherwise using this server. The reserved value NONE (case insensitive) shall be used to mean no access constraints are imposed. When this element is omitted, no meaning is implied. </documentation>
 							</annotation>
 						</element>
 					</sequence>
diff --git a/pycsw/schemas/ogc/ows/1.0.0/owsServiceProvider.xsd b/pycsw/core/schemas/ogc/ows/1.1.0/owsServiceProvider.xsd
similarity index 83%
rename from pycsw/schemas/ogc/ows/1.0.0/owsServiceProvider.xsd
rename to pycsw/core/schemas/ogc/ows/1.1.0/owsServiceProvider.xsd
index 17c3dba..bce3e64 100644
--- a/pycsw/schemas/ogc/ows/1.0.0/owsServiceProvider.xsd
+++ b/pycsw/core/schemas/ogc/ows/1.1.0/owsServiceProvider.xsd
@@ -1,20 +1,22 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<schema targetNamespace="http://www.opengis.net/ows" 
-xmlns:ows="http://www.opengis.net/ows" 
+<schema targetNamespace="http://www.opengis.net/ows/1.1" 
+xmlns:ows="http://www.opengis.net/ows/1.1" 
+xmlns:xlink="http://www.w3.org/1999/xlink" 
 xmlns="http://www.w3.org/2001/XMLSchema" 
-elementFormDefault="qualified" version="1.0.0 2010-01-30" xml:lang="en">
+elementFormDefault="qualified" version="1.1.0.3" xml:lang="en">
 	<annotation>
-		<appinfo>owsServiceProvider.xsd 2010-01-30</appinfo>
-		<documentation>This XML Schema Document encodes the common "ServiceProvider" section of the GetCapabilities operation response, known as the Capabilities XML document. This section encodes the SV_ServiceProvider class of ISO 19119 (OGC Abstract Specification Topic 12).
+		<appinfo>owsServiceProvider.xsd</appinfo>
+		<documentation>This XML Schema Document encodes the common "ServiceProvider" section of the GetCapabilities operation response, known as the Capabilities XML document. This section encodes the SV_ServiceProvider class of ISO 19119 (OGC Abstract Specification Topic 12). 
 		
 		OWS is an OGC Standard.
-		Copyright (c) 2005,2010 Open Geospatial Consortium, Inc. All Rights Reserved.
+		Copyright (c) 2006,2010 Open Geospatial Consortium.
 		To obtain additional rights of use, visit http://www.opengeospatial.org/legal/ .
 		</documentation>
 	</annotation>
 	<!-- ==============================================================
 		includes and imports
 	============================================================== -->
+	<include schemaLocation="owsAll.xsd"/>
 	<include schemaLocation="ows19115subset.xsd"/>
 	<!-- ==============================================================
 		elements and types
diff --git a/pycsw/core/schemas/ogc/ows/2.0/ows19115subset.xsd b/pycsw/core/schemas/ogc/ows/2.0/ows19115subset.xsd
new file mode 100644
index 0000000..b4506ad
--- /dev/null
+++ b/pycsw/core/schemas/ogc/ows/2.0/ows19115subset.xsd
@@ -0,0 +1,364 @@
+<?xml version="1.0" encoding="utf-8"?>
+<schema targetNamespace="http://www.opengis.net/ows/2.0"
+        xmlns:ows="http://www.opengis.net/ows/2.0"
+        xmlns:xlink="http://www.w3.org/1999/xlink"
+        xmlns="http://www.w3.org/2001/XMLSchema"
+        elementFormDefault="qualified"
+        version="2.0.2"
+        xml:lang="en">
+  <annotation>
+    <appinfo>ows19115subset.xsd</appinfo>
+    <documentation>This XML Schema Document encodes the parts of ISO 19115 used
+    by the common "ServiceIdentification" and "ServiceProvider" sections of the
+    GetCapabilities operation response, known as the service metadata XML
+    document. The parts encoded here are the MD_Keywords, CI_ResponsibleParty,
+    and related classes. The UML package prefixes were omitted from XML names,
+    and the XML element names were all capitalized, for consistency with other
+    OWS Schemas. This document also provides a simple coding of text in
+    multiple languages, simplified from Annex J of ISO 19115.
+		
+    OWS is an OGC Standard.
+    Copyright (c) 2009 Open Geospatial Consortium.
+    To obtain additional rights of use, visit http://www.opengeospatial.org/legal/ .
+    </documentation>
+  </annotation>
+  
+  <!-- ==============================================================
+                includes and imports
+        ============================================================== -->
+  <include schemaLocation="owsAll.xsd"/>
+  <import namespace="http://www.w3.org/1999/xlink"
+          schemaLocation="../../../w3c/1999/xlink.xsd" />
+  <import namespace="http://www.w3.org/XML/1998/namespace"
+          schemaLocation="../../../w3c/2001/xml.xsd" />
+  <!-- ==============================================================
+                elements and types
+        ============================================================== -->
+  <complexType name="LanguageStringType">
+    <annotation>
+      <documentation>Text string with the language of the string identified as
+      recommended in the XML 1.0 W3C Recommendation, section
+      2.12.</documentation>
+    </annotation>
+    <simpleContent>
+      <extension base="string">
+        <attribute ref="xml:lang"
+                   use="optional" />
+      </extension>
+    </simpleContent>
+  </complexType>
+  <!-- =========================================================== -->
+  <element name="Title"
+           type="ows:LanguageStringType">
+    <annotation>
+      <documentation>Title of this resource, normally used for display to
+      humans.</documentation>
+    </annotation>
+  </element>
+  <!-- =========================================================== -->
+  <element name="Abstract"
+           type="ows:LanguageStringType">
+    <annotation>
+      <documentation>Brief narrative description of this resource, normally
+      used for display to humans.</documentation>
+    </annotation>
+  </element>
+  <!-- =========================================================== -->
+  <element name="Keywords"
+           type="ows:KeywordsType" />
+  <!-- =========================================================== -->
+  <complexType name="KeywordsType">
+    <annotation>
+      <documentation>Unordered list of one or more commonly used or formalised
+      word(s) or phrase(s) used to describe the subject. When needed, the
+      optional "type" can name the type of the associated list of keywords
+      that shall all have the same type. Also when needed, the codeSpace
+      attribute of that "type" can reference the type name authority and/or
+      thesaurus. If the xml:lang attribute is not included in a Keyword
+      element, then no language is specified for that element unless specified
+      by another means. All Keyword elements in the same Keywords element that
+      share the same xml:lang attribute value represent different keywords in
+      that language.</documentation>
+      <documentation>For OWS use, the optional thesaurusName element was
+      omitted as being complex information that could be referenced by the
+      codeSpace attribute of the Type element.</documentation>
+    </annotation>
+    <sequence>
+      <element name="Keyword"
+               type="ows:LanguageStringType"
+               maxOccurs="unbounded" />
+      <element name="Type"
+               type="ows:CodeType"
+               minOccurs="0" />
+    </sequence>
+  </complexType>
+  <!-- =========================================================== -->
+  <complexType name="CodeType">
+    <annotation>
+      <documentation>Name or code with an (optional) authority. If the
+      codeSpace attribute is present, its value shall reference a dictionary,
+      thesaurus, or authority for the name or code, such as the organisation
+      who assigned the value, or the dictionary from which it is
+      taken.</documentation>
+      <documentation>Type copied from basicTypes.xsd of GML 3 with
+      documentation edited, for possible use outside the ServiceIdentification
+      section of a service metadata document.</documentation>
+    </annotation>
+    <simpleContent>
+      <extension base="string">
+        <attribute name="codeSpace"
+                   type="anyURI"
+                   use="optional" />
+      </extension>
+    </simpleContent>
+  </complexType>
+  <!-- =========================================================== -->
+  <element name="PointOfContact"
+           type="ows:ResponsiblePartyType">
+    <annotation>
+      <documentation>Identification of, and means of communication with,
+      person(s) responsible for the resource(s).</documentation>
+      <documentation>For OWS use in the ServiceProvider section of a service
+      metadata document, the optional organizationName element was removed,
+      since this type is always used with the ProviderName element which
+      provides that information. The optional individualName element was made
+      mandatory, since either the organizationName or individualName element
+      is mandatory. The mandatory "role" element was changed to optional,
+      since no clear use of this information is known in the ServiceProvider
+      section.</documentation>
+    </annotation>
+  </element>
+  <!-- =========================================================== -->
+  <complexType name="ResponsiblePartyType">
+    <annotation>
+      <documentation>Identification of, and means of communication with,
+      person responsible for the server. At least one of IndividualName,
+      OrganisationName, or PositionName shall be included.</documentation>
+    </annotation>
+    <sequence>
+      <element ref="ows:IndividualName"
+               minOccurs="0" />
+      <element ref="ows:OrganisationName"
+               minOccurs="0" />
+      <element ref="ows:PositionName"
+               minOccurs="0" />
+      <element ref="ows:ContactInfo"
+               minOccurs="0" />
+      <element ref="ows:Role" />
+    </sequence>
+  </complexType>
+  <!-- =========================================================== -->
+  <!-- =========================================================== -->
+  <complexType name="ResponsiblePartySubsetType">
+    <annotation>
+      <documentation>Identification of, and means of communication with,
+      person responsible for the server.</documentation>
+      <documentation>For OWS use in the ServiceProvider section of a service
+      metadata document, the optional organizationName element was removed,
+      since this type is always used with the ProviderName element which
+      provides that information. The mandatory "role" element was changed to
+      optional, since no clear use of this information is known in the
+      ServiceProvider section.</documentation>
+    </annotation>
+    <sequence>
+      <element ref="ows:IndividualName"
+               minOccurs="0" />
+      <element ref="ows:PositionName"
+               minOccurs="0" />
+      <element ref="ows:ContactInfo"
+               minOccurs="0" />
+      <element ref="ows:Role"
+               minOccurs="0" />
+    </sequence>
+  </complexType>
+  <!-- =========================================================== -->
+  <element name="IndividualName"
+           type="string">
+    <annotation>
+      <documentation>Name of the responsible person: surname, given name,
+      title separated by a delimiter.</documentation>
+    </annotation>
+  </element>
+  <!-- =========================================================== -->
+  <element name="OrganisationName"
+           type="string">
+    <annotation>
+      <documentation>Name of the responsible organization.</documentation>
+    </annotation>
+  </element>
+  <!-- =========================================================== -->
+  <element name="PositionName"
+           type="string">
+    <annotation>
+      <documentation>Role or position of the responsible
+      person.</documentation>
+    </annotation>
+  </element>
+  <!-- =========================================================== -->
+  <element name="Role"
+           type="ows:CodeType">
+    <annotation>
+      <documentation>Function performed by the responsible party. Possible
+      values of this Role shall include the values and the meanings listed in
+      Subclause B.5.5 of ISO 19115:2003.</documentation>
+    </annotation>
+  </element>
+  <!-- =========================================================== -->
+  <element name="ContactInfo"
+           type="ows:ContactType">
+    <annotation>
+      <documentation>Address of the responsible party.</documentation>
+    </annotation>
+  </element>
+  <!-- =========================================================== -->
+  <complexType name="ContactType">
+    <annotation>
+      <documentation>Information required to enable contact with the
+      responsible person and/or organization.</documentation>
+      <documentation>For OWS use in the service metadata document, the
+      optional hoursOfService and contactInstructions elements were retained,
+      as possibly being useful in the ServiceProvider section.</documentation>
+    </annotation>
+    <sequence>
+      <element name="Phone"
+               type="ows:TelephoneType"
+               minOccurs="0">
+        <annotation>
+          <documentation>Telephone numbers at which the organization or
+          individual may be contacted.</documentation>
+        </annotation>
+      </element>
+      <element name="Address"
+               type="ows:AddressType"
+               minOccurs="0">
+        <annotation>
+          <documentation>Physical and email address at which the organization
+          or individual may be contacted.</documentation>
+        </annotation>
+      </element>
+      <element name="OnlineResource"
+               type="ows:OnlineResourceType"
+               minOccurs="0">
+        <annotation>
+          <documentation>On-line information that can be used to contact the
+          individual or organization. OWS specifics: The xlink:href attribute
+          in the xlink:simpleAttrs attribute group shall be used to reference
+          this resource. Whenever practical, the xlink:href attribute with
+          type anyURI should be a URL from which more contact information can
+          be electronically retrieved. The xlink:title attribute with type
+          "string" can be used to name this set of information. The other
+          attributes in the xlink:simpleAttrs attribute group should not be
+          used.</documentation>
+        </annotation>
+      </element>
+      <element name="HoursOfService"
+               type="string"
+               minOccurs="0">
+        <annotation>
+          <documentation>Time period (including time zone) when individuals
+          can contact the organization or individual.</documentation>
+        </annotation>
+      </element>
+      <element name="ContactInstructions"
+               type="string"
+               minOccurs="0">
+        <annotation>
+          <documentation>Supplemental instructions on how or when to contact
+          the individual or organization.</documentation>
+        </annotation>
+      </element>
+    </sequence>
+  </complexType>
+  <!-- =========================================================== -->
+  <complexType name="OnlineResourceType">
+    <annotation>
+      <documentation>Reference to on-line resource from which data can be
+      obtained.</documentation>
+      <documentation>For OWS use in the service metadata document, the
+      CI_OnlineResource class was XML encoded as the attributeGroup
+      "xlink:simpleAttrs", as used in GML.</documentation>
+    </annotation>
+    <attributeGroup ref="xlink:simpleAttrs" />
+  </complexType>
+  <!-- ========================================================== -->
+  <complexType name="TelephoneType">
+    <annotation>
+      <documentation>Telephone numbers for contacting the responsible
+      individual or organization.</documentation>
+    </annotation>
+    <sequence>
+      <element name="Voice"
+               type="string"
+               minOccurs="0"
+               maxOccurs="unbounded">
+        <annotation>
+          <documentation>Telephone number by which individuals can speak to
+          the responsible organization or individual.</documentation>
+        </annotation>
+      </element>
+      <element name="Facsimile"
+               type="string"
+               minOccurs="0"
+               maxOccurs="unbounded">
+        <annotation>
+          <documentation>Telephone number of a facsimile machine for the
+          responsible organization or individual.</documentation>
+        </annotation>
+      </element>
+    </sequence>
+  </complexType>
+  <!-- =========================================================== -->
+  <complexType name="AddressType">
+    <annotation>
+      <documentation>Location of the responsible individual or
+      organization.</documentation>
+    </annotation>
+    <sequence>
+      <element name="DeliveryPoint"
+               type="string"
+               minOccurs="0"
+               maxOccurs="unbounded">
+        <annotation>
+          <documentation>Address line for the location.</documentation>
+        </annotation>
+      </element>
+      <element name="City"
+               type="string"
+               minOccurs="0">
+        <annotation>
+          <documentation>City of the location.</documentation>
+        </annotation>
+      </element>
+      <element name="AdministrativeArea"
+               type="string"
+               minOccurs="0">
+        <annotation>
+          <documentation>State or province of the location.</documentation>
+        </annotation>
+      </element>
+      <element name="PostalCode"
+               type="string"
+               minOccurs="0">
+        <annotation>
+          <documentation>ZIP or other postal code.</documentation>
+        </annotation>
+      </element>
+      <element name="Country"
+               type="string"
+               minOccurs="0">
+        <annotation>
+          <documentation>Country of the physical address.</documentation>
+        </annotation>
+      </element>
+      <element name="ElectronicMailAddress"
+               type="string"
+               minOccurs="0"
+               maxOccurs="unbounded">
+        <annotation>
+          <documentation>Address of the electronic mailbox of the responsible
+          organization or individual.</documentation>
+        </annotation>
+      </element>
+    </sequence>
+  </complexType>
+</schema>
diff --git a/pycsw/core/schemas/ogc/ows/2.0/owsAdditionalParameters.xsd b/pycsw/core/schemas/ogc/ows/2.0/owsAdditionalParameters.xsd
new file mode 100644
index 0000000..8e91265
--- /dev/null
+++ b/pycsw/core/schemas/ogc/ows/2.0/owsAdditionalParameters.xsd
@@ -0,0 +1,114 @@
+<?xml version="1.0" encoding="utf-8"?>
+<schema targetNamespace="http://www.opengis.net/ows/2.0"
+        xmlns:ows="http://www.opengis.net/ows/2.0"
+        xmlns="http://www.w3.org/2001/XMLSchema"
+        elementFormDefault="qualified"
+        version="2.0.2"
+        xml:lang="en">
+  <annotation>
+    <appinfo>owsAdditionalParameters.xsd</appinfo>
+    <documentation>This XML Schema Document encodes a new AdditionalParameters
+    element that contains one or more AdditionalParameter elements, which each
+    contain a specific parameter name and one or more values of that parameter.
+    This AdditionalParameters element is substitutable for ows:Metadata,
+    anywhere that element is allowed. The document also encodes a new nilValue
+    element of a newly defined NilValue type that allows the specification of
+    a nilReason attribute.
+
+   OWS is an OGC Standard.
+   Copyright (c) 2009 Open Geospatial Consortium.
+   To obtain additional rights of use, visit http://www.opengeospatial.org/legal/ .
+    </documentation>
+  </annotation>
+
+  <!-- ==============================================================
+                includes and imports
+        ============================================================== -->
+  <include schemaLocation="owsAll.xsd"/>
+  <include schemaLocation="owsCommon.xsd" />
+  <include schemaLocation="ows19115subset.xsd" />
+  <include schemaLocation="owsDomainType.xsd" />
+  
+  <!-- ==============================================================
+                elements and types
+        ============================================================== -->
+  <element name="AdditionalParameters"
+           type="ows:AdditionalParametersType"
+           substitutionGroup="ows:Metadata">
+    <annotation>
+      <documentation>Unordered list of one or more
+      AdditionalParameters.</documentation>
+    </annotation>
+  </element>
+  <!-- ========================================================== -->
+  <complexType name="AdditionalParametersBaseType">
+    <complexContent>
+      <restriction base="ows:MetadataType">
+        <sequence>
+          <element ref="ows:AdditionalParameter" />
+        </sequence>
+      </restriction>
+    </complexContent>
+  </complexType>
+  <!-- ========================================================== -->
+  <complexType name="AdditionalParametersType">
+    <complexContent>
+      <extension base="ows:AdditionalParametersBaseType">
+        <sequence>
+          <element ref="ows:AdditionalParameter"
+                   minOccurs="0"
+                   maxOccurs="unbounded" />
+        </sequence>
+      </extension>
+    </complexContent>
+  </complexType>
+  <!-- ========================================================== -->
+  <element name="AdditionalParameter"
+           substitutionGroup="ows:AbstractMetaData">
+    <annotation>
+      <documentation>One additional metadata parameter.</documentation>
+    </annotation>
+    <complexType>
+      <sequence>
+        <element name="Name"
+                 type="ows:CodeType">
+          <annotation>
+            <documentation>Name or identifier of this AdditionalParameter,
+            unique for this OGC Web Service.</documentation>
+          </annotation>
+        </element>
+        <element name="Value"
+                 type="anyType"
+                 maxOccurs="unbounded">
+          <annotation>
+            <documentation>Unordered list of one or more values of this
+            AdditionalParameter.</documentation>
+          </annotation>
+        </element>
+      </sequence>
+    </complexType>
+  </element>
+  <!-- ========================================================== -->
+  <element name="nilValue"
+           type="ows:NilValueType" />
+  <!-- ========================================================== -->
+  <complexType name="NilValueType">
+    <annotation>
+      <documentation>The value used (e.g. -255) to represent a nil value with
+      optional nilReason and codeSpace attributes.</documentation>
+    </annotation>
+    <simpleContent>
+      <extension base="ows:CodeType">
+        <attribute name="nilReason"
+                   type="anyURI"
+                   use="optional">
+          <annotation>
+            <documentation>An anyURI value which refers to a resource that
+            describes the reason for the nil value</documentation>
+          </annotation>
+        </attribute>
+      </extension>
+    </simpleContent>
+  </complexType>
+  <!-- ========================================================== -->
+</schema>
diff --git a/pycsw/core/schemas/ogc/ows/2.0/owsAll.xsd b/pycsw/core/schemas/ogc/ows/2.0/owsAll.xsd
new file mode 100644
index 0000000..8063899
--- /dev/null
+++ b/pycsw/core/schemas/ogc/ows/2.0/owsAll.xsd
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<schema targetNamespace="http://www.opengis.net/ows/2.0"
+        xmlns:ows="http://www.opengis.net/ows/2.0"
+        xmlns="http://www.w3.org/2001/XMLSchema"
+        elementFormDefault="qualified"
+        version="2.0.2"
+        xml:lang="en">
+  <annotation>
+    <appinfo>owsAll.xsd</appinfo>
+    <documentation>This XML Schema Document includes and imports, directly or
+      indirectly, all the XML Schemas defined by the OWS Common Implemetation
+      Specification.
+      
+      OWS is an OGC Standard.
+      Copyright (c) 2009 Open Geospatial Consortium.
+      To obtain additional rights of use, visit http://www.opengeospatial.org/legal/ .
+    </documentation>
+  </annotation>
+
+  <!-- ==============================================================
+		includes and imports
+	============================================================== -->
+  <include schemaLocation="owsGetResourceByID.xsd"/>
+  <include schemaLocation="owsExceptionReport.xsd"/>
+  <include schemaLocation="owsDomainType.xsd"/>
+  <include schemaLocation="owsContents.xsd"/>
+  <include schemaLocation="owsInputOutputData.xsd"/>
+  <include schemaLocation="owsAdditionalParameters.xsd"/>
+</schema>
diff --git a/pycsw/core/schemas/ogc/ows/2.0/owsCommon.xsd b/pycsw/core/schemas/ogc/ows/2.0/owsCommon.xsd
new file mode 100644
index 0000000..4c24e2e
--- /dev/null
+++ b/pycsw/core/schemas/ogc/ows/2.0/owsCommon.xsd
@@ -0,0 +1,275 @@
+<?xml version="1.0" encoding="utf-8"?>
+<schema targetNamespace="http://www.opengis.net/ows/2.0"
+        xmlns:ows="http://www.opengis.net/ows/2.0"
+        xmlns:xlink="http://www.w3.org/1999/xlink"
+        xmlns="http://www.w3.org/2001/XMLSchema"
+        elementFormDefault="qualified"
+        version="2.0.2"
+        xml:lang="en">
+  <annotation>
+    <appinfo>owsCommon.xsd</appinfo>
+    <documentation>This XML Schema Document encodes various parameters and
+    parameter types that can be used in OWS operation requests and responses.
+    
+    OWS is an OGC Standard.
+    Copyright (c) 2009 Open Geospatial Consortium.
+    To obtain additional rights of use, visit http://www.opengeospatial.org/legal/
+    </documentation>
+  </annotation>
+  <!-- ==============================================================
+                includes and imports
+        ============================================================== -->
+  <include schemaLocation="owsAll.xsd"/>
+  <import namespace="http://www.w3.org/1999/xlink"
+          schemaLocation="../../../w3c/1999/xlink.xsd" />
+
+  <!-- ==============================================================
+                elements and types
+        ============================================================== -->
+  <simpleType name="MimeType">
+    <annotation>
+      <documentation>XML encoded identifier of a standard MIME type, possibly
+      a parameterized MIME type.</documentation>
+    </annotation>
+    <restriction base="string">
+      <pattern value="(application|audio|image|text|video|message|multipart|model)/.+(;\s*.+=.+)*" />
+    </restriction>
+  </simpleType>
+  <!-- ========================================================= -->
+  <simpleType name="VersionType">
+    <annotation>
+      <documentation>Specification version for OWS operation. The string value
+      shall contain one x.y.z "version" value (e.g., "2.1.3"). A version
+      number shall contain three non-negative integers separated by decimal
+      points, in the form "x.y.z". The integers y and z shall not exceed 99.
+      Each version shall be for the Implementation Specification (document)
+      and the associated XML Schemas to which requested operations will
+      conform. An Implementation Specification version normally specifies XML
+      Schemas against which an XML encoded operation response must conform and
+      should be validated. See Version negotiation subclause for more
+      information.</documentation>
+    </annotation>
+    <restriction base="string">
+      <pattern value="\d+\.\d?\d\.\d?\d" />
+    </restriction>
+  </simpleType>
+  <!-- ========================================================== -->
+  <element name="Metadata"
+           type="ows:MetadataType" />
+  <!-- ========================================================== -->
+  <complexType name="MetadataType">
+    <annotation>
+      <documentation>This element either references or contains more metadata
+      about the element that includes this element. To reference metadata
+      stored remotely, at least the xlinks:href attribute in xlink:simpleAttrs
+      shall be included. Either at least one of the attributes in
+      xlink:simpleAttrs or a substitute for the AbstractMetaData element shall
+      be included, but not both. An Implementation Specification can restrict
+      the contents of this element to always be a reference or always contain
+      metadata. (Informative: This element was adapted from the
+      metaDataProperty element in GML 3.0.)</documentation>
+    </annotation>
+    <sequence>
+      <element ref="ows:AbstractMetaData"
+               minOccurs="0" />
+    </sequence>
+    <attributeGroup ref="xlink:simpleAttrs">
+      <annotation>
+        <documentation>Reference to metadata recorded elsewhere, either
+        external to this XML document or within it. Whenever practical, the
+        xlink:href attribute with type anyURI should include a URL from which
+        this metadata can be electronically retrieved.</documentation>
+      </annotation>
+    </attributeGroup>
+    <attribute name="about"
+               type="anyURI"
+               use="optional">
+      <annotation>
+        <documentation>Optional reference to the aspect of the element which
+        includes this "metadata" element that this metadata provides more
+        information about.</documentation>
+      </annotation>
+    </attribute>
+  </complexType>
+  <!-- ========================================================== -->
+  <element name="AbstractMetaData"
+           abstract="true">
+    <annotation>
+      <documentation>Abstract element containing more metadata about the
+      element that includes the containing "metadata" element. A specific
+      server implementation, or an Implementation Specification, can define
+      concrete elements in the AbstractMetaData substitution
+      group.</documentation>
+    </annotation>
+  </element>
+  <!-- ========================================================== -->
+  <!-- ========================================================== -->
+  <element name="BoundingBox"
+           type="ows:BoundingBoxType" />
+  <!-- =========================================================== -->
+  <complexType name="BoundingBoxType">
+    <annotation>
+      <documentation>XML encoded minimum rectangular bounding box (or region)
+      parameter, surrounding all the associated data.</documentation>
+      <documentation>This type is adapted from the EnvelopeType of GML 3.1,
+      with modified contents and documentation for encoding a MINIMUM size box
+      SURROUNDING all associated data.</documentation>
+    </annotation>
+    <sequence>
+      <element name="LowerCorner"
+               type="ows:PositionType">
+        <annotation>
+          <documentation>Position of the bounding box corner at which the
+          value of each coordinate normally is the algebraic minimum within
+          this bounding box. In some cases, this position is normally
+          displayed at the top, such as the top left for some image
+          coordinates. For more information, see Subclauses 10.2.5 and
+          C.13.</documentation>
+        </annotation>
+      </element>
+      <element name="UpperCorner"
+               type="ows:PositionType">
+        <annotation>
+          <documentation>Position of the bounding box corner at which the
+          value of each coordinate normally is the algebraic maximum within
+          this bounding box. In some cases, this position is normally
+          displayed at the bottom, such as the bottom right for some image
+          coordinates. For more information, see Subclauses 10.2.5 and
+          C.13.</documentation>
+        </annotation>
+      </element>
+    </sequence>
+    <attribute name="crs"
+               type="anyURI"
+               use="optional">
+      <annotation>
+        <documentation>Usually references the definition of a CRS, as
+        specified in [OGC Topic 2]. Such a CRS definition can be XML encoded
+        using the gml:CoordinateReferenceSystemType in [GML 3.1]. For well
+        known references, it is not required that a CRS definition exist at
+        the location the URI points to. If no anyURI value is included, the
+        applicable CRS must be either: a) Specified outside the bounding box,
+        but inside a data structure that includes this bounding box, as
+        specified for a specific OWS use of this bounding box type. b) Fixed
+        and specified in the Implementation Specification for a specific OWS
+        use of the bounding box type.</documentation>
+      </annotation>
+    </attribute>
+    <attribute name="dimensions"
+               type="positiveInteger"
+               use="optional">
+      <annotation>
+        <documentation>The number of dimensions in this CRS (the length of a
+        coordinate sequence in this use of the PositionType). This number is
+        specified by the CRS definition, but can also be specified
+        here.</documentation>
+      </annotation>
+    </attribute>
+  </complexType>
+  <!-- =========================================================== -->
+  <simpleType name="PositionType">
+    <annotation>
+      <documentation>Position instances hold the coordinates of a position in
+      a coordinate reference system (CRS) referenced by the related "crs"
+      attribute or elsewhere. For an angular coordinate axis that is
+      physically continuous for multiple revolutions, but whose recorded
+      values can be discontinuous, special conditions apply when the bounding
+      box is continuous across the value discontinuity: a) If the bounding box
+      is continuous clear around this angular axis, then ordinate values of
+      minus and plus infinity shall be used. b) If the bounding box is
+      continuous across the value discontinuity but is not continuous clear
+      around this angular axis, then some non-normal value can be used if
+      specified for a specific OWS use of the BoundingBoxType. For more
+      information, see Subclauses 10.2.5 and C.13.</documentation>
+      <documentation>This type is adapted from DirectPositionType and
+      doubleList of GML 3.1. The adaptations include omission of all the
+      attributes, since the needed information is included in the
+      BoundingBoxType.</documentation>
+    </annotation>
+    <list itemType="double" />
+  </simpleType>
+  <!-- =========================================================== -->
+  <element name="WGS84BoundingBox"
+           type="ows:WGS84BoundingBoxType"
+           substitutionGroup="ows:BoundingBox" />
+  <!-- =========================================================== -->
+  <complexType name="WGS84BoundingBoxType">
+    <annotation>
+      <documentation>XML encoded minimum rectangular bounding box (or region)
+      parameter, surrounding all the associated data. This box is specialized
+      for use with the 2D WGS 84 coordinate reference system with decimal
+      values of longitude and latitude.</documentation>
+      <documentation>This type is adapted from the general BoundingBoxType,
+      with modified contents and documentation for use with the 2D WGS 84
+      coordinate reference system.</documentation>
+    </annotation>
+    <complexContent>
+      <restriction base="ows:BoundingBoxType">
+        <sequence>
+          <element name="LowerCorner"
+                   type="ows:PositionType2D">
+            <annotation>
+              <documentation>Position of the bounding box corner at which the
+              values of longitude and latitude normally are the algebraic
+              minimums within this bounding box. For more information, see
+              Subclauses 10.4.5 and C.13.</documentation>
+            </annotation>
+          </element>
+          <element name="UpperCorner"
+                   type="ows:PositionType2D">
+            <annotation>
+              <documentation>Position of the bounding box corner at which the
+              values of longitude and latitude normally are the algebraic
+              minimums within this bounding box. For more information, see
+              Subclauses 10.4.5 and C.13.</documentation>
+            </annotation>
+          </element>
+        </sequence>
+        <attribute name="crs"
+                   type="anyURI"
+                   use="optional"
+                   fixed="urn:ogc:def:crs:OGC:2:84">
+          <annotation>
+            <documentation>This attribute can be included when considered
+            useful. When included, this attribute shall reference the 2D WGS
+            84 coordinate reference system with longitude before latitude and
+            decimal values of longitude and latitude.</documentation>
+          </annotation>
+        </attribute>
+        <attribute name="dimensions"
+                   type="positiveInteger"
+                   use="optional"
+                   fixed="2">
+          <annotation>
+            <documentation>The number of dimensions in this CRS (the length of
+            a coordinate sequence in this use of the PositionType). This
+            number is specified by the CRS definition, but can also be
+            specified here.</documentation>
+          </annotation>
+        </attribute>
+      </restriction>
+    </complexContent>
+  </complexType>
+  <!-- =========================================================== -->
+  <simpleType name="PositionType2D">
+    <annotation>
+      <documentation>Two-dimensional position instances hold the longitude and
+      latitude coordinates of a position in the 2D WGS 84 coordinate reference
+      system. The longitude value shall be listed first, followed by the
+      latitude value, both in decimal degrees. Latitude values shall range
+      from -90 to +90 degrees, and longitude values shall normally range from
+      -180 to +180 degrees. For the longitude axis, special conditions apply
+      when the bounding box is continuous across the +/- 180 degrees meridian
+      longitude value discontinuity: a) If the bounding box is continuous
+      clear around the Earth, then longitude values of minus and plus infinity
+      shall be used. b) If the bounding box is continuous across the value
+      discontinuity but is not continuous clear around the Earth, then some
+      non-normal value can be used if specified for a specific OWS use of the
+      WGS84BoundingBoxType. For more information, see Subclauses 10.4.5 and
+      C.13.</documentation>
+    </annotation>
+    <restriction base="ows:PositionType">
+      <length value="2" />
+    </restriction>
+  </simpleType>
+</schema>
diff --git a/pycsw/core/schemas/ogc/ows/2.0/owsContents.xsd b/pycsw/core/schemas/ogc/ows/2.0/owsContents.xsd
new file mode 100644
index 0000000..6719e10
--- /dev/null
+++ b/pycsw/core/schemas/ogc/ows/2.0/owsContents.xsd
@@ -0,0 +1,163 @@
+<?xml version="1.0" encoding="utf-8"?>
+<schema targetNamespace="http://www.opengis.net/ows/2.0"
+        xmlns:ows="http://www.opengis.net/ows/2.0"
+        xmlns:xlink="http://www.w3.org/1999/xlink"
+        xmlns="http://www.w3.org/2001/XMLSchema"
+        elementFormDefault="qualified"
+        version="2.0.2"
+        xml:lang="en">
+  <annotation>
+    <appinfo>owsContents.xsd</appinfo>
+    <documentation>This XML Schema Document encodes the typical Contents
+    section of an OWS service metadata (Capabilities) document. This Schema
+    can be built upon to define the Contents section for a specific OWS. If
+    the ContentsBaseType in this XML Schema cannot be restricted and extended
+    to define the Contents section for a specific OWS, all other relevant
+    parts defined in owsContents.xsd shall be used by the "ContentsType" in
+    the wxsContents.xsd prepared for the specific OWS.
+    
+    OWS is an OGC Standard.
+    Copyright (c) 2009 Open Geospatial Consortium.
+    To obtain additional rights of use, visit http://www.opengeospatial.org/legal/
+    </documentation>
+  </annotation>
+  <!-- ==============================================================
+                includes and imports
+        ============================================================== -->
+  <include schemaLocation="owsAll.xsd"/>
+  <include schemaLocation="owsDataIdentification.xsd" />
+  
+  <!-- ==============================================================
+                elements and types
+        ============================================================== -->
+  <complexType name="ContentsBaseType">
+    <annotation>
+      <documentation>Contents of typical Contents section of an OWS service
+      metadata (Capabilities) document. This type shall be extended and/or
+      restricted if needed for specific OWS use to include the specific
+      metadata needed.</documentation>
+    </annotation>
+    <sequence>
+      <element ref="ows:DatasetDescriptionSummary"
+               minOccurs="0"
+               maxOccurs="unbounded">
+        <annotation>
+          <documentation>Unordered set of summary descriptions for the
+          datasets available from this OWS server. This set shall be included
+          unless another source is referenced and all this metadata is
+          available from that source.</documentation>
+        </annotation>
+      </element>
+      <element ref="ows:OtherSource"
+               minOccurs="0"
+               maxOccurs="unbounded">
+        <annotation>
+          <documentation>Unordered set of references to other sources of
+          metadata describing the coverage offerings available from this
+          server.</documentation>
+        </annotation>
+      </element>
+    </sequence>
+  </complexType>
+  <!-- ===========================================================-->
+  <element name="OtherSource"
+           type="ows:MetadataType">
+    <annotation>
+      <documentation>Reference to a source of metadata describing coverage
+      offerings available from this server. This parameter can reference a
+      catalogue server from which dataset metadata is available. This ability
+      is expected to be used by servers with thousands or millions of
+      datasets, for which searching a catalogue is more feasible than fetching
+      a long Capabilities XML document. When no DatasetDescriptionSummaries
+      are included, and one or more catalogue servers are referenced, this set
+      of catalogues shall contain current metadata summaries for all the
+      datasets currently available from this OWS server, with the metadata for
+      each such dataset referencing this OWS server.</documentation>
+    </annotation>
+  </element>
+  <!-- ===========================================================-->
+  <element name="DatasetDescriptionSummary"
+           type="ows:DatasetDescriptionSummaryBaseType" />
+  <!-- ===========================================================-->
+  <complexType name="DatasetDescriptionSummaryBaseType">
+    <annotation>
+      <documentation>Typical dataset metadata in typical Contents section of
+      an OWS service metadata (Capabilities) document. This type shall be
+      extended and/or restricted if needed for specific OWS use, to include
+      the specific Dataset description metadata needed.</documentation>
+    </annotation>
+    <complexContent>
+      <extension base="ows:DescriptionType">
+        <sequence>
+          <element ref="ows:WGS84BoundingBox"
+                   minOccurs="0"
+                   maxOccurs="unbounded">
+            <annotation>
+              <documentation>Unordered list of zero or more minimum bounding
+              rectangles surrounding coverage data, using the WGS 84 CRS with
+              decimal degrees and longitude before latitude. If no WGS 84
+              bounding box is recorded for a coverage, any such bounding boxes
+              recorded for a higher level in a hierarchy of datasets shall
+              apply to this coverage. If WGS 84 bounding box(es) are recorded
+              for a coverage, any such bounding boxes recorded for a higher
+              level in a hierarchy of datasets shall be ignored. For each
+              lowest-level coverage in a hierarchy, at least one applicable
+              WGS84BoundingBox shall be either recorded or inherited, to
+              simplify searching for datasets that might overlap a specified
+              region. If multiple WGS 84 bounding boxes are included, this
+              shall be interpreted as the union of the areas of these bounding
+              boxes.</documentation>
+            </annotation>
+          </element>
+          <element name="Identifier"
+                   type="ows:CodeType">
+            <annotation>
+              <documentation>Unambiguous identifier or name of this coverage,
+              unique for this server.</documentation>
+            </annotation>
+          </element>
+          <element ref="ows:BoundingBox"
+                   minOccurs="0"
+                   maxOccurs="unbounded">
+            <annotation>
+              <documentation>Unordered list of zero or more minimum bounding
+              rectangles surrounding coverage data, in AvailableCRSs. Zero or
+              more BoundingBoxes are allowed in addition to one or more
+              WGS84BoundingBoxes to allow more precise specification of the
+              Dataset area in AvailableCRSs. These Bounding Boxes shall not
+              use any CRS not listed as an AvailableCRS. However, an
+              AvailableCRS can be listed without a corresponding Bounding Box.
+              If no such bounding box is recorded for a coverage, any such
+              bounding boxes recorded for a higher level in a hierarchy of
+              datasets shall apply to this coverage. If such bounding box(es)
+              are recorded for a coverage, any such bounding boxes recorded
+              for a higher level in a hierarchy of datasets shall be ignored.
+              If multiple bounding boxes are included with the same CRS, this
+              shall be interpreted as the union of the areas of these bounding
+              boxes.</documentation>
+            </annotation>
+          </element>
+          <element ref="ows:Metadata"
+                   minOccurs="0"
+                   maxOccurs="unbounded">
+            <annotation>
+              <documentation>Optional unordered list of additional metadata
+              about this dataset. A list of optional metadata elements for
+              this dataset description could be specified in the
+              Implementation Specification for this service.</documentation>
+            </annotation>
+          </element>
+          <element ref="ows:DatasetDescriptionSummary"
+                   minOccurs="0"
+                   maxOccurs="unbounded">
+            <annotation>
+              <documentation>Metadata describing zero or more unordered
+              subsidiary datasets available from this server.</documentation>
+            </annotation>
+          </element>
+        </sequence>
+      </extension>
+    </complexContent>
+  </complexType>
+  <!-- ===========================================================-->
+</schema>
diff --git a/pycsw/core/schemas/ogc/ows/2.0/owsDataIdentification.xsd b/pycsw/core/schemas/ogc/ows/2.0/owsDataIdentification.xsd
new file mode 100644
index 0000000..cb59979
--- /dev/null
+++ b/pycsw/core/schemas/ogc/ows/2.0/owsDataIdentification.xsd
@@ -0,0 +1,202 @@
+<?xml version="1.0" encoding="utf-8"?>
+<schema xmlns:ows="http://www.opengis.net/ows/2.0"
+        xmlns:xlink="http://www.w3.org/1999/xlink"
+        xmlns="http://www.w3.org/2001/XMLSchema"
+        targetNamespace="http://www.opengis.net/ows/2.0"
+        elementFormDefault="qualified"
+        version="2.0.2"
+        xml:lang="en">
+  <annotation>
+    <appinfo>owsDataIdentification.xsd</appinfo>
+    <documentation>This XML Schema Document encodes the parts of the
+    MD_DataIdentification class of ISO 19115 (OGC Abstract Specification Topic
+    11) which are expected to be used for most datasets. This Schema also
+    encodes the parts of this class that are expected to be useful for other
+    metadata. Both may be used within the Contents section of OWS service
+    metadata (Capabilities) documents.
+    
+    OWS is an OGC Standard.
+    Copyright (c) 2009 Open Geospatial Consortium.
+    To obtain additional rights of use, visit http://www.opengeospatial.org/legal/
+    </documentation>
+  </annotation>
+  
+  <!-- ==============================================================
+                includes and imports
+        ============================================================== -->
+  <include schemaLocation="owsAll.xsd"/>
+  <include schemaLocation="owsCommon.xsd" />
+  <include schemaLocation="ows19115subset.xsd" />
+  
+  <!-- ==============================================================
+                elements and types
+        ============================================================== -->
+  <complexType name="DescriptionType">
+    <annotation>
+      <documentation>Human-readable descriptive information for the object it
+      is included within. This type shall be extended if needed for specific
+      OWS use to include additional metadata for each type of information.
+      This type shall not be restricted for a specific OWS to change the
+      multiplicity (or optionality) of some elements. If the xml:lang
+      attribute is not included in a Title, Abstract or Keyword element, then
+      no language is specified for that element unless specified by another
+      means. All Title, Abstract and Keyword elements in the same Description
+      that share the same xml:lang attribute value represent the description
+      of the parent object in that language. Multiple Title or Abstract
+      elements shall not exist in the same Description with the same xml:lang
+      attribute value unless otherwise specified.</documentation>
+    </annotation>
+    <sequence>
+      <element ref="ows:Title"
+               minOccurs="0"
+               maxOccurs="unbounded" />
+      <element ref="ows:Abstract"
+               minOccurs="0"
+               maxOccurs="unbounded" />
+      <element ref="ows:Keywords"
+               minOccurs="0"
+               maxOccurs="unbounded" />
+    </sequence>
+  </complexType>
+  <!-- ========================================================= -->
+  <complexType name="BasicIdentificationType">
+    <annotation>
+      <documentation>Basic metadata identifying and describing a set of
+      data.</documentation>
+    </annotation>
+    <complexContent>
+      <extension base="ows:DescriptionType">
+        <sequence>
+          <element ref="ows:Identifier"
+                   minOccurs="0">
+            <annotation>
+              <documentation>Optional unique identifier or name of this
+              dataset.</documentation>
+            </annotation>
+          </element>
+          <element ref="ows:Metadata"
+                   minOccurs="0"
+                   maxOccurs="unbounded">
+            <annotation>
+              <documentation>Optional unordered list of additional metadata
+              about this data(set). A list of optional metadata elements for
+              this data identification could be specified in the
+              Implementation Specification for this service.</documentation>
+            </annotation>
+          </element>
+        </sequence>
+      </extension>
+    </complexContent>
+  </complexType>
+  <!-- ========================================================= -->
+  <complexType name="IdentificationType">
+    <annotation>
+      <documentation>Extended metadata identifying and describing a set of
+      data. This type shall be extended if needed for each specific OWS to
+      include additional metadata for each type of dataset. If needed, this
+      type should first be restricted for each specific OWS to change the
+      multiplicity (or optionality) of some elements.</documentation>
+    </annotation>
+    <complexContent>
+      <extension base="ows:BasicIdentificationType">
+        <sequence>
+          <element ref="ows:BoundingBox"
+                   minOccurs="0"
+                   maxOccurs="unbounded">
+            <annotation>
+              <documentation>Unordered list of zero or more bounding boxes
+              whose union describes the extent of this
+              dataset.</documentation>
+            </annotation>
+          </element>
+          <element ref="ows:OutputFormat"
+                   minOccurs="0"
+                   maxOccurs="unbounded">
+            <annotation>
+              <documentation>Unordered list of zero or more references to data
+              formats supported for server outputs.</documentation>
+            </annotation>
+          </element>
+          <element ref="ows:AvailableCRS"
+                   minOccurs="0"
+                   maxOccurs="unbounded">
+            <annotation>
+              <documentation>Unordered list of zero or more available
+              coordinate reference systems.</documentation>
+            </annotation>
+          </element>
+        </sequence>
+      </extension>
+    </complexContent>
+  </complexType>
+  <!-- ===========================================================-->
+  <element name="Identifier"
+           type="ows:CodeType">
+    <annotation>
+      <documentation>Unique identifier or name of this
+      dataset.</documentation>
+    </annotation>
+  </element>
+  <!-- ===========================================================-->
+  <element name="OutputFormat"
+           type="ows:MimeType">
+    <annotation>
+      <documentation>Reference to a format in which this data can be encoded
+      and transferred. More specific parameter names should be used by
+      specific OWS specifications wherever applicable. More than one such
+      parameter can be included for different purposes.</documentation>
+    </annotation>
+  </element>
+  <!-- ===========================================================-->
+  <element name="AvailableCRS"
+           type="anyURI" />
+  <element name="SupportedCRS"
+           type="anyURI"
+           substitutionGroup="ows:AvailableCRS">
+    <annotation>
+      <documentation>Coordinate reference system in which data from this
+      data(set) or resource is available or supported. More specific parameter
+      names should be used by specific OWS specifications wherever applicable.
+      More than one such parameter can be included for different
+      purposes.</documentation>
+    </annotation>
+  </element>
+  <!-- ==========================================================
+        The following elements could be added to the IdentificationType when useful for a 
+        specific OWS. In addition the PointOfContact element in ows19115subset.xsd could 
+        be added.
+        ============================================================= -->
+  <element name="AccessConstraints"
+           type="string">
+    <annotation>
+      <documentation>Access constraint applied to assure the protection of
+      privacy or intellectual property, or any other restrictions on
+      retrieving or using data from or otherwise using this server. The
+      reserved value NONE (case insensitive) shall be used to mean no access
+      constraints are imposed.</documentation>
+    </annotation>
+  </element>
+  <!-- ========================================================== -->
+  <element name="Fees"
+           type="string">
+    <annotation>
+      <documentation>Fees and terms for retrieving data from or otherwise
+      using this server, including the monetary units as specified in ISO
+      4217. The reserved value NONE (case insensitive) shall be used to mean
+      no fees or terms.</documentation>
+    </annotation>
+  </element>
+  <!-- ========================================================== -->
+  <element name="Language"
+           type="language">
+    <annotation>
+      <documentation>Identifier of a language used by the data(set) contents.
+      This language identifier shall be as specified in IETF RFC 4646. The
+      language tags shall be either complete 5 character codes (e.g. "en-CA"),
+      or abbreviated 2 character codes (e.g. "en"). In addition to the RFC
+      4646 codes, the server shall support the single special value "*" which
+      is used to indicate "any language".</documentation>
+    </annotation>
+  </element>
+  <!-- ========================================================== -->
+</schema>
diff --git a/pycsw/core/schemas/ogc/ows/2.0/owsDomainType.xsd b/pycsw/core/schemas/ogc/ows/2.0/owsDomainType.xsd
new file mode 100644
index 0000000..0b24a65
--- /dev/null
+++ b/pycsw/core/schemas/ogc/ows/2.0/owsDomainType.xsd
@@ -0,0 +1,388 @@
+<?xml version="1.0" encoding="utf-8"?>
+<schema xmlns:ows="http://www.opengis.net/ows/2.0"
+        xmlns:xlink="http://www.w3.org/1999/xlink"
+        xmlns="http://www.w3.org/2001/XMLSchema"
+        targetNamespace="http://www.opengis.net/ows/2.0"
+        elementFormDefault="qualified"
+        version="2.0.2"
+        xml:lang="en">
+  <annotation>
+    <appinfo>owsDomainType.xsd</appinfo>
+    <documentation>This XML Schema Document encodes the allowed values (or
+    domain) of a quantity, often for an input or output parameter to an OWS.
+    Such a parameter is sometimes called a variable, quantity, literal, or
+    typed literal. Such a parameter can use one of many data types, including
+    double, integer, boolean, string, or URI. The allowed values can also be
+    encoded for a quantity that is not explicit or not transferred, but is
+    constrained by a server implementation.
+    
+    OWS is an OGC Standard.
+    Copyright (c) 2009 Open Geospatial Consortium.
+    To obtain additional rights of use, visit http://www.opengeospatial.org/legal/
+    </documentation>
+  </annotation>
+  <!-- ==============================================================
+                includes and imports
+        ============================================================== -->
+  <include schemaLocation="owsAll.xsd"/>
+  <include schemaLocation="owsCommon.xsd" />
+  <import namespace="http://www.w3.org/1999/xlink"
+          schemaLocation="../../../w3c/1999/xlink.xsd" />
+
+  <!-- ==============================================================
+                elements and types
+        ============================================================== -->
+  <complexType name="DomainType">
+    <annotation>
+      <documentation>Valid domain (or allowed set of values) of one quantity,
+      with its name or identifier.</documentation>
+    </annotation>
+    <complexContent>
+      <extension base="ows:UnNamedDomainType">
+        <attribute name="name"
+                   type="string"
+                   use="required">
+          <annotation>
+            <documentation>Name or identifier of this
+            quantity.</documentation>
+          </annotation>
+        </attribute>
+      </extension>
+    </complexContent>
+  </complexType>
+  <!-- ========================================================== -->
+  <complexType name="UnNamedDomainType">
+    <annotation>
+      <documentation>Valid domain (or allowed set of values) of one quantity,
+      with needed metadata but without a quantity name or
+      identifier.</documentation>
+    </annotation>
+    <sequence>
+      <group ref="ows:PossibleValues" />
+      <element ref="ows:DefaultValue"
+               minOccurs="0">
+        <annotation>
+          <documentation>Optional default value for this quantity, which
+          should be included when this quantity has a default
+          value.</documentation>
+        </annotation>
+      </element>
+      <element ref="ows:Meaning"
+               minOccurs="0">
+        <annotation>
+          <documentation>Meaning metadata should be referenced or included for
+          each quantity.</documentation>
+        </annotation>
+      </element>
+      <element ref="ows:DataType"
+               minOccurs="0">
+        <annotation>
+          <documentation>This data type metadata should be referenced or
+          included for each quantity.</documentation>
+        </annotation>
+      </element>
+      <group ref="ows:ValuesUnit"
+             minOccurs="0">
+        <annotation>
+          <documentation>Unit of measure, which should be included when this
+          set of PossibleValues has units or a more complete reference
+          system.</documentation>
+        </annotation>
+      </group>
+      <element ref="ows:Metadata"
+               minOccurs="0"
+               maxOccurs="unbounded">
+        <annotation>
+          <documentation>Optional unordered list of other metadata about this
+          quantity. A list of required and optional other metadata elements
+          for this quantity should be specified in the Implementation
+          Specification for this service.</documentation>
+        </annotation>
+      </element>
+    </sequence>
+  </complexType>
+  <!-- ========================================================== -->
+  <group name="PossibleValues">
+    <annotation>
+      <documentation>Specifies the possible values of this
+      quantity.</documentation>
+    </annotation>
+    <choice>
+      <element ref="ows:AllowedValues" />
+      <element ref="ows:AnyValue" />
+      <element ref="ows:NoValues" />
+      <element ref="ows:ValuesReference" />
+    </choice>
+  </group>
+  <!-- ========================================================== -->
+  <element name="AnyValue">
+    <annotation>
+      <documentation>Specifies that any value is allowed for this
+      parameter.</documentation>
+    </annotation>
+    <complexType />
+  </element>
+  <!-- ========================================================== -->
+  <element name="NoValues">
+    <annotation>
+      <documentation>Specifies that no values are allowed for this parameter
+      or quantity.</documentation>
+    </annotation>
+    <complexType />
+  </element>
+  <!-- ========================================================== -->
+  <element name="ValuesReference">
+    <annotation>
+      <documentation>Reference to externally specified list of all the valid
+      values and/or ranges of values for this quantity. (Informative: This
+      element was simplified from the metaDataProperty element in GML
+      3.0.)</documentation>
+    </annotation>
+    <complexType>
+      <simpleContent>
+        <extension base="string">
+          <annotation>
+            <documentation>Human-readable name of the list of values provided
+            by the referenced document. Can be empty string when this list has
+            no name.</documentation>
+          </annotation>
+          <attribute ref="ows:reference"
+                     use="required" />
+        </extension>
+      </simpleContent>
+    </complexType>
+  </element>
+  <!-- ========================================================== -->
+  <group name="ValuesUnit">
+    <annotation>
+      <documentation>Indicates that this quantity has units or a reference
+      system, and identifies the unit or reference system used by the
+      AllowedValues or ValuesReference.</documentation>
+    </annotation>
+    <choice>
+      <element ref="ows:UOM">
+        <annotation>
+          <documentation>Identifier of unit of measure of this set of values.
+          Should be included then this set of values has units (and not a more
+          complete reference system).</documentation>
+        </annotation>
+      </element>
+      <element ref="ows:ReferenceSystem">
+        <annotation>
+          <documentation>Identifier of reference system used by this set of
+          values. Should be included then this set of values has a reference
+          system (not just units).</documentation>
+        </annotation>
+      </element>
+    </choice>
+  </group>
+  <!-- ========================================================== -->
+  <!-- ========================================================== -->
+  <element name="AllowedValues">
+    <annotation>
+      <documentation>List of all the valid values and/or ranges of values for
+      this quantity. For numeric quantities, signed values should be ordered
+      from negative infinity to positive infinity.</documentation>
+    </annotation>
+    <complexType>
+      <choice maxOccurs="unbounded">
+        <element ref="ows:Value" />
+        <element ref="ows:Range" />
+      </choice>
+    </complexType>
+  </element>
+  <!-- ========================================================== -->
+  <element name="Value"
+           type="ows:ValueType" />
+  <!-- ========================================================== -->
+  <complexType name="ValueType">
+    <annotation>
+      <documentation>A single value, encoded as a string. This type can be
+      used for one value, for a spacing between allowed values, or for the
+      default value of a parameter.</documentation>
+    </annotation>
+    <simpleContent>
+      <extension base="string" />
+    </simpleContent>
+  </complexType>
+  <!-- ========================================================== -->
+  <element name="DefaultValue"
+           type="ows:ValueType">
+    <annotation>
+      <documentation>The default value for a quantity for which multiple
+      values are allowed.</documentation>
+    </annotation>
+  </element>
+  <!-- ========================================================== -->
+  <element name="Range"
+           type="ows:RangeType" />
+  <!-- ========================================================== -->
+  <complexType name="RangeType">
+    <annotation>
+      <documentation>A range of values of a numeric parameter. This range can
+      be continuous or discrete, defined by a fixed spacing between adjacent
+      valid values. If the MinimumValue or MaximumValue is not included, there
+      is no value limit in that direction. Inclusion of the specified minimum
+      and maximum values in the range shall be defined by the
+      rangeClosure.</documentation>
+    </annotation>
+    <sequence>
+      <element ref="ows:MinimumValue"
+               minOccurs="0" />
+      <element ref="ows:MaximumValue"
+               minOccurs="0" />
+      <element ref="ows:Spacing"
+               minOccurs="0">
+        <annotation>
+          <documentation>Shall be included when the allowed values are NOT
+          continuous in this range. Shall not be included when the allowed
+          values are continuous in this range.</documentation>
+        </annotation>
+      </element>
+    </sequence>
+    <attribute ref="ows:rangeClosure"
+               use="optional">
+      <annotation>
+        <documentation>Shall be included unless the default value
+        applies.</documentation>
+      </annotation>
+    </attribute>
+  </complexType>
+  <!-- ========================================================== -->
+  <element name="MinimumValue"
+           type="ows:ValueType">
+    <annotation>
+      <documentation>Minimum value of this numeric parameter.</documentation>
+    </annotation>
+  </element>
+  <!-- ========================================================== -->
+  <element name="MaximumValue"
+           type="ows:ValueType">
+    <annotation>
+      <documentation>Maximum value of this numeric parameter.</documentation>
+    </annotation>
+  </element>
+  <!-- ========================================================== -->
+  <element name="Spacing"
+           type="ows:ValueType">
+    <annotation>
+      <documentation>The regular distance or spacing between the allowed
+      values in a range.</documentation>
+    </annotation>
+  </element>
+  <!-- ========================================================== -->
+  <attribute name="rangeClosure"
+             default="closed">
+    <annotation>
+      <documentation>Specifies which of the minimum and maximum values are
+      included in the range. Note that plus and minus infinity are considered
+      closed bounds.</documentation>
+    </annotation>
+    <simpleType>
+      <restriction base="NMTOKENS">
+        <enumeration value="closed">
+          <annotation>
+            <documentation>The specified minimum and maximum values are
+            included in this range.</documentation>
+          </annotation>
+        </enumeration>
+        <enumeration value="open">
+          <annotation>
+            <documentation>The specified minimum and maximum values are NOT
+            included in this range.</documentation>
+          </annotation>
+        </enumeration>
+        <enumeration value="open-closed">
+          <annotation>
+            <documentation>The specified minimum value is NOT included in this
+            range, and the specified maximum value IS included in this
+            range.</documentation>
+          </annotation>
+        </enumeration>
+        <enumeration value="closed-open">
+          <annotation>
+            <documentation>The specified minimum value IS included in this
+            range, and the specified maximum value is NOT included in this
+            range.</documentation>
+          </annotation>
+        </enumeration>
+      </restriction>
+    </simpleType>
+  </attribute>
+  <!-- ========================================================== -->
+  <!-- ========================================================== -->
+  <complexType name="DomainMetadataType">
+    <annotation>
+      <documentation>References metadata about a quantity, and provides a name
+      for this metadata. (Informative: This element was simplified from the
+      metaDataProperty element in GML 3.0.)</documentation>
+    </annotation>
+    <simpleContent>
+      <extension base="string">
+        <annotation>
+          <documentation>Human-readable name of the metadata described by
+          associated referenced document.</documentation>
+        </annotation>
+        <attribute ref="ows:reference"
+                   use="optional" />
+      </extension>
+    </simpleContent>
+  </complexType>
+  <!-- ========================================================== -->
+  <attribute name="reference"
+             type="anyURI">
+    <annotation>
+      <documentation>Reference to data or metadata recorded elsewhere, either
+      external to this XML document or within it. Whenever practical, this
+      attribute should be a URL from which this metadata can be electronically
+      retrieved. Alternately, this attribute can reference a URN for
+      well-known metadata. For example, such a URN could be a URN defined in
+      the "ogc" URN namespace.</documentation>
+    </annotation>
+  </attribute>
+  <!-- ========================================================== -->
+  <element name="Meaning"
+           type="ows:DomainMetadataType">
+    <annotation>
+      <documentation>Definition of the meaning or semantics of this set of
+      values. This Meaning can provide more specific, complete, precise,
+      machine accessible, and machine understandable semantics about this
+      quantity, relative to other available semantic information. For example,
+      other semantic information is often provided in "documentation" elements
+      in XML Schemas or "description" elements in GML objects.</documentation>
+    </annotation>
+  </element>
+  <!-- ========================================================== -->
+  <element name="DataType"
+           type="ows:DomainMetadataType">
+    <annotation>
+      <documentation>Definition of the data type of this set of values. In
+      this case, the xlink:href attribute can reference a URN for a well-known
+      data type. For example, such a URN could be a data type identification
+      URN defined in the "ogc" URN namespace.</documentation>
+    </annotation>
+  </element>
+  <!-- ========================================================== -->
+  <element name="ReferenceSystem"
+           type="ows:DomainMetadataType">
+    <annotation>
+      <documentation>Definition of the reference system used by this set of
+      values, including the unit of measure whenever applicable (as is
+      normal). In this case, the xlink:href attribute can reference a URN for
+      a well-known reference system, such as for a coordinate reference system
+      (CRS). For example, such a URN could be a CRS identification URN defined
+      in the "ogc" URN namespace.</documentation>
+    </annotation>
+  </element>
+  <!-- ========================================================== -->
+  <element name="UOM"
+           type="ows:DomainMetadataType">
+    <annotation>
+      <documentation>Definition of the unit of measure of this set of values.
+      In this case, the xlink:href attribute can reference a URN for a
+      well-known unit of measure (uom). For example, such a URN could be a UOM
+      identification URN defined in the "ogc" URN namespace.</documentation>
+    </annotation>
+  </element>
+  <!-- ========================================================== -->
+</schema>
diff --git a/pycsw/core/schemas/ogc/ows/2.0/owsExceptionReport.xsd b/pycsw/core/schemas/ogc/ows/2.0/owsExceptionReport.xsd
new file mode 100644
index 0000000..52ad62a
--- /dev/null
+++ b/pycsw/core/schemas/ogc/ows/2.0/owsExceptionReport.xsd
@@ -0,0 +1,126 @@
+<?xml version="1.0" encoding="utf-8"?>
+<schema targetNamespace="http://www.opengis.net/ows/2.0"
+        xmlns:ows="http://www.opengis.net/ows/2.0"
+        xmlns="http://www.w3.org/2001/XMLSchema"
+        elementFormDefault="qualified"
+        version="2.0.2"
+        xml:lang="en">
+  <annotation>
+    <appinfo>owsExceptionReport.xsd</appinfo>
+    <documentation>This XML Schema Document encodes the Exception Report
+    response to all OWS operations.
+	
+    OWS is an OGC Standard.
+    Copyright (c) 2009 Open Geospatial Consortium.
+    To obtain additional rights of use, visit http://www.opengeospatial.org/legal/ .
+    </documentation>
+  </annotation>
+  <!-- ==============================================================
+                includes and imports
+        ============================================================== -->
+  <include schemaLocation="owsAll.xsd"/>
+  <import namespace="http://www.w3.org/XML/1998/namespace"
+          schemaLocation="../../../w3c/2001/xml.xsd" />
+
+  <!-- ==============================================================
+                elements and types
+        ============================================================== -->
+  <element name="ExceptionReport">
+    <annotation>
+      <documentation>Report message returned to the client that requested any
+      OWS operation when the server detects an error while processing that
+      operation request.</documentation>
+    </annotation>
+    <complexType>
+      <sequence>
+        <element ref="ows:Exception"
+                 maxOccurs="unbounded">
+          <annotation>
+            <documentation>Unordered list of one or more Exception elements
+            that each describes an error. These Exception elements shall be
+            interpreted by clients as being independent of one another (not
+            hierarchical).</documentation>
+          </annotation>
+        </element>
+      </sequence>
+      <attribute name="version"
+                 use="required">
+        <annotation>
+          <documentation>Specification version for OWS operation. The string
+          value shall contain one x.y.z "version" value (e.g., "2.1.3"). A
+          version number shall contain three non-negative integers separated
+          by decimal points, in the form "x.y.z". The integers y and z shall
+          not exceed 99. Each version shall be for the Implementation
+          Specification (document) and the associated XML Schemas to which
+          requested operations will conform. An Implementation Specification
+          version normally specifies XML Schemas against which an XML encoded
+          operation response must conform and should be validated. See Version
+          negotiation subclause for more information.</documentation>
+        </annotation>
+        <simpleType>
+          <restriction base="string">
+            <pattern value="\d+\.\d?\d\.\d?\d" />
+          </restriction>
+        </simpleType>
+      </attribute>
+      <attribute ref="xml:lang"
+                 use="optional">
+        <annotation>
+          <documentation>Identifier of the language used by all included
+          exception text values. These language identifiers shall be as
+          specified in IETF RFC 4646. When this attribute is omitted, the
+          language used is not identified.</documentation>
+        </annotation>
+      </attribute>
+    </complexType>
+  </element>
+  <!-- ======================================================= -->
+  <element name="Exception"
+           type="ows:ExceptionType" />
+  <!-- ======================================================= -->
+  <complexType name="ExceptionType">
+    <annotation>
+      <documentation>An Exception element describes one detected error that a
+      server chooses to convey to the client.</documentation>
+    </annotation>
+    <sequence>
+      <element name="ExceptionText"
+               type="string"
+               minOccurs="0"
+               maxOccurs="unbounded">
+        <annotation>
+          <documentation>Ordered sequence of text strings that describe this
+          specific exception or error. The contents of these strings are left
+          open to definition by each server implementation. A server is
+          strongly encouraged to include at least one ExceptionText value, to
+          provide more information about the detected error than provided by
+          the exceptionCode. When included, multiple ExceptionText values
+          shall provide hierarchical information about one detected error,
+          with the most significant information listed first.</documentation>
+        </annotation>
+      </element>
+    </sequence>
+    <attribute name="exceptionCode"
+               type="string"
+               use="required">
+      <annotation>
+        <documentation>A code representing the type of this exception, which
+        shall be selected from a set of exceptionCode values specified for the
+        specific service operation and server.</documentation>
+      </annotation>
+    </attribute>
+    <attribute name="locator"
+               type="string"
+               use="optional">
+      <annotation>
+        <documentation>When included, this locator shall indicate to the
+        client where an exception was encountered in servicing the client's
+        operation request. This locator should be included whenever meaningful
+        information can be provided by the server. The contents of this
+        locator will depend on the specific exceptionCode and OWS service, and
+        shall be specified in the OWS Implementation
+        Specification.</documentation>
+      </annotation>
+    </attribute>
+  </complexType>
+</schema>
diff --git a/pycsw/core/schemas/ogc/ows/2.0/owsGetCapabilities.xsd b/pycsw/core/schemas/ogc/ows/2.0/owsGetCapabilities.xsd
new file mode 100644
index 0000000..02f4819
--- /dev/null
+++ b/pycsw/core/schemas/ogc/ows/2.0/owsGetCapabilities.xsd
@@ -0,0 +1,220 @@
+<?xml version="1.0" encoding="utf-8"?>
+<schema xmlns:ows="http://www.opengis.net/ows/2.0"
+        xmlns="http://www.w3.org/2001/XMLSchema"
+        targetNamespace="http://www.opengis.net/ows/2.0"
+        elementFormDefault="qualified"
+        version="2.0.2"
+        xml:lang="en">
+  <annotation>
+    <appinfo>owsGetCapabilities.xsd</appinfo>
+    <documentation>This XML Schema Document defines the GetCapabilities
+    operation request and response XML elements and types, which are common to
+    all OWSs. This XML Schema shall be edited by each OWS, for example, to
+    specify a specific value for the "service" attribute.
+    
+    OWS is an OGC Standard.
+    Copyright (c) 2009 Open Geospatial Consortium.
+    To obtain additional rights of use, visit http://www.opengeospatial.org/legal/ .
+    </documentation>
+  </annotation>
+  <!-- ==============================================================
+                includes and imports
+        ============================================================== -->
+  <include schemaLocation="owsAll.xsd"/>
+  <include schemaLocation="owsServiceIdentification.xsd" />
+  <include schemaLocation="owsServiceProvider.xsd" />
+  <include schemaLocation="owsOperationsMetadata.xsd" />
+
+  <!-- ==============================================================
+                elements and types
+        ============================================================== -->
+  <complexType name="CapabilitiesBaseType">
+    <annotation>
+      <documentation>XML encoded GetCapabilities operation response. This
+      document provides clients with service metadata about a specific service
+      instance, usually including metadata about the tightly-coupled data
+      served. If the server does not implement the updateSequence parameter,
+      the server shall always return the complete Capabilities document,
+      without the updateSequence parameter. When the server implements the
+      updateSequence parameter and the GetCapabilities operation request
+      included the updateSequence parameter with the current value, the server
+      shall return this element with only the "version" and "updateSequence"
+      attributes. Otherwise, all optional elements shall be included or not
+      depending on the actual value of the Contents parameter in the
+      GetCapabilities operation request. This base type shall be extended by
+      each specific OWS to include the additional contents
+      needed.</documentation>
+    </annotation>
+    <sequence>
+      <element ref="ows:ServiceIdentification"
+               minOccurs="0" />
+      <element ref="ows:ServiceProvider"
+               minOccurs="0" />
+      <element ref="ows:OperationsMetadata"
+               minOccurs="0" />
+      <element name="Languages"
+               minOccurs="0">
+        <annotation>
+          <documentation>The list of languages that this service is able to
+          fully support. That is, if one of the listed languages is requested
+          using the AcceptLanguages parameter in future requests to the
+          server, all text strings contained in the response are guaranteed to
+          be in that language. This list does not necessarily constitute a
+          complete list of all languages that may be (at least partially)
+          supported by the server. It only states the languages that are fully
+          supported. If a server cannot guarantee full support of any
+          particular language, it shall omit it from the list of supported
+          languages in the capabilities document.</documentation>
+        </annotation>
+        <complexType>
+          <sequence>
+            <element ref="ows:Language" maxOccurs="unbounded"/>
+          </sequence>
+        </complexType>
+      </element>
+    </sequence>
+    <attribute name="version"
+               type="ows:VersionType"
+               use="required" />
+    <attribute name="updateSequence"
+               type="ows:UpdateSequenceType"
+               use="optional">
+      <annotation>
+        <documentation>Service metadata document version, having values that
+        are "increased" whenever any change is made in service metadata
+        document. Values are selected by each server, and are always opaque to
+        clients. When not supported by server, server shall not return this
+        attribute.</documentation>
+      </annotation>
+    </attribute>
+  </complexType>
+  <!-- =========================================================== -->
+  <element name="GetCapabilities"
+           type="ows:GetCapabilitiesType" />
+  <!-- =========================================================== -->
+  <complexType name="GetCapabilitiesType">
+    <annotation>
+      <documentation>XML encoded GetCapabilities operation request. This
+      operation allows clients to retrieve service metadata about a specific
+      service instance. In this XML encoding, no "request" parameter is
+      included, since the element name specifies the specific operation. This
+      base type shall be extended by each specific OWS to include the
+      additional required "service" attribute, with the correct value for that
+      OWS.</documentation>
+    </annotation>
+    <sequence>
+      <element name="AcceptVersions"
+               type="ows:AcceptVersionsType"
+               minOccurs="0">
+        <annotation>
+          <documentation>When omitted, server shall return latest supported
+          version.</documentation>
+        </annotation>
+      </element>
+      <element name="Sections"
+               type="ows:SectionsType"
+               minOccurs="0">
+        <annotation>
+          <documentation>When omitted or not supported by server, server shall
+          return complete service metadata (Capabilities)
+          document.</documentation>
+        </annotation>
+      </element>
+      <element name="AcceptFormats"
+               type="ows:AcceptFormatsType"
+               minOccurs="0">
+        <annotation>
+          <documentation>When omitted or not supported by server, server shall
+          return service metadata document using the MIME type
+          "text/xml".</documentation>
+        </annotation>
+      </element>
+      <element name="AcceptLanguages"
+               minOccurs="0">
+        <annotation>
+          <documentation>Ordered list of languages desired by the client for
+          all human readable text in the response, in order of preference. For
+          every element, the first matching language available from the server
+          shall be present in the response.</documentation>
+        </annotation>
+        <complexType>
+          <sequence>
+            <element ref="ows:Language" maxOccurs="unbounded"/>
+          </sequence>
+        </complexType>
+      </element>
+    </sequence>
+    <attribute name="updateSequence"
+               type="ows:UpdateSequenceType"
+               use="optional">
+      <annotation>
+        <documentation>When omitted or not supported by server, server shall
+        return latest complete service metadata document.</documentation>
+      </annotation>
+    </attribute>
+  </complexType>
+  <!-- =========================================================== -->
+  <!-- =========================================================== -->
+  <simpleType name="ServiceType">
+    <annotation>
+      <documentation>Service type identifier, where the string value is the
+      OWS type abbreviation, such as "WMS" or "WFS".</documentation>
+    </annotation>
+    <restriction base="string" />
+  </simpleType>
+  <!-- ========================================================= -->
+  <complexType name="AcceptVersionsType">
+    <annotation>
+      <documentation>Prioritized sequence of one or more specification
+      versions accepted by client, with preferred versions listed first. See
+      Version negotiation subclause for more information.</documentation>
+    </annotation>
+    <sequence>
+      <element name="Version"
+               type="ows:VersionType"
+               maxOccurs="unbounded" />
+    </sequence>
+  </complexType>
+  <!-- =========================================================== -->
+  <complexType name="SectionsType">
+    <annotation>
+      <documentation>Unordered list of zero or more names of requested
+      sections in complete service metadata document. Each Section value shall
+      contain an allowed section name as specified by each OWS specification.
+      See Sections parameter subclause for more information.</documentation>
+    </annotation>
+    <sequence>
+      <element name="Section"
+               type="string"
+               minOccurs="0"
+               maxOccurs="unbounded" />
+    </sequence>
+  </complexType>
+  <!-- =========================================================== -->
+  <simpleType name="UpdateSequenceType">
+    <annotation>
+      <documentation>Service metadata document version, having values that are
+      "increased" whenever any change is made in service metadata document.
+      Values are selected by each server, and are always opaque to clients.
+      See updateSequence parameter use subclause for more
+      information.</documentation>
+    </annotation>
+    <restriction base="string" />
+  </simpleType>
+  <!-- =========================================================== -->
+  <complexType name="AcceptFormatsType">
+    <annotation>
+      <documentation>Prioritized sequence of zero or more GetCapabilities
+      operation response formats desired by client, with preferred formats
+      listed first. Each response format shall be identified by its MIME type.
+      See AcceptFormats parameter use subclause for more
+      information.</documentation>
+    </annotation>
+    <sequence>
+      <element name="OutputFormat"
+               type="ows:MimeType"
+               minOccurs="0"
+               maxOccurs="unbounded" />
+    </sequence>
+  </complexType>
+</schema>
diff --git a/pycsw/core/schemas/ogc/ows/2.0/owsGetResourceByID.xsd b/pycsw/core/schemas/ogc/ows/2.0/owsGetResourceByID.xsd
new file mode 100644
index 0000000..54e4231
--- /dev/null
+++ b/pycsw/core/schemas/ogc/ows/2.0/owsGetResourceByID.xsd
@@ -0,0 +1,83 @@
+<?xml version="1.0" encoding="utf-8"?>
+<schema targetNamespace="http://www.opengis.net/ows/2.0"
+        xmlns:ows="http://www.opengis.net/ows/2.0"
+        xmlns="http://www.w3.org/2001/XMLSchema"
+        elementFormDefault="qualified"
+        version="2.0.2"
+        xml:lang="en">
+  <annotation>
+    <appinfo>owsGetResourceByID.xsd</appinfo>
+    <documentation>This XML Schema Document encodes the GetResourceByID
+    operation request message. This typical operation is specified as a base
+    for profiling in specific OWS specifications. For information on the
+    allowed changes and limitations in such profiling, see Subclause 9.4.1 of
+    the OWS Common specification.
+    
+    OWS is an OGC Standard.
+    Copyright (c) 2009 Open Geospatial Consortium.
+    To obtain additional rights of use, visit http://www.opengeospatial.org/legal/ .
+    </documentation>
+  </annotation>
+  <!-- ==============================================================
+                includes and imports
+        ============================================================== -->
+  <include schemaLocation="owsAll.xsd"/>
+  <include schemaLocation="owsDataIdentification.xsd" />
+  <include schemaLocation="owsGetCapabilities.xsd" />
+
+  <!-- ==============================================================
+                elements and types
+        ============================================================== -->
+  <element name="Resource">
+    <annotation>
+      <documentation>XML encoded GetResourceByID operation response. The
+      complexType used by this element shall be specified by each specific
+      OWS.</documentation>
+    </annotation>
+  </element>
+  <!-- =========================================================== -->
+  <element name="GetResourceByID"
+           type="ows:GetResourceByIdType"></element>
+  <!-- =========================================================== -->
+  <complexType name="GetResourceByIdType">
+    <annotation>
+      <documentation>Request to a service to perform the GetResourceByID
+      operation. This operation allows a client to retrieve one or more
+      identified resources, including datasets and resources that describe
+      datasets or parameters. In this XML encoding, no "request" parameter is
+      included, since the element name specifies the specific
+      operation.</documentation>
+    </annotation>
+    <sequence>
+      <element name="ResourceID"
+               type="anyURI"
+               minOccurs="0"
+               maxOccurs="unbounded">
+        <annotation>
+          <documentation>Unordered list of zero or more resource identifiers.
+          These identifiers can be listed in the Contents section of the
+          service metadata (Capabilities) document. For more information on
+          this parameter, see Subclause 9.4.2.1 of the OWS Common
+          specification.</documentation>
+        </annotation>
+      </element>
+      <element ref="ows:OutputFormat"
+               minOccurs="0">
+        <annotation>
+          <documentation>Optional reference to the data format to be used for
+          response to this operation request. This element shall be included
+          when multiple output formats are available for the selected
+          resource(s), and the client desires a format other than the
+          specified default, if any.</documentation>
+        </annotation>
+      </element>
+    </sequence>
+    <attribute name="service"
+               type="ows:ServiceType"
+               use="required" />
+    <attribute name="version"
+               type="ows:VersionType"
+               use="required" />
+  </complexType>
+  <!-- =========================================================== -->
+</schema>
diff --git a/pycsw/core/schemas/ogc/ows/2.0/owsInputOutputData.xsd b/pycsw/core/schemas/ogc/ows/2.0/owsInputOutputData.xsd
new file mode 100644
index 0000000..d9604d0
--- /dev/null
+++ b/pycsw/core/schemas/ogc/ows/2.0/owsInputOutputData.xsd
@@ -0,0 +1,98 @@
+<?xml version="1.0" encoding="utf-8"?>
+<schema targetNamespace="http://www.opengis.net/ows/2.0"
+        xmlns:ows="http://www.opengis.net/ows/2.0"
+        xmlns="http://www.w3.org/2001/XMLSchema"
+        elementFormDefault="qualified"
+        version="2.0.2"
+        xml:lang="en">
+  <annotation>
+    <appinfo>owsInputOutputData.xsd</appinfo>
+    <documentation>This XML Schema Document specifies types and elements for
+    input and output of operation data, allowing including multiple data items
+    with each data item either included or referenced. The contents of each
+    type and element specified here can be restricted and/or extended for each
+    use in a specific OWS specification.
+		
+    OWS is an OGC Standard.
+    Copyright (c) 2009 Open Geospatial Consortium.
+    To obtain additional rights of use, visit http://www.opengeospatial.org/legal/ .
+    </documentation>
+  </annotation>
+  <!-- ==============================================================
+                includes and imports
+        ============================================================== -->
+  <include schemaLocation="owsAll.xsd"/>
+  <include schemaLocation="owsManifest.xsd" />
+
+  <!-- ==========================================================
+                Types and elements
+            ========================================================== -->
+  <element name="OperationResponse"
+           type="ows:ManifestType">
+    <annotation>
+      <documentation>Response from an OWS operation, allowing including
+      multiple output data items with each item either included or referenced.
+      This OperationResponse element, or an element using the ManifestType
+      with a more specific element name, shall be used whenever applicable for
+      responses from OWS operations.</documentation>
+      <documentation>This element is specified for use where the ManifestType
+      contents are needed for an operation response, but the Manifest element
+      name is not fully applicable. This element or the ManifestType shall be
+      used instead of using the ows:ReferenceType proposed in OGC
+      04-105.</documentation>
+    </annotation>
+  </element>
+  <!-- ========================================================== -->
+  <element name="InputData"
+           type="ows:ManifestType">
+    <annotation>
+      <documentation>Input data in a XML-encoded OWS operation request,
+      allowing including multiple data items with each data item either
+      included or referenced. This InputData element, or an element using the
+      ManifestType with a more-specific element name (TBR), shall be used
+      whenever applicable within XML-encoded OWS operation
+      requests.</documentation>
+    </annotation>
+  </element>
+  <!-- ========================================================== -->
+  <element name="ServiceReference"
+           type="ows:ServiceReferenceType"
+           substitutionGroup="ows:Reference" />
+  <!-- ========================================================== -->
+  <complexType name="ServiceReferenceType">
+    <annotation>
+      <documentation>Complete reference to a remote resource that needs to be
+      retrieved from an OWS using an XML-encoded operation request. This
+      element shall be used, within an InputData or Manifest element that is
+      used for input data, when that input data needs to be retrieved from
+      another web service using a XML-encoded OWS operation request. This
+      element shall not be used for local payload input data or for requesting
+      the resource from a web server using HTTP Get.</documentation>
+    </annotation>
+    <complexContent>
+      <extension base="ows:ReferenceType">
+        <choice>
+          <element name="RequestMessage"
+                   type="anyType">
+            <annotation>
+              <documentation>The XML-encoded operation request message to be
+              sent to request this input data from another web server using
+              HTTP Post.</documentation>
+            </annotation>
+          </element>
+          <element name="RequestMessageReference"
+                   type="anyURI">
+            <annotation>
+              <documentation>Reference to the XML-encoded operation request
+              message to be sent to request this input data from another web
+              server using HTTP Post. The referenced message shall be attached
+              to the same message (using the cid scheme), or be accessible
+              using a URL.</documentation>
+            </annotation>
+          </element>
+        </choice>
+      </extension>
+    </complexContent>
+  </complexType>
+  <!-- ========================================================== -->
+</schema>
diff --git a/pycsw/core/schemas/ogc/ows/2.0/owsManifest.xsd b/pycsw/core/schemas/ogc/ows/2.0/owsManifest.xsd
new file mode 100644
index 0000000..5fcf47a
--- /dev/null
+++ b/pycsw/core/schemas/ogc/ows/2.0/owsManifest.xsd
@@ -0,0 +1,181 @@
+<?xml version="1.0" encoding="utf-8"?>
+<schema targetNamespace="http://www.opengis.net/ows/2.0"
+        xmlns:ows="http://www.opengis.net/ows/2.0"
+        xmlns:xlink="http://www.w3.org/1999/xlink"
+        xmlns="http://www.w3.org/2001/XMLSchema"
+        elementFormDefault="qualified"
+        version="2.0.2"
+        xml:lang="en">
+  <annotation>
+    <appinfo>owsManifest.xsd</appinfo>
+    <documentation>This XML Schema Document specifies types and elements for
+    document or resource references and for package manifests that contain
+    multiple references. The contents of each type and element specified here
+    can be restricted and/or extended for each use in a specific OWS
+    specification.
+
+    OWS is an OGC Standard.
+    Copyright (c) 2009 Open Geospatial Consortium.
+    To obtain additional rights of use, visit http://www.opengeospatial.org/legal/ .
+    </documentation>
+  </annotation>
+  <!-- ==============================================================
+                includes and imports
+        ============================================================== -->
+  <include schemaLocation="owsAll.xsd"/>
+  <include schemaLocation="owsDataIdentification.xsd" />
+  <import namespace="http://www.w3.org/1999/xlink"
+          schemaLocation="../../../w3c/1999/xlink.xsd" />
+
+  <!-- ==========================================================
+                Types and elements
+            ========================================================== -->
+  <element name="AbstractReferenceBase"
+           type="ows:AbstractReferenceBaseType"
+           abstract="true" />
+  <!-- ========================================================== -->
+  <complexType name="AbstractReferenceBaseType">
+    <annotation>
+      <documentation>Base for a reference to a remote or local
+      resource.</documentation>
+      <documentation>This type contains only a restricted and annotated set of
+      the attributes from the xlink:simpleAttrs attributeGroup.</documentation>
+    </annotation>
+    <attribute name="type"
+               type="string"
+               fixed="simple"
+               form="qualified" />
+    <attribute ref="xlink:href"
+               use="required">
+      <annotation>
+        <documentation>Reference to a remote resource or local payload. A
+        remote resource is typically addressed by a URL. For a local payload
+        (such as a multipart mime message), the xlink:href must start with the
+        prefix cid:.</documentation>
+      </annotation>
+    </attribute>
+    <attribute ref="xlink:role"
+               use="optional">
+      <annotation>
+        <documentation>Reference to a resource that describes the role of this
+        reference. When no value is supplied, no particular role value is to
+        be inferred.</documentation>
+      </annotation>
+    </attribute>
+    <attribute ref="xlink:arcrole"
+               use="optional">
+      <annotation>
+        <documentation>Although allowed, this attribute is not expected to be
+        useful in this application of xlink:simpleAttrs.</documentation>
+      </annotation>
+    </attribute>
+    <attribute ref="xlink:title"
+               use="optional">
+      <annotation>
+        <documentation>Describes the meaning of the referenced resource in a
+        human-readable fashion.</documentation>
+      </annotation>
+    </attribute>
+    <attribute ref="xlink:show"
+               use="optional">
+      <annotation>
+        <documentation>Although allowed, this attribute is not expected to be
+        useful in this application of xlink:simpleAttrs.</documentation>
+      </annotation>
+    </attribute>
+    <attribute ref="xlink:actuate"
+               use="optional">
+      <annotation>
+        <documentation>Although allowed, this attribute is not expected to be
+        useful in this application of xlink:simpleAttrs.</documentation>
+      </annotation>
+    </attribute>
+  </complexType>
+  <!-- ========================================================== -->
+  <element name="Reference"
+           type="ows:ReferenceType"
+           substitutionGroup="ows:AbstractReferenceBase" />
+  <!-- ========================================================== -->
+  <complexType name="ReferenceType">
+    <annotation>
+      <documentation>Complete reference to a remote or local resource,
+      allowing including metadata about that resource.</documentation>
+    </annotation>
+    <complexContent>
+      <extension base="ows:AbstractReferenceBaseType">
+        <sequence>
+          <element ref="ows:Identifier"
+                   minOccurs="0">
+            <annotation>
+              <documentation>Optional unique identifier of the referenced
+              resource.</documentation>
+            </annotation>
+          </element>
+          <element ref="ows:Abstract"
+                   minOccurs="0"
+                   maxOccurs="unbounded" />
+          <element name="Format"
+                   type="ows:MimeType"
+                   minOccurs="0">
+            <annotation>
+              <documentation>The format of the referenced resource. This
+              element is omitted when the mime type is indicated in the http
+              header of the reference.</documentation>
+            </annotation>
+          </element>
+          <element ref="ows:Metadata"
+                   minOccurs="0"
+                   maxOccurs="unbounded">
+            <annotation>
+              <documentation>Optional unordered list of additional metadata
+              about this resource. A list of optional metadata elements for
+              this ReferenceType could be specified in the Implementation
+              Specification for each use of this type in a specific
+              OWS.</documentation>
+            </annotation>
+          </element>
+        </sequence>
+      </extension>
+    </complexContent>
+  </complexType>
+  <!-- =========================================================== -->
+  <!-- =========================================================== -->
+  <element name="ReferenceGroup"
+           type="ows:ReferenceGroupType" />
+  <!-- =========================================================== -->
+  <complexType name="ReferenceGroupType">
+    <annotation>
+      <documentation>Logical group of one or more references to remote and/or
+      local resources, allowing including metadata about that group. A Group
+      can be used instead of a Manifest that can only contain one
+      group.</documentation>
+    </annotation>
+    <complexContent>
+      <extension base="ows:BasicIdentificationType">
+        <sequence>
+          <element ref="ows:AbstractReferenceBase"
+                   maxOccurs="unbounded" />
+        </sequence>
+      </extension>
+    </complexContent>
+  </complexType>
+  <!-- =========================================================== -->
+  <element name="Manifest"
+           type="ows:ManifestType" />
+  <!-- =========================================================== -->
+  <complexType name="ManifestType">
+    <annotation>
+      <documentation>Unordered list of one or more groups of references to
+      remote and/or local resources.</documentation>
+    </annotation>
+    <complexContent>
+      <extension base="ows:BasicIdentificationType">
+        <sequence>
+          <element ref="ows:ReferenceGroup"
+                   maxOccurs="unbounded" />
+        </sequence>
+      </extension>
+    </complexContent>
+  </complexType>
+  <!-- ========================================================== -->
+</schema>
diff --git a/pycsw/core/schemas/ogc/ows/2.0/owsOperationsMetadata.xsd b/pycsw/core/schemas/ogc/ows/2.0/owsOperationsMetadata.xsd
new file mode 100644
index 0000000..084863e
--- /dev/null
+++ b/pycsw/core/schemas/ogc/ows/2.0/owsOperationsMetadata.xsd
@@ -0,0 +1,234 @@
+<?xml version="1.0" encoding="utf-8"?>
+<schema targetNamespace="http://www.opengis.net/ows/2.0"
+        xmlns:ows="http://www.opengis.net/ows/2.0"
+        xmlns="http://www.w3.org/2001/XMLSchema"
+        elementFormDefault="qualified"
+        version="2.0.2"
+        xml:lang="en">
+  <annotation>
+    <appinfo>owsOperationsMetadata.xsd</appinfo>
+    <documentation>This XML Schema Document encodes the basic contents of the
+    "OperationsMetadata" section of the GetCapabilities operation response,
+    also known as the Capabilities XML document.
+
+    OWS is an OGC Standard.
+    Copyright (c) 2009 Open Geospatial Consortium.
+    To obtain additional rights of use, visit http://www.opengeospatial.org/legal/ .
+    </documentation>
+  </annotation>
+  <!-- ==============================================================
+                includes and imports
+        ============================================================== -->
+  <include schemaLocation="owsAll.xsd"/>
+  <include schemaLocation="owsCommon.xsd" />
+  <include schemaLocation="ows19115subset.xsd" />
+  <include schemaLocation="owsDomainType.xsd" />
+
+  <!-- ==============================================================
+                elements and types
+        ============================================================== -->
+  <element name="OperationsMetadata">
+    <annotation>
+      <documentation>Metadata about the operations and related abilities
+      specified by this service and implemented by this server, including the
+      URLs for operation requests. The basic contents of this section shall be
+      the same for all OWS types, but individual services can add elements
+      and/or change the optionality of optional elements.</documentation>
+    </annotation>
+    <complexType>
+      <sequence>
+        <element ref="ows:Operation"
+                 minOccurs="2"
+                 maxOccurs="unbounded">
+          <annotation>
+            <documentation>Metadata for unordered list of all the (requests
+            for) operations that this server interface implements. The list of
+            required and optional operations implemented shall be specified in
+            the Implementation Specification for this service.</documentation>
+          </annotation>
+        </element>
+        <element name="Parameter"
+                 type="ows:DomainType"
+                 minOccurs="0"
+                 maxOccurs="unbounded">
+          <annotation>
+            <documentation>Optional unordered list of parameter valid domains
+            that each apply to one or more operations which this server
+            interface implements. The list of required and optional parameter
+            domain limitations shall be specified in the Implementation
+            Specification for this service.</documentation>
+          </annotation>
+        </element>
+        <element name="Constraint"
+                 type="ows:DomainType"
+                 minOccurs="0"
+                 maxOccurs="unbounded">
+          <annotation>
+            <documentation>Optional unordered list of valid domain constraints
+            on non-parameter quantities that each apply to this server. The
+            list of required and optional constraints shall be specified in
+            the Implementation Specification for this service.</documentation>
+          </annotation>
+        </element>
+        <element ref="ows:ExtendedCapabilities"
+                 minOccurs="0" />
+      </sequence>
+    </complexType>
+  </element>
+  <!-- ========================================================== -->
+  <element name="ExtendedCapabilities"
+           type="anyType">
+    <annotation>
+      <documentation>Individual software vendors and servers can use this
+      element to provide metadata about any additional server
+      abilities.</documentation>
+    </annotation>
+  </element>
+  <!-- ========================================================== -->
+  <element name="Operation">
+    <annotation>
+      <documentation>Metadata for one operation that this server
+      implements.</documentation>
+    </annotation>
+    <complexType>
+      <sequence>
+        <element ref="ows:DCP"
+                 maxOccurs="unbounded">
+          <annotation>
+            <documentation>Unordered list of Distributed Computing Platforms
+            (DCPs) supported for this operation. At present, only the HTTP DCP
+            is defined, so this element will appear only once.</documentation>
+          </annotation>
+        </element>
+        <element name="Parameter"
+                 type="ows:DomainType"
+                 minOccurs="0"
+                 maxOccurs="unbounded">
+          <annotation>
+            <documentation>Optional unordered list of parameter domains that
+            each apply to this operation which this server implements. If one
+            of these Parameter elements has the same "name" attribute as a
+            Parameter element in the OperationsMetadata element, this
+            Parameter element shall override the other one for this operation.
+            The list of required and optional parameter domain limitations for
+            this operation shall be specified in the Implementation
+            Specification for this service.</documentation>
+          </annotation>
+        </element>
+        <element name="Constraint"
+                 type="ows:DomainType"
+                 minOccurs="0"
+                 maxOccurs="unbounded">
+          <annotation>
+            <documentation>Optional unordered list of valid domain constraints
+            on non-parameter quantities that each apply to this operation. If
+            one of these Constraint elements has the same "name" attribute as
+            a Constraint element in the OperationsMetadata element, this
+            Constraint element shall override the other one for this
+            operation. The list of required and optional constraints for this
+            operation shall be specified in the Implementation Specification
+            for this service.</documentation>
+          </annotation>
+        </element>
+        <element ref="ows:Metadata"
+                 minOccurs="0"
+                 maxOccurs="unbounded">
+          <annotation>
+            <documentation>Optional unordered list of additional metadata
+            about this operation and its' implementation. A list of required
+            and optional metadata elements for this operation should be
+            specified in the Implementation Specification for this service.
+            (Informative: This metadata might specify the operation request
+            parameters or provide the XML Schemas for the operation
+            request.)</documentation>
+          </annotation>
+        </element>
+      </sequence>
+      <attribute name="name"
+                 type="string"
+                 use="required">
+        <annotation>
+          <documentation>Name or identifier of this operation (request) (for
+          example, GetCapabilities). The list of required and optional
+          operations implemented shall be specified in the Implementation
+          Specification for this service.</documentation>
+        </annotation>
+      </attribute>
+    </complexType>
+  </element>
+  <!-- ========================================================== -->
+  <element name="DCP">
+    <annotation>
+      <documentation>Information for one distributed Computing Platform (DCP)
+      supported for this operation. At present, only the HTTP DCP is defined,
+      so this element only includes the HTTP element.</documentation>
+    </annotation>
+    <complexType>
+      <choice>
+        <element ref="ows:HTTP" />
+      </choice>
+    </complexType>
+  </element>
+  <!-- ========================================================== -->
+  <element name="HTTP">
+    <annotation>
+      <documentation>Connect point URLs for the HTTP Distributed Computing
+      Platform (DCP). Normally, only one Get and/or one Post is included in
+      this element. More than one Get and/or Post is allowed to support
+      including alternative URLs for uses such as load balancing or
+      backup.</documentation>
+    </annotation>
+    <complexType>
+      <choice maxOccurs="unbounded">
+        <element name="Get"
+                 type="ows:RequestMethodType">
+          <annotation>
+            <documentation>Connect point URL prefix and any constraints for
+            the HTTP "Get" request method for this operation
+            request.</documentation>
+          </annotation>
+        </element>
+        <element name="Post"
+                 type="ows:RequestMethodType">
+          <annotation>
+            <documentation>Connect point URL and any constraints for the HTTP
+            "Post" request method for this operation request.</documentation>
+          </annotation>
+        </element>
+      </choice>
+    </complexType>
+  </element>
+  <!-- ========================================================== -->
+  <complexType name="RequestMethodType">
+    <annotation>
+      <documentation>Connect point URL and any constraints for this HTTP
+      request method for this operation request. In the OnlineResourceType,
+      the xlink:href attribute in the xlink:simpleAttrs attribute group shall
+      be used to contain this URL. The other attributes in the
+      xlink:simpleAttrs attribute group should not be used.</documentation>
+    </annotation>
+    <complexContent>
+      <extension base="ows:OnlineResourceType">
+        <sequence>
+          <element name="Constraint"
+                   type="ows:DomainType"
+                   minOccurs="0"
+                   maxOccurs="unbounded">
+            <annotation>
+              <documentation>Optional unordered list of valid domain
+              constraints on non-parameter quantities that each apply to this
+              request method for this operation. If one of these Constraint
+              elements has the same "name" attribute as a Constraint element
+              in the OperationsMetadata or Operation element, this Constraint
+              element shall override the other one for this operation. The
+              list of required and optional constraints for this request
+              method for this operation shall be specified in the
+              Implementation Specification for this service.</documentation>
+            </annotation>
+          </element>
+        </sequence>
+      </extension>
+    </complexContent>
+  </complexType>
+  <!-- ========================================================== -->
+</schema>
diff --git a/pycsw/core/schemas/ogc/ows/2.0/owsServiceIdentification.xsd b/pycsw/core/schemas/ogc/ows/2.0/owsServiceIdentification.xsd
new file mode 100644
index 0000000..a9872b7
--- /dev/null
+++ b/pycsw/core/schemas/ogc/ows/2.0/owsServiceIdentification.xsd
@@ -0,0 +1,98 @@
+<?xml version="1.0" encoding="utf-8"?>
+<schema targetNamespace="http://www.opengis.net/ows/2.0"
+        xmlns:ows="http://www.opengis.net/ows/2.0"
+        xmlns="http://www.w3.org/2001/XMLSchema"
+        elementFormDefault="qualified"
+        version="2.0.2"
+        xml:lang="en">
+  <annotation>
+    <appinfo>owsServiceIdentification.xsd</appinfo>
+    <documentation>This XML Schema Document encodes the common
+    "ServiceIdentification" section of the GetCapabilities operation response,
+    known as the Capabilities XML document. This section encodes the
+    SV_ServiceIdentification class of ISO 19119 (OGC Abstract Specification
+    Topic 12). 
+
+    OWS is an OGC Standard.
+    Copyright (c) 2009 Open Geospatial Consortium.
+    To obtain additional rights of use, visit http://www.opengeospatial.org/legal/ .
+    </documentation>
+  </annotation>
+  
+  <!-- ==============================================================
+                includes and imports
+        ============================================================== -->
+  <include schemaLocation="owsAll.xsd"/>
+  <include schemaLocation="owsDataIdentification.xsd" />
+  
+  <!-- ==============================================================
+                elements and types
+        ============================================================== -->
+  <element name="ServiceIdentification">
+    <annotation>
+      <documentation>General metadata for this specific server. This XML
+      Schema of this section shall be the same for all OWS.</documentation>
+    </annotation>
+    <complexType>
+      <complexContent>
+        <extension base="ows:DescriptionType">
+          <sequence>
+            <element name="ServiceType"
+                     type="ows:CodeType">
+              <annotation>
+                <documentation>A service type name from a registry of
+                services. For example, the values of the codeSpace URI and
+                name and code string may be "OGC" and "catalogue." This type
+                name is normally used for machine-to-machine
+                communication.</documentation>
+              </annotation>
+            </element>
+            <element name="ServiceTypeVersion"
+                     type="ows:VersionType"
+                     maxOccurs="unbounded">
+              <annotation>
+                <documentation>Unordered list of one or more versions of this
+                service type implemented by this server. This information is
+                not adequate for version negotiation, and shall not be used
+                for that purpose.</documentation>
+              </annotation>
+            </element>
+            <element name="Profile"
+                     type="anyURI"
+                     minOccurs="0"
+                     maxOccurs="unbounded">
+              <annotation>
+                <documentation>Unordered list of identifiers of Application
+                Profiles that are implemented by this server. This element
+                should be included for each specified application profile
+                implemented by this server. The identifier value should be
+                specified by each Application Profile. If this element is
+                omitted, no meaning is implied.</documentation>
+              </annotation>
+            </element>
+            <element ref="ows:Fees"
+                     minOccurs="0">
+              <annotation>
+                <documentation>If this element is omitted, no meaning is
+                implied.</documentation>
+              </annotation>
+            </element>
+            <element ref="ows:AccessConstraints"
+                     minOccurs="0"
+                     maxOccurs="unbounded">
+              <annotation>
+                <documentation>Unordered list of access constraints applied to
+                assure the protection of privacy or intellectual property, and
+                any other restrictions on retrieving or using data from or
+                otherwise using this server. The reserved value NONE (case
+                insensitive) shall be used to mean no access constraints are
+                imposed. When this element is omitted, no meaning is
+                implied.</documentation>
+              </annotation>
+            </element>
+          </sequence>
+        </extension>
+      </complexContent>
+    </complexType>
+  </element>
+</schema>
diff --git a/pycsw/core/schemas/ogc/ows/2.0/owsServiceProvider.xsd b/pycsw/core/schemas/ogc/ows/2.0/owsServiceProvider.xsd
new file mode 100644
index 0000000..c82d4a9
--- /dev/null
+++ b/pycsw/core/schemas/ogc/ows/2.0/owsServiceProvider.xsd
@@ -0,0 +1,64 @@
+<?xml version="1.0" encoding="utf-8"?>
+<schema targetNamespace="http://www.opengis.net/ows/2.0"
+        xmlns:ows="http://www.opengis.net/ows/2.0"
+        xmlns:xlink="http://www.w3.org/1999/xlink"
+        xmlns="http://www.w3.org/2001/XMLSchema"
+        elementFormDefault="qualified"
+        version="2.0.2"
+        xml:lang="en">
+  <annotation>
+    <appinfo>owsServiceProvider.xsd</appinfo>
+    <documentation>This XML Schema Document encodes the common
+    "ServiceProvider" section of the GetCapabilities operation response, known
+    as the Capabilities XML document. This section encodes the
+    SV_ServiceProvider class of ISO 19119 (OGC Abstract Specification Topic 12). 
+
+    OWS is an OGC Standard.
+    Copyright (c) 2009 Open Geospatial Consortium.
+    To obtain additional rights of use, visit http://www.opengeospatial.org/legal/ .
+    </documentation>
+  </annotation>
+  <!-- ==============================================================
+                includes and imports
+        ============================================================== -->
+  <include schemaLocation="owsAll.xsd"/>
+  <include schemaLocation="ows19115subset.xsd" />
+
+  <!-- ==============================================================
+                elements and types
+        ============================================================== -->
+  <element name="ServiceProvider">
+    <annotation>
+      <documentation>Metadata about the organization that provides this
+      specific service instance or server.</documentation>
+    </annotation>
+    <complexType>
+      <sequence>
+        <element name="ProviderName"
+                 type="string">
+          <annotation>
+            <documentation>A unique identifier for the service provider
+            organization.</documentation>
+          </annotation>
+        </element>
+        <element name="ProviderSite"
+                 type="ows:OnlineResourceType"
+                 minOccurs="0">
+          <annotation>
+            <documentation>Reference to the most relevant web site of the
+            service provider.</documentation>
+          </annotation>
+        </element>
+        <element name="ServiceContact"
+                 type="ows:ResponsiblePartySubsetType">
+          <annotation>
+            <documentation>Information for contacting the service provider.
+            The OnlineResource element within this ServiceContact element
+            should not be used to reference a web site of the service
+            provider.</documentation>
+          </annotation>
+        </element>
+      </sequence>
+    </complexType>
+  </element>
+</schema>
diff --git a/pycsw/schemas/w3c/1999/xlink.xsd b/pycsw/core/schemas/w3c/1999/xlink.xsd
similarity index 100%
rename from pycsw/schemas/w3c/1999/xlink.xsd
rename to pycsw/core/schemas/w3c/1999/xlink.xsd
diff --git a/pycsw/schemas/w3c/2001/xml.xsd b/pycsw/core/schemas/w3c/2001/xml.xsd
similarity index 100%
rename from pycsw/schemas/w3c/2001/xml.xsd
rename to pycsw/core/schemas/w3c/2001/xml.xsd
diff --git a/pycsw/util.py b/pycsw/core/util.py
similarity index 88%
rename from pycsw/util.py
rename to pycsw/core/util.py
index 8360328..b8b25fd 100644
--- a/pycsw/util.py
+++ b/pycsw/core/util.py
@@ -1,10 +1,11 @@
-# -*- coding: iso-8859-15 -*-
+# -*- coding: utf-8 -*-
 # =================================================================
 #
 # Authors: Tom Kralidis <tomkralidis at gmail.com>
 #          Angelos Tzotsos <tzotsos at gmail.com>
 #
-# Copyright (c) 2010 Tom Kralidis
+# Copyright (c) 2015 Tom Kralidis
+# Copyright (c) 2015 Angelos Tzotsos
 #
 # Permission is hereby granted, free of charge, to any person
 # obtaining a copy of this software and associated documentation
@@ -32,11 +33,12 @@
 import time
 import datetime
 import logging
-import urllib2
-from lxml import etree
+from six.moves.urllib.request import Request, urlopen
 from shapely.wkt import loads
 from owslib.util import http_post
+from pycsw.core.etree import etree
 
+from six import binary_type, text_type
 LOGGER = logging.getLogger(__name__)
 
 #Global variables for spatial ranking algorithm
@@ -44,6 +46,7 @@ ranking_enabled = False
 ranking_pass = False
 ranking_query_geometry = ''
 
+
 PARSER = etree.XMLParser(resolve_entities=False)
 
 def get_today_and_now():
@@ -116,7 +119,7 @@ def xmltag_split2(tag, namespaces, colon=False):
     """Return XML namespace prefix of element"""
     try:
         nsuri = tag.split('}')[0].split('{')[1]
-        nsprefix = [key for key, value in namespaces.iteritems()
+        nsprefix = [key for key, value in namespaces.items()
                     if value == nsuri]
         value = nsprefix[0]
         if colon:
@@ -217,7 +220,7 @@ def get_geometry_area(geometry):
 def get_spatial_overlay_rank(target_geometry, query_geometry):
     """Derive spatial overlay rank for geospatial search as per Lanfear (2006)
     http://pubs.usgs.gov/of/2006/1279/2006-1279.pdf"""
-    
+
     from shapely.geometry.base import BaseGeometry
     #TODO: Add those parameters to config file
     kt = 1.0
@@ -263,7 +266,8 @@ def bbox_from_polygons(bboxs):
 def update_xpath(nsmap, xml, recprop):
     """Update XML document XPath values"""
 
-    if isinstance(xml, unicode):  # not lxml serialized yet
+    if isinstance(xml, binary_type) or isinstance(xml, text_type):
+        # serialize to lxml
         xml = etree.fromstring(xml, PARSER)
 
     recprop = eval(recprop)
@@ -275,6 +279,7 @@ def update_xpath(nsmap, xml, recprop):
                 if node1.text != recprop['value']:  # values differ, update
                     node1.text = recprop['value']
     except Exception as err:
+        print(err)
         raise RuntimeError('ERROR: %s' % str(err))
 
     return etree.tostring(xml)
@@ -285,7 +290,7 @@ def transform_mappings(queryables, typename, reverse=False):
     if reverse:  # from csw:Record
         for qbl in queryables.keys():
             if qbl in typename.values():
-                tmp = [k for k, v in typename.iteritems() if v == qbl][0]
+                tmp = next(k for k, v in typename.items() if v == qbl)
                 val = queryables[tmp]
                 queryables[qbl] = {}
                 queryables[qbl]['xpath'] = val['xpath']
@@ -303,33 +308,24 @@ def get_anytext(bag):
     """
 
     if isinstance(bag, list):  # list of words
-        return ' '.join(filter(None, bag)).strip()
+        return ' '.join([_f for _f in bag if _f]).strip()
     else:  # xml
-        if isinstance(bag, unicode) or isinstance(bag, str):  # not serialized yet
+        if isinstance(bag, binary_type) or isinstance(bag, text_type):
+            # serialize to lxml
             bag = etree.fromstring(bag, PARSER)
-            # get all XML element content
+        # get all XML element content
         return ' '.join([value.strip() for value in bag.xpath('//text()')])
 
 
-def exml2dict(element, namespaces):
-    """Convert an lxml object to JSON
-        From:
-        http://bitbucket.org/smulloni/pesterfish/src/1578db946d74/pesterfish.py
-    """
+def xml2dict(xml_string, namespaces):
+    """Convert an lxml object to a dictionary"""
 
-    jdict = dict(tag='%s%s' % (xmltag_split2(element.tag, namespaces, True),
-                               xmltag_split(element.tag)))
-    if element.text:
-        if element.text.find('\n') == -1:
-            jdict['text'] = element.text
-    if element.attrib:
-        jdict['attributes'] = dict(('%s%s' % (xmltag_split2(k, namespaces, True),
-                                   xmltag_split(k)), f(v) if hasattr(v, 'keys') else v)
-                                   for k, v in element.attrib.items())
-    children = element.getchildren()
-    if children:
-        jdict['children'] = map(lambda x: exml2dict(x, namespaces), children)
-    return jdict
+    import xmltodict
+
+    namespaces_reverse = dict((v, k) for k, v in namespaces.items())
+
+    return xmltodict.parse(xml_string, process_namespaces=True,
+                           namespaces=namespaces_reverse)
 
 
 def getqattr(obj, name):
@@ -364,12 +360,12 @@ def http_request(method, url, request=None, timeout=30):
     if method == 'POST':
         return http_post(url, request, timeout=timeout)
     else:  # GET
-        request = urllib2.Request(url)
+        request = Request(url)
         request.add_header('User-Agent', 'pycsw (http://pycsw.org/)')
-        return urllib2.urlopen(request, timeout=timeout).read()
+        return urlopen(request, timeout=timeout).read()
 
 def bind_url(url):
-    """binds an HTTP GET query string endpiont"""
+    """binds an HTTP GET query string endpoint"""
     if url.find('?') == -1: # like http://host/wms
         binder = '?'
 
@@ -421,6 +417,25 @@ def sniff_table(table):
     """Checks whether repository.table is a schema namespaced"""
     schema = None
     table = table
-    if table.find('.') != - 1: 
+    if table.find('.') != - 1:
         schema, table = table.split('.')
     return [schema, table]
+
+
+def validate_4326(bbox_list):
+    ''' Helper function to validate 4326 '''
+
+    is_valid = False
+
+    if ((-180.0 <= float(bbox_list[0]) <= 180.0) and
+        (-90.0 <= float(bbox_list[1]) <= 90.0) and
+        (-180.0 <= float(bbox_list[2]) <= 180.0) and
+        (-90.0 <= float(bbox_list[3]) <= 90.0)):
+        is_valid = True
+
+    return is_valid
+
+def get_elapsed_time(begin, end):
+    ''' Helper function to calculate elapsed time in milliseconds'''
+
+    return int((end - begin) * 1000)
diff --git a/pycsw/oaipmh.py b/pycsw/oaipmh.py
index 59a1df6..39282ce 100644
--- a/pycsw/oaipmh.py
+++ b/pycsw/oaipmh.py
@@ -1,9 +1,9 @@
-# -*- coding: iso-8859-15 -*-
+# -*- coding: utf-8 -*-
 # =================================================================
 #
 # Authors: Tom Kralidis <tomkralidis at gmail.com>
 #
-# Copyright (c) 2014 Tom Kralidis
+# Copyright (c) 2015 Tom Kralidis
 #
 # Permission is hereby granted, free of charge, to any person
 # obtaining a copy of this software and associated documentation
@@ -29,8 +29,9 @@
 # =================================================================
 
 import logging
-from lxml import etree
-from pycsw import fes, util
+from pycsw.core import util
+from pycsw.core.etree import etree
+
 
 LOGGER = logging.getLogger(__name__)
 
@@ -88,6 +89,13 @@ class OAIPMH(object):
                 'identifier': '//dif:Entry_ID',
                 'dateStamp': '//dif:Last_DIF_Revision_Date',
                 'setSpec': '//dataset'
+            },
+            'gm03': {
+                'namespace': 'http://www.interlis.ch/INTERLIS2.3',
+                'schema': 'http://www.geocat.ch/internet/geocat/en/home/documentation/gm03.parsys.50316.downloadList.86742.DownloadFile.tmp/gm0321.zip',
+                'identifier': '//gm03:DATASECTION//gm03:fileIdentifer',
+                'dateStamp': '//gm03:DATASECTION//gm03:dateStamp',
+                'setSpec': '//dataset'
             }
         }
         self.metadata_sets = {
@@ -133,16 +141,16 @@ class OAIPMH(object):
                     kvpout['id'] = kvp['identifier']
                 if ('outputschema' in kvpout and
                     kvp['metadataprefix'] == 'oai_dc'):  # just use default DC
-                    del kvpout['outputschema'] 
+                    del kvpout['outputschema']
             elif kvp['verb'] in ['ListRecords', 'ListIdentifiers']:
                 if 'resumptiontoken' in kvp:
                     kvpout['startposition'] = kvp['resumptiontoken']
                 if ('outputschema' in kvpout and
                    kvp['verb'] == 'ListIdentifiers'):  # simple output only
-                    pass #del kvpout['outputschema'] 
+                    pass #del kvpout['outputschema']
                 if ('outputschema' in kvpout and
                     kvp['metadataprefix'] in ['dc', 'oai_dc']):  # just use default DC
-                    del kvpout['outputschema'] 
+                    del kvpout['outputschema']
 
 
                 start = end = None
@@ -187,7 +195,7 @@ class OAIPMH(object):
             return node
 
         if util.xmltag_split(response.tag) == 'ExceptionReport':
-            etree.SubElement(node, util.nspath_eval('oai:error', self.namespaces), code='badArgument').text = response.xpath('//ows:ExceptionText', namespaces=self.context.namespaces)[0].text
+            etree.SubElement(node, util.nspath_eval('oai:error', self.namespaces), code='badArgument').text = response.xpath('//ows:ExceptionText|//ows20:ExceptionText', namespaces=self.context.namespaces)[0].text
             return node
 
         verb = kvp.pop('verb')
@@ -200,7 +208,7 @@ class OAIPMH(object):
                 etree.SubElement(node, util.nspath_eval('oai:error', self.namespaces), code='badArgument').text = 'Invalid metadataPrefix parameter'
                 return node
 
-        for key, value in kvp.iteritems():
+        for key, value in kvp.items():
             if key != 'mode' and key not in self.request_model[verb]:
                 etree.SubElement(node, util.nspath_eval('oai:error', self.namespaces), code='badArgument').text = 'Illegal parameter \'%s\'' % key
                 return node
@@ -217,13 +225,13 @@ class OAIPMH(object):
                 etree.SubElement(verbnode, util.nspath_eval('oai:granularity', self.namespaces)).text = 'YYYY-MM-DDThh:mm:ssZ'
 
         elif verb == 'ListSets':
-            for key, value in self.metadata_sets.iteritems():
+            for key, value in sorted(self.metadata_sets.items()):
                 setnode = etree.SubElement(verbnode, util.nspath_eval('oai:set', self.namespaces))
                 etree.SubElement(setnode, util.nspath_eval('oai:setSpec', self.namespaces)).text = key
                 etree.SubElement(setnode, util.nspath_eval('oai:setName', self.namespaces)).text = value[0]
 
         elif verb == 'ListMetadataFormats':
-            for key, value in self.metadata_formats.iteritems():
+            for key, value in sorted(self.metadata_formats.items()):
                 mdfnode = etree.SubElement(verbnode, util.nspath_eval('oai:metadataFormat', self.namespaces))
                 etree.SubElement(mdfnode, util.nspath_eval('oai:metadataPrefix', self.namespaces)).text = key
                 etree.SubElement(mdfnode, util.nspath_eval('oai:schema', self.namespaces)).text = value['schema']
@@ -249,7 +257,7 @@ class OAIPMH(object):
                     complete_list_size = response.xpath('//@numberOfRecordsMatched')[0]
                     next_record = response.xpath('//@nextRecord')[0]
                     cursor = str(int(complete_list_size) - int(next_record) - 1)
-                
+
                     resumption_token = etree.SubElement(verbnode, util.nspath_eval('oai:resumptionToken', self.namespaces),
                                                         completeListSize=complete_list_size, cursor=cursor).text = next_record
         return node
@@ -274,9 +282,9 @@ class OAIPMH(object):
             value = xpath
         el = etree.SubElement(parent, util.nspath_eval(elname, self.context.namespaces))
         if value:
-            if elname == 'oai:setSpec': 
+            if elname == 'oai:setSpec':
                 value = None
-                for k, v in self.metadata_sets.iteritems():
+                for k, v in self.metadata_sets.items():
                     if v[1] == elname:
                         value = k
                         break
diff --git a/pycsw/plugins/profiles/__init__.py b/pycsw/ogc/__init__.py
similarity index 95%
copy from pycsw/plugins/profiles/__init__.py
copy to pycsw/ogc/__init__.py
index f98f82b..08a4c3d 100644
--- a/pycsw/plugins/profiles/__init__.py
+++ b/pycsw/ogc/__init__.py
@@ -1,9 +1,9 @@
-# -*- coding: ISO-8859-15 -*-
+# -*- coding: utf-8 -*-
 # =================================================================
 #
 # Authors: Tom Kralidis <tomkralidis at gmail.com>
 #
-# Copyright (c) 2011 Tom Kralidis
+# Copyright (c) 2015 Tom Kralidis
 #
 # Permission is hereby granted, free of charge, to any person
 # obtaining a copy of this software and associated documentation
diff --git a/pycsw/plugins/profiles/__init__.py b/pycsw/ogc/csw/__init__.py
similarity index 95%
copy from pycsw/plugins/profiles/__init__.py
copy to pycsw/ogc/csw/__init__.py
index f98f82b..08a4c3d 100644
--- a/pycsw/plugins/profiles/__init__.py
+++ b/pycsw/ogc/csw/__init__.py
@@ -1,9 +1,9 @@
-# -*- coding: ISO-8859-15 -*-
+# -*- coding: utf-8 -*-
 # =================================================================
 #
 # Authors: Tom Kralidis <tomkralidis at gmail.com>
 #
-# Copyright (c) 2011 Tom Kralidis
+# Copyright (c) 2015 Tom Kralidis
 #
 # Permission is hereby granted, free of charge, to any person
 # obtaining a copy of this software and associated documentation
diff --git a/pycsw/ogc/csw/csw2.py b/pycsw/ogc/csw/csw2.py
new file mode 100644
index 0000000..7a783f2
--- /dev/null
+++ b/pycsw/ogc/csw/csw2.py
@@ -0,0 +1,1988 @@
+# -*- coding: utf-8 -*-
+# =================================================================
+#
+# Authors: Tom Kralidis <tomkralidis at gmail.com>
+#          Angelos Tzotsos <tzotsos at gmail.com>
+#
+# Copyright (c) 2016 Tom Kralidis
+# Copyright (c) 2015 Angelos Tzotsos
+#
+# Permission is hereby granted, free of charge, to any person
+# obtaining a copy of this software and associated documentation
+# files (the "Software"), to deal in the Software without
+# restriction, including without limitation the rights to use,
+# copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the
+# Software is furnished to do so, subject to the following
+# conditions:
+#
+# The above copyright notice and this permission notice shall be
+# included in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+# OTHER DEALINGS IN THE SOFTWARE.
+#
+# =================================================================
+
+import os
+import sys
+import cgi
+from six.moves.urllib.parse import quote, unquote
+from six import StringIO
+from six.moves.configparser import SafeConfigParser
+from pycsw.core.etree import etree
+from pycsw import oaipmh, opensearch, sru
+from pycsw.plugins.profiles import profile as pprofile
+import pycsw.plugins.outputschemas
+from pycsw.core import config, log, metadata, util
+from pycsw.ogc.fes import fes1
+import logging
+
+LOGGER = logging.getLogger(__name__)
+
+
+class Csw2(object):
+    ''' CSW 2.x server '''
+    def __init__(self, server_csw):
+        ''' Initialize CSW2 '''
+
+        self.parent = server_csw
+        self.version = '2.0.2'
+
+    def getcapabilities(self):
+        ''' Handle GetCapabilities request '''
+        serviceidentification = True
+        serviceprovider = True
+        operationsmetadata = True
+        if 'sections' in self.parent.kvp:
+            serviceidentification = False
+            serviceprovider = False
+            operationsmetadata = False
+            for section in self.parent.kvp['sections'].split(','):
+                if section == 'ServiceIdentification':
+                    serviceidentification = True
+                if section == 'ServiceProvider':
+                    serviceprovider = True
+                if section == 'OperationsMetadata':
+                    operationsmetadata = True
+
+        # check extra parameters that may be def'd by profiles
+        if self.parent.profiles is not None:
+            for prof in self.parent.profiles['loaded'].keys():
+                result = \
+                self.parent.profiles['loaded'][prof].check_parameters(self.parent.kvp)
+                if result is not None:
+                    return self.exceptionreport(result['code'],
+                    result['locator'], result['text'])
+
+        # @updateSequence: get latest update to repository
+        try:
+            updatesequence = \
+            util.get_time_iso2unix(self.parent.repository.query_insert())
+        except:
+            updatesequence = None
+
+        node = etree.Element(util.nspath_eval('csw:Capabilities',
+        self.parent.context.namespaces),
+        nsmap=self.parent.context.namespaces, version='2.0.2',
+        updateSequence=str(updatesequence))
+
+        if 'updatesequence' in self.parent.kvp:
+            if int(self.parent.kvp['updatesequence']) == updatesequence:
+                return node
+            elif int(self.parent.kvp['updatesequence']) > updatesequence:
+                return self.exceptionreport('InvalidUpdateSequence',
+                'updatesequence',
+                'outputsequence specified (%s) is higher than server\'s \
+                updatesequence (%s)' % (self.parent.kvp['updatesequence'],
+                updatesequence))
+
+        node.attrib[util.nspath_eval('xsi:schemaLocation',
+        self.parent.context.namespaces)] = '%s %s/csw/2.0.2/CSW-discovery.xsd' % \
+        (self.parent.context.namespaces['csw'],
+         self.parent.config.get('server', 'ogc_schemas_base'))
+
+        metadata_main = dict(self.parent.config.items('metadata:main'))
+
+        if serviceidentification:
+            LOGGER.debug('Writing section ServiceIdentification.')
+
+            serviceidentification = etree.SubElement(node, \
+            util.nspath_eval('ows:ServiceIdentification',
+            self.parent.context.namespaces))
+
+            etree.SubElement(serviceidentification,
+            util.nspath_eval('ows:Title', self.parent.context.namespaces)).text = \
+            metadata_main.get('identification_title', 'missing')
+
+            etree.SubElement(serviceidentification,
+            util.nspath_eval('ows:Abstract', self.parent.context.namespaces)).text = \
+            metadata_main.get('identification_abstract', 'missing')
+
+            keywords = etree.SubElement(serviceidentification,
+            util.nspath_eval('ows:Keywords', self.parent.context.namespaces))
+
+            for k in \
+            metadata_main.get('identification_keywords').split(','):
+                etree.SubElement(
+                keywords, util.nspath_eval('ows:Keyword',
+                self.parent.context.namespaces)).text = k
+
+            etree.SubElement(keywords,
+            util.nspath_eval('ows:Type', self.parent.context.namespaces),
+            codeSpace='ISOTC211/19115').text = \
+            metadata_main.get('identification_keywords_type', 'missing')
+
+            etree.SubElement(serviceidentification,
+            util.nspath_eval('ows:ServiceType', self.parent.context.namespaces),
+            codeSpace='OGC').text = 'CSW'
+
+            for stv in self.parent.context.model['parameters']['version']['values']:
+                etree.SubElement(serviceidentification,
+                util.nspath_eval('ows:ServiceTypeVersion',
+                self.parent.context.namespaces)).text = stv
+
+            etree.SubElement(serviceidentification,
+            util.nspath_eval('ows:Fees', self.parent.context.namespaces)).text = \
+            metadata_main.get('identification_fees', 'missing')
+
+            etree.SubElement(serviceidentification,
+            util.nspath_eval('ows:AccessConstraints',
+            self.parent.context.namespaces)).text = \
+            metadata_main.get('identification_accessconstraints', 'missing')
+
+        if serviceprovider:
+            LOGGER.debug('Writing section ServiceProvider.')
+            serviceprovider = etree.SubElement(node,
+            util.nspath_eval('ows:ServiceProvider', self.parent.context.namespaces))
+
+            etree.SubElement(serviceprovider,
+            util.nspath_eval('ows:ProviderName', self.parent.context.namespaces)).text = \
+            metadata_main.get('provider_name', 'missing')
+
+            providersite = etree.SubElement(serviceprovider,
+            util.nspath_eval('ows:ProviderSite', self.parent.context.namespaces))
+
+            providersite.attrib[util.nspath_eval('xlink:type',
+            self.parent.context.namespaces)] = 'simple'
+
+            providersite.attrib[util.nspath_eval('xlink:href',
+            self.parent.context.namespaces)] = \
+            metadata_main.get('provider_url', 'missing')
+
+            servicecontact = etree.SubElement(serviceprovider,
+            util.nspath_eval('ows:ServiceContact', self.parent.context.namespaces))
+
+            etree.SubElement(servicecontact,
+            util.nspath_eval('ows:IndividualName',
+            self.parent.context.namespaces)).text = \
+            metadata_main.get('contact_name', 'missing')
+
+            etree.SubElement(servicecontact,
+            util.nspath_eval('ows:PositionName',
+            self.parent.context.namespaces)).text = \
+            metadata_main.get('contact_position', 'missing')
+
+            contactinfo = etree.SubElement(servicecontact,
+            util.nspath_eval('ows:ContactInfo', self.parent.context.namespaces))
+
+            phone = etree.SubElement(contactinfo, util.nspath_eval('ows:Phone',
+            self.parent.context.namespaces))
+
+            etree.SubElement(phone, util.nspath_eval('ows:Voice',
+            self.parent.context.namespaces)).text = \
+            metadata_main.get('contact_phone', 'missing')
+
+            etree.SubElement(phone, util.nspath_eval('ows:Facsimile',
+            self.parent.context.namespaces)).text = \
+            metadata_main.get('contact_fax', 'missing')
+
+            address = etree.SubElement(contactinfo,
+            util.nspath_eval('ows:Address', self.parent.context.namespaces))
+
+            etree.SubElement(address,
+            util.nspath_eval('ows:DeliveryPoint',
+            self.parent.context.namespaces)).text = \
+            metadata_main.get('contact_address', 'missing')
+
+            etree.SubElement(address, util.nspath_eval('ows:City',
+            self.parent.context.namespaces)).text = \
+            metadata_main.get('contact_city', 'missing')
+
+            etree.SubElement(address,
+            util.nspath_eval('ows:AdministrativeArea',
+            self.parent.context.namespaces)).text = \
+            metadata_main.get('contact_stateorprovince', 'missing')
+
+            etree.SubElement(address,
+            util.nspath_eval('ows:PostalCode',
+            self.parent.context.namespaces)).text = \
+            metadata_main.get('contact_postalcode', 'missing')
+
+            etree.SubElement(address,
+            util.nspath_eval('ows:Country', self.parent.context.namespaces)).text = \
+            metadata_main.get('contact_country', 'missing')
+
+            etree.SubElement(address,
+            util.nspath_eval('ows:ElectronicMailAddress',
+            self.parent.context.namespaces)).text = \
+            metadata_main.get('contact_email', 'missing')
+
+            url = etree.SubElement(contactinfo,
+            util.nspath_eval('ows:OnlineResource', self.parent.context.namespaces))
+
+            url.attrib[util.nspath_eval('xlink:type',
+            self.parent.context.namespaces)] = 'simple'
+
+            url.attrib[util.nspath_eval('xlink:href',
+            self.parent.context.namespaces)] = \
+            metadata_main.get('contact_url', 'missing')
+
+            etree.SubElement(contactinfo,
+            util.nspath_eval('ows:HoursOfService',
+            self.parent.context.namespaces)).text = \
+            metadata_main.get('contact_hours', 'missing')
+
+            etree.SubElement(contactinfo,
+            util.nspath_eval('ows:ContactInstructions',
+            self.parent.context.namespaces)).text = \
+            metadata_main.get('contact_instructions', 'missing')
+
+            etree.SubElement(servicecontact,
+            util.nspath_eval('ows:Role', self.parent.context.namespaces),
+            codeSpace='ISOTC211/19115').text = \
+            metadata_main.get('contact_role', 'missing')
+
+        if operationsmetadata:
+            LOGGER.debug('Writing section OperationsMetadata.')
+            operationsmetadata = etree.SubElement(node,
+            util.nspath_eval('ows:OperationsMetadata',
+            self.parent.context.namespaces))
+
+            for operation in self.parent.context.model['operations_order']:
+                oper = etree.SubElement(operationsmetadata,
+                util.nspath_eval('ows:Operation', self.parent.context.namespaces),
+                name=operation)
+
+                dcp = etree.SubElement(oper, util.nspath_eval('ows:DCP',
+                self.parent.context.namespaces))
+
+                http = etree.SubElement(dcp, util.nspath_eval('ows:HTTP',
+                self.parent.context.namespaces))
+
+                if self.parent.context.model['operations'][operation]['methods']['get']:
+                    get = etree.SubElement(http, util.nspath_eval('ows:Get',
+                    self.parent.context.namespaces))
+
+                    get.attrib[util.nspath_eval('xlink:type',\
+                    self.parent.context.namespaces)] = 'simple'
+
+                    get.attrib[util.nspath_eval('xlink:href',\
+                    self.parent.context.namespaces)] = self.parent.config.get('server', 'url')
+
+                if self.parent.context.model['operations'][operation]['methods']['post']:
+                    post = etree.SubElement(http, util.nspath_eval('ows:Post',
+                    self.parent.context.namespaces))
+                    post.attrib[util.nspath_eval('xlink:type',
+                    self.parent.context.namespaces)] = 'simple'
+                    post.attrib[util.nspath_eval('xlink:href',
+                    self.parent.context.namespaces)] = \
+                    self.parent.config.get('server', 'url')
+
+                for parameter in \
+                sorted(self.parent.context.model['operations'][operation]['parameters']):
+                    param = etree.SubElement(oper,
+                    util.nspath_eval('ows:Parameter',
+                    self.parent.context.namespaces), name=parameter)
+
+                    for val in \
+                    sorted(self.parent.context.model['operations'][operation]\
+                    ['parameters'][parameter]['values']):
+                        etree.SubElement(param,
+                        util.nspath_eval('ows:Value',
+                        self.parent.context.namespaces)).text = val
+
+                if operation == 'GetRecords':  # advertise queryables
+                    for qbl in sorted(self.parent.repository.queryables.keys()):
+                        if qbl != '_all':
+                            param = etree.SubElement(oper,
+                            util.nspath_eval('ows:Constraint',
+                            self.parent.context.namespaces), name=qbl)
+
+                            for qbl2 in sorted(self.parent.repository.queryables[qbl]):
+                                etree.SubElement(param,
+                                util.nspath_eval('ows:Value',
+                                self.parent.context.namespaces)).text = qbl2
+
+                    if self.parent.profiles is not None:
+                        for con in sorted(self.parent.context.model[\
+                        'operations']['GetRecords']['constraints'].keys()):
+                            param = etree.SubElement(oper,
+                            util.nspath_eval('ows:Constraint',
+                            self.parent.context.namespaces), name = con)
+                            for val in self.parent.context.model['operations']\
+                            ['GetRecords']['constraints'][con]['values']:
+                                etree.SubElement(param,
+                                util.nspath_eval('ows:Value',
+                                self.parent.context.namespaces)).text = val
+
+            for parameter in sorted(self.parent.context.model['parameters'].keys()):
+                param = etree.SubElement(operationsmetadata,
+                util.nspath_eval('ows:Parameter', self.parent.context.namespaces),
+                name=parameter)
+
+                for val in self.parent.context.model['parameters'][parameter]['values']:
+                    etree.SubElement(param, util.nspath_eval('ows:Value',
+                    self.parent.context.namespaces)).text = val
+
+            for constraint in sorted(self.parent.context.model['constraints'].keys()):
+                param = etree.SubElement(operationsmetadata,
+                util.nspath_eval('ows:Constraint', self.parent.context.namespaces),
+                name=constraint)
+
+                for val in self.parent.context.model['constraints'][constraint]['values']:
+                    etree.SubElement(param, util.nspath_eval('ows:Value',
+                    self.parent.context.namespaces)).text = val
+
+            if self.parent.profiles is not None:
+                for prof in self.parent.profiles['loaded'].keys():
+                    ecnode = \
+                    self.parent.profiles['loaded'][prof].get_extendedcapabilities()
+                    if ecnode is not None:
+                        operationsmetadata.append(ecnode)
+
+        # always write out Filter_Capabilities
+        LOGGER.debug('Writing section Filter_Capabilities.')
+        fltcaps = etree.SubElement(node,
+        util.nspath_eval('ogc:Filter_Capabilities', self.parent.context.namespaces))
+
+        spatialcaps = etree.SubElement(fltcaps,
+        util.nspath_eval('ogc:Spatial_Capabilities', self.parent.context.namespaces))
+
+        geomops = etree.SubElement(spatialcaps,
+        util.nspath_eval('ogc:GeometryOperands', self.parent.context.namespaces))
+
+        for geomtype in \
+        fes1.MODEL['GeometryOperands']['values']:
+            etree.SubElement(geomops,
+            util.nspath_eval('ogc:GeometryOperand',
+            self.parent.context.namespaces)).text = geomtype
+
+        spatialops = etree.SubElement(spatialcaps,
+        util.nspath_eval('ogc:SpatialOperators', self.parent.context.namespaces))
+
+        for spatial_comparison in \
+        fes1.MODEL['SpatialOperators']['values']:
+            etree.SubElement(spatialops,
+            util.nspath_eval('ogc:SpatialOperator', self.parent.context.namespaces),
+            name=spatial_comparison)
+
+        scalarcaps = etree.SubElement(fltcaps,
+        util.nspath_eval('ogc:Scalar_Capabilities', self.parent.context.namespaces))
+
+        etree.SubElement(scalarcaps, util.nspath_eval('ogc:LogicalOperators',
+        self.parent.context.namespaces))
+
+        cmpops = etree.SubElement(scalarcaps,
+        util.nspath_eval('ogc:ComparisonOperators', self.parent.context.namespaces))
+
+        for cmpop in sorted(fes1.MODEL['ComparisonOperators'].keys()):
+            etree.SubElement(cmpops,
+            util.nspath_eval('ogc:ComparisonOperator',
+            self.parent.context.namespaces)).text = \
+            fes1.MODEL['ComparisonOperators'][cmpop]['opname']
+
+        arithops = etree.SubElement(scalarcaps,
+        util.nspath_eval('ogc:ArithmeticOperators', self.parent.context.namespaces))
+
+        functions = etree.SubElement(arithops,
+        util.nspath_eval('ogc:Functions', self.parent.context.namespaces))
+
+        functionames = etree.SubElement(functions,
+        util.nspath_eval('ogc:FunctionNames', self.parent.context.namespaces))
+
+        for fnop in sorted(fes1.MODEL['Functions'].keys()):
+            etree.SubElement(functionames,
+            util.nspath_eval('ogc:FunctionName', self.parent.context.namespaces),
+            nArgs=fes1.MODEL['Functions'][fnop]['args']).text = fnop
+
+        idcaps = etree.SubElement(fltcaps,
+        util.nspath_eval('ogc:Id_Capabilities', self.parent.context.namespaces))
+
+        for idcap in fes1.MODEL['Ids']['values']:
+            etree.SubElement(idcaps, util.nspath_eval('ogc:%s' % idcap,
+            self.parent.context.namespaces))
+
+        return node
+
+    def describerecord(self):
+        ''' Handle DescribeRecord request '''
+
+        if 'typename' not in self.parent.kvp or \
+        len(self.parent.kvp['typename']) == 0:  # missing typename
+        # set to return all typenames
+            self.parent.kvp['typename'] = ['csw:Record']
+
+            if self.parent.profiles is not None:
+                for prof in self.parent.profiles['loaded'].keys():
+                    self.parent.kvp['typename'].append(
+                    self.parent.profiles['loaded'][prof].typename)
+
+        elif self.parent.requesttype == 'GET':  # pass via GET
+            self.parent.kvp['typename'] = self.parent.kvp['typename'].split(',')
+
+        if ('outputformat' in self.parent.kvp and
+            self.parent.kvp['outputformat'] not in
+            self.parent.context.model['operations']['DescribeRecord']
+            ['parameters']['outputFormat']['values']):  # bad outputformat
+            return self.exceptionreport('InvalidParameterValue',
+            'outputformat', 'Invalid value for outputformat: %s' %
+            self.parent.kvp['outputformat'])
+
+        if ('schemalanguage' in self.parent.kvp and
+            self.parent.kvp['schemalanguage'] not in
+            self.parent.context.model['operations']['DescribeRecord']['parameters']
+            ['schemaLanguage']['values']):  # bad schemalanguage
+            return self.exceptionreport('InvalidParameterValue',
+            'schemalanguage', 'Invalid value for schemalanguage: %s' %
+            self.parent.kvp['schemalanguage'])
+
+        node = etree.Element(util.nspath_eval('csw:DescribeRecordResponse',
+        self.parent.context.namespaces), nsmap=self.parent.context.namespaces)
+
+        node.attrib[util.nspath_eval('xsi:schemaLocation',
+        self.parent.context.namespaces)] = \
+        '%s %s/csw/2.0.2/CSW-discovery.xsd' % (self.parent.context.namespaces['csw'],
+        self.parent.config.get('server', 'ogc_schemas_base'))
+
+        for typename in self.parent.kvp['typename']:
+            if typename.find(':') == -1:  # unqualified typename
+                return self.exceptionreport('InvalidParameterValue',
+                'typename', 'Typename not qualified: %s' % typename)
+            if typename == 'csw:Record':   # load core schema
+                LOGGER.debug('Writing csw:Record schema.')
+                schemacomponent = etree.SubElement(node,
+                util.nspath_eval('csw:SchemaComponent', self.parent.context.namespaces),
+                schemaLanguage='XMLSCHEMA',
+                targetNamespace=self.parent.context.namespaces['csw'])
+
+                path = os.path.join(self.parent.config.get('server', 'home'),
+                'core', 'schemas', 'ogc', 'csw', '2.0.2', 'record.xsd')
+
+                dublincore = etree.parse(path, self.parent.context.parser).getroot()
+
+                schemacomponent.append(dublincore)
+
+            if self.parent.profiles is not None:
+                for prof in self.parent.profiles['loaded'].keys():
+                    if self.parent.profiles['loaded'][prof].typename == typename:
+                        scnodes = \
+                        self.parent.profiles['loaded'][prof].get_schemacomponents()
+                        if scnodes:
+                            for scn in scnodes:
+                                node.append(scn)
+        return node
+
+    def getdomain(self):
+        ''' Handle GetDomain request '''
+        if ('parametername' not in self.parent.kvp and
+            'propertyname' not in self.parent.kvp):
+            return self.exceptionreport('MissingParameterValue',
+            'parametername', 'Missing value. \
+            One of propertyname or parametername must be specified')
+
+        node = etree.Element(util.nspath_eval('csw:GetDomainResponse',
+        self.parent.context.namespaces), nsmap=self.parent.context.namespaces)
+
+        node.attrib[util.nspath_eval('xsi:schemaLocation',
+        self.parent.context.namespaces)] = '%s %s/csw/2.0.2/CSW-discovery.xsd' % \
+        (self.parent.context.namespaces['csw'],
+        self.parent.config.get('server', 'ogc_schemas_base'))
+
+        if 'parametername' in self.parent.kvp:
+            for pname in self.parent.kvp['parametername'].split(','):
+                LOGGER.debug('Parsing parametername %s.' % pname)
+                domainvalue = etree.SubElement(node,
+                util.nspath_eval('csw:DomainValues', self.parent.context.namespaces),
+                type='csw:Record')
+                etree.SubElement(domainvalue,
+                util.nspath_eval('csw:ParameterName',
+                self.parent.context.namespaces)).text = pname
+                try:
+                    operation, parameter = pname.split('.')
+                except:
+                    return node
+                if (operation in self.parent.context.model['operations'].keys() and
+                    parameter in
+                    self.parent.context.model['operations'][operation]['parameters'].keys()):
+                    listofvalues = etree.SubElement(domainvalue,
+                    util.nspath_eval('csw:ListOfValues', self.parent.context.namespaces))
+                    for val in \
+                    sorted(self.parent.context.model['operations'][operation]\
+                    ['parameters'][parameter]['values']):
+                        etree.SubElement(listofvalues,
+                        util.nspath_eval('csw:Value',
+                        self.parent.context.namespaces)).text = val
+
+        if 'propertyname' in self.parent.kvp:
+            for pname in self.parent.kvp['propertyname'].split(','):
+                LOGGER.debug('Parsing propertyname %s.' % pname)
+
+                if pname.find('/') == 0:  # it's an XPath
+                    pname2 = pname
+                else:  # it's a core queryable, map to internal typename model
+                    try:
+                        pname2 = self.parent.repository.queryables['_all'][pname]['dbcol']
+                    except:
+                        pname2 = pname
+
+                # decipher typename
+                dvtype = None
+                if self.parent.profiles is not None:
+                    for prof in self.parent.profiles['loaded'].keys():
+                        for prefix in self.parent.profiles['loaded'][prof].prefixes:
+                            if pname2.find(prefix) != -1:
+                                dvtype = self.parent.profiles['loaded'][prof].typename
+                                break
+                if not dvtype:
+                    dvtype = 'csw:Record'
+
+                domainvalue = etree.SubElement(node,
+                util.nspath_eval('csw:DomainValues', self.parent.context.namespaces),
+                type=dvtype)
+                etree.SubElement(domainvalue,
+                util.nspath_eval('csw:PropertyName',
+                self.parent.context.namespaces)).text = pname
+
+                try:
+                    LOGGER.debug(
+                    'Querying repository property %s, typename %s, \
+                    domainquerytype %s.' % \
+                    (pname2, dvtype, self.parent.domainquerytype))
+
+                    count = False
+
+                    if (self.parent.config.has_option('server', 'domaincounts') and
+                        self.parent.config.get('server', 'domaincounts') == 'true'):
+                        count = True
+
+                    results = self.parent.repository.query_domain(
+                    pname2, dvtype, self.parent.domainquerytype, count)
+
+                    LOGGER.debug('Results: %s' % str(len(results)))
+
+                    if self.parent.domainquerytype == 'range':
+                        rangeofvalues = etree.SubElement(domainvalue,
+                        util.nspath_eval('csw:RangeOfValues',
+                        self.parent.context.namespaces))
+
+                        etree.SubElement(rangeofvalues,
+                        util.nspath_eval('csw:MinValue',
+                        self.parent.context.namespaces)).text = results[0][0]
+
+                        etree.SubElement(rangeofvalues,
+                        util.nspath_eval('csw:MaxValue',
+                        self.parent.context.namespaces)).text = results[0][1]
+                    else:
+                        listofvalues = etree.SubElement(domainvalue,
+                        util.nspath_eval('csw:ListOfValues',
+                        self.parent.context.namespaces))
+                        for result in results:
+                            LOGGER.debug(str(result))
+                            if (result is not None and
+                                result[0] is not None):  # drop null values
+                                if count:  # show counts
+                                    val = '%s (%s)' % (result[0], result[1])
+                                else:
+                                    val = result[0]
+                                etree.SubElement(listofvalues,
+                                util.nspath_eval('csw:Value',
+                                self.parent.context.namespaces)).text = val
+                except Exception as err:
+                    LOGGER.debug('No results for propertyname %s: %s.' %
+                    (pname2, str(err)))
+        return node
+
+    def getrecords(self):
+        ''' Handle GetRecords request '''
+
+        timestamp = util.get_today_and_now()
+
+        if ('elementsetname' not in self.parent.kvp and
+            'elementname' not in self.parent.kvp):
+            # mutually exclusive required
+            return self.exceptionreport('MissingParameterValue',
+            'elementsetname',
+            'Missing one of ElementSetName or ElementName parameter(s)')
+
+        if 'outputschema' not in self.parent.kvp:
+            self.parent.kvp['outputschema'] = self.parent.context.namespaces['csw']
+
+        if (self.parent.kvp['outputschema'] not in self.parent.context.model['operations']
+            ['GetRecords']['parameters']['outputSchema']['values']):
+            return self.exceptionreport('InvalidParameterValue',
+            'outputschema', 'Invalid outputSchema parameter value: %s' %
+            self.parent.kvp['outputschema'])
+
+        if 'outputformat' not in self.parent.kvp:
+            self.parent.kvp['outputformat'] = 'application/xml'
+
+        if (self.parent.kvp['outputformat'] not in self.parent.context.model['operations']
+            ['GetRecords']['parameters']['outputFormat']['values']):
+            return self.exceptionreport('InvalidParameterValue',
+            'outputformat', 'Invalid outputFormat parameter value: %s' %
+            self.parent.kvp['outputformat'])
+
+        if 'resulttype' not in self.parent.kvp:
+            self.parent.kvp['resulttype'] = 'hits'
+
+        if self.parent.kvp['resulttype'] is not None:
+            if (self.parent.kvp['resulttype'] not in self.parent.context.model['operations']
+            ['GetRecords']['parameters']['resultType']['values']):
+                return self.exceptionreport('InvalidParameterValue',
+                'resulttype', 'Invalid resultType parameter value: %s' %
+                self.parent.kvp['resulttype'])
+
+        if (('elementname' not in self.parent.kvp or
+             len(self.parent.kvp['elementname']) == 0) and
+             self.parent.kvp['elementsetname'] not in
+             self.parent.context.model['operations']['GetRecords']['parameters']
+             ['ElementSetName']['values']):
+            return self.exceptionreport('InvalidParameterValue',
+            'elementsetname', 'Invalid ElementSetName parameter value: %s' %
+            self.parent.kvp['elementsetname'])
+
+        if ('elementname' in self.parent.kvp and
+            self.parent.requesttype == 'GET'):  # passed via GET
+            self.parent.kvp['elementname'] = self.parent.kvp['elementname'].split(',')
+            self.parent.kvp['elementsetname'] = 'summary'
+
+        if 'typenames' not in self.parent.kvp:
+            return self.exceptionreport('MissingParameterValue',
+            'typenames', 'Missing typenames parameter')
+
+        if ('typenames' in self.parent.kvp and
+            self.parent.requesttype == 'GET'):  # passed via GET
+            self.parent.kvp['typenames'] = self.parent.kvp['typenames'].split(',')
+
+        if 'typenames' in self.parent.kvp:
+            for tname in self.parent.kvp['typenames']:
+                if (tname not in self.parent.context.model['operations']['GetRecords']
+                    ['parameters']['typeNames']['values']):
+                    return self.exceptionreport('InvalidParameterValue',
+                    'typenames', 'Invalid typeNames parameter value: %s' %
+                    tname)
+
+        # check elementname's
+        if 'elementname' in self.parent.kvp:
+            for ename in self.parent.kvp['elementname']:
+                enamelist = self.parent.repository.queryables['_all'].keys()
+                if ename not in enamelist:
+                    return self.exceptionreport('InvalidParameterValue',
+                    'elementname', 'Invalid ElementName parameter value: %s' %
+                    ename)
+
+        if self.parent.kvp['resulttype'] == 'validate':
+            return self._write_acknowledgement()
+
+        maxrecords_cfg = -1  # not set in config server.maxrecords
+
+        if self.parent.config.has_option('server', 'maxrecords'):
+            maxrecords_cfg = int(self.parent.config.get('server', 'maxrecords'))
+
+        if 'maxrecords' not in self.parent.kvp:  # not specified by client
+            if maxrecords_cfg > -1:  # specified in config
+                self.parent.kvp['maxrecords'] = maxrecords_cfg
+            else:  # spec default
+                self.parent.kvp['maxrecords'] = 10
+        else:  # specified by client
+            if self.parent.kvp['maxrecords'] == '':
+                self.parent.kvp['maxrecords'] = 10
+            if maxrecords_cfg > -1:  # set in config
+                if int(self.parent.kvp['maxrecords']) > maxrecords_cfg:
+                    self.parent.kvp['maxrecords'] = maxrecords_cfg
+
+        if any(x in ['bbox', 'q', 'time'] for x in self.parent.kvp):
+            LOGGER.debug('OpenSearch Geo/Time parameters detected.')
+            self.parent.kvp['constraintlanguage'] = 'FILTER'
+            tmp_filter = opensearch.kvp2filterxml(self.parent.kvp, self.parent.context)
+            if tmp_filter is not "":
+                self.parent.kvp['constraint'] = tmp_filter
+                LOGGER.debug('OpenSearch Geo/Time parameters to Filter: %s.' % self.parent.kvp['constraint'])
+
+        if self.parent.requesttype == 'GET':
+            if 'constraint' in self.parent.kvp:
+                # GET request
+                LOGGER.debug('csw:Constraint passed over HTTP GET.')
+                if 'constraintlanguage' not in self.parent.kvp:
+                    return self.exceptionreport('MissingParameterValue',
+                    'constraintlanguage',
+                    'constraintlanguage required when constraint specified')
+                if (self.parent.kvp['constraintlanguage'] not in
+                self.parent.context.model['operations']['GetRecords']['parameters']
+                ['CONSTRAINTLANGUAGE']['values']):
+                    return self.exceptionreport('InvalidParameterValue',
+                    'constraintlanguage', 'Invalid constraintlanguage: %s'
+                    % self.parent.kvp['constraintlanguage'])
+                if self.parent.kvp['constraintlanguage'] == 'CQL_TEXT':
+                    tmp = self.parent.kvp['constraint']
+                    self.parent.kvp['constraint'] = {}
+                    self.parent.kvp['constraint']['type'] = 'cql'
+                    self.parent.kvp['constraint']['where'] = \
+                    self.parent._cql_update_queryables_mappings(tmp,
+                    self.parent.repository.queryables['_all'])
+                    self.parent.kvp['constraint']['values'] = {}
+                elif self.parent.kvp['constraintlanguage'] == 'FILTER':
+                    # validate filter XML
+                    try:
+                        schema = os.path.join(self.parent.config.get('server', 'home'),
+                        'core', 'schemas', 'ogc', 'filter', '1.1.0', 'filter.xsd')
+                        LOGGER.debug('Validating Filter %s.' %
+                        self.parent.kvp['constraint'])
+                        schema = etree.XMLSchema(file=schema)
+                        parser = etree.XMLParser(schema=schema, resolve_entities=False)
+                        doc = etree.fromstring(self.parent.kvp['constraint'], parser)
+                        LOGGER.debug('Filter is valid XML.')
+                        self.parent.kvp['constraint'] = {}
+                        self.parent.kvp['constraint']['type'] = 'filter'
+                        self.parent.kvp['constraint']['where'], self.parent.kvp['constraint']['values'] = \
+                        fes1.parse(doc,
+                        self.parent.repository.queryables['_all'],
+                        self.parent.repository.dbtype,
+                        self.parent.context.namespaces, self.parent.orm, self.parent.language['text'], self.parent.repository.fts)
+                    except Exception as err:
+                        errortext = \
+                        'Exception: document not valid.\nError: %s.' % str(err)
+
+                        LOGGER.debug(errortext)
+                        return self.exceptionreport('InvalidParameterValue',
+                        'constraint', 'Invalid Filter query: %s' % errortext)
+            else:
+                self.parent.kvp['constraint'] = {}
+
+        if 'sortby' not in self.parent.kvp:
+            self.parent.kvp['sortby'] = None
+        elif 'sortby' in self.parent.kvp and self.parent.requesttype == 'GET':
+            LOGGER.debug('Sorted query specified.')
+            tmp = self.parent.kvp['sortby']
+            self.parent.kvp['sortby'] = {}
+
+            try:
+                name, order = tmp.rsplit(':', 1)
+            except:
+                return self.exceptionreport('InvalidParameterValue',
+                'sortby', 'Invalid SortBy value: must be in the format\
+                propertyname:A or propertyname:D')
+
+            try:
+                self.parent.kvp['sortby']['propertyname'] = \
+                self.parent.repository.queryables['_all'][name]['dbcol']
+                if name.find('BoundingBox') != -1 or name.find('Envelope') != -1:
+                    # it's a spatial sort
+                    self.parent.kvp['sortby']['spatial'] = True
+            except Exception as err:
+                return self.exceptionreport('InvalidParameterValue',
+                'sortby', 'Invalid SortBy propertyname: %s' % name)
+
+            if order not in ['A', 'D']:
+                return self.exceptionreport('InvalidParameterValue',
+                'sortby', 'Invalid SortBy value: sort order must be "A" or "D"')
+
+            if order == 'D':
+                self.parent.kvp['sortby']['order'] = 'DESC'
+            else:
+                self.parent.kvp['sortby']['order'] = 'ASC'
+
+        if 'startposition' not in self.parent.kvp:
+            self.parent.kvp['startposition'] = 1
+
+        # query repository
+        LOGGER.debug('Querying repository with constraint: %s,\
+        sortby: %s, typenames: %s, maxrecords: %s, startposition: %s.' %
+        (self.parent.kvp['constraint'], self.parent.kvp['sortby'], self.parent.kvp['typenames'],
+        self.parent.kvp['maxrecords'], self.parent.kvp['startposition']))
+
+        try:
+            matched, results = self.parent.repository.query(
+            constraint=self.parent.kvp['constraint'],
+            sortby=self.parent.kvp['sortby'], typenames=self.parent.kvp['typenames'],
+            maxrecords=self.parent.kvp['maxrecords'],
+            startposition=int(self.parent.kvp['startposition'])-1)
+        except Exception as err:
+            return self.exceptionreport('InvalidParameterValue', 'constraint',
+            'Invalid query: %s' % err)
+
+        dsresults = []
+
+        if (self.parent.config.has_option('server', 'federatedcatalogues') and
+            'distributedsearch' in self.parent.kvp and
+            self.parent.kvp['distributedsearch'] and self.parent.kvp['hopcount'] > 0):
+            # do distributed search
+
+            LOGGER.debug('DistributedSearch specified (hopCount: %s).' %
+            self.parent.kvp['hopcount'])
+
+            from owslib.csw import CatalogueServiceWeb
+            from owslib.ows import ExceptionReport
+            for fedcat in \
+            self.parent.config.get('server', 'federatedcatalogues').split(','):
+                LOGGER.debug('Performing distributed search on federated \
+                catalogue: %s.' % fedcat)
+                remotecsw = CatalogueServiceWeb(fedcat, skip_caps=True)
+                try:
+                    remotecsw.getrecords2(xml=self.parent.request,
+                                          esn=self.parent.kvp['elementsetname'],
+                                          outputschema=self.parent.kvp['outputschema'])
+                    if hasattr(remotecsw, 'results'):
+                        LOGGER.debug(
+                        'Distributed search results from catalogue \
+                        %s: %s.' % (fedcat, remotecsw.results))
+
+                        remotecsw_matches = int(remotecsw.results['matches'])
+                        plural = 's' if remotecsw_matches != 1 else ''
+                        if remotecsw_matches > 0:
+                            matched = str(int(matched) + remotecsw_matches)
+                            dsresults.append(etree.Comment(
+                            ' %d result%s from %s ' %
+                            (remotecsw_matches, plural, fedcat)))
+
+                            dsresults.append(remotecsw.records)
+                except ExceptionReport as err:
+                    error_string = 'remote CSW %s returned exception: ' % fedcat
+                    dsresults.append(etree.Comment(
+                    ' %s\n\n%s ' % (error_string, err)))
+                    LOGGER.debug(str(err))
+                except Exception as err:
+                    error_string = 'remote CSW %s returned error: ' % fedcat
+                    dsresults.append(etree.Comment(
+                    ' %s\n\n%s ' % (error_string, err)))
+                    LOGGER.debug(str(err))
+
+        if int(matched) == 0:
+            returned = nextrecord = '0'
+        else:
+            if int(matched) < int(self.parent.kvp['maxrecords']):
+                returned = matched
+                nextrecord = '0'
+            else:
+                returned = str(self.parent.kvp['maxrecords'])
+                if int(self.parent.kvp['startposition']) + int(self.parent.kvp['maxrecords']) >= int(matched):
+                    nextrecord = '0'
+                else:
+                    nextrecord = str(int(self.parent.kvp['startposition']) + \
+                    int(self.parent.kvp['maxrecords']))
+
+        LOGGER.debug('Results: matched: %s, returned: %s, next: %s.' % \
+        (matched, returned, nextrecord))
+
+        node = etree.Element(util.nspath_eval('csw:GetRecordsResponse',
+        self.parent.context.namespaces),
+        nsmap=self.parent.context.namespaces, version='2.0.2')
+
+        node.attrib[util.nspath_eval('xsi:schemaLocation',
+        self.parent.context.namespaces)] = \
+        '%s %s/csw/2.0.2/CSW-discovery.xsd' % \
+        (self.parent.context.namespaces['csw'], self.parent.config.get('server', 'ogc_schemas_base'))
+
+        if 'requestid' in self.parent.kvp and self.parent.kvp['requestid'] is not None:
+            etree.SubElement(node, util.nspath_eval('csw:RequestId',
+            self.parent.context.namespaces)).text = self.parent.kvp['requestid']
+
+        etree.SubElement(node, util.nspath_eval('csw:SearchStatus',
+        self.parent.context.namespaces), timestamp=timestamp)
+
+        if 'where' not in self.parent.kvp['constraint'] and \
+        self.parent.kvp['resulttype'] is None:
+            returned = '0'
+
+        searchresults = etree.SubElement(node,
+        util.nspath_eval('csw:SearchResults', self.parent.context.namespaces),
+        numberOfRecordsMatched=matched, numberOfRecordsReturned=returned,
+        nextRecord=nextrecord, recordSchema=self.parent.kvp['outputschema'])
+
+        if self.parent.kvp['elementsetname'] is not None:
+            searchresults.attrib['elementSet'] = self.parent.kvp['elementsetname']
+
+        if 'where' not in self.parent.kvp['constraint'] \
+        and self.parent.kvp['resulttype'] is None:
+            LOGGER.debug('Empty result set returned.')
+            return node
+
+        if self.parent.kvp['resulttype'] == 'hits':
+            return node
+
+
+        if results is not None:
+            if len(results) < int(self.parent.kvp['maxrecords']):
+                max1 = len(results)
+            else:
+                max1 = int(self.parent.kvp['startposition']) + (int(self.parent.kvp['maxrecords'])-1)
+            LOGGER.debug('Presenting records %s - %s.' %
+            (self.parent.kvp['startposition'], max1))
+
+            for res in results:
+                try:
+                    if (self.parent.kvp['outputschema'] ==
+                        'http://www.opengis.net/cat/csw/2.0.2' and
+                        'csw:Record' in self.parent.kvp['typenames']):
+                        # serialize csw:Record inline
+                        searchresults.append(self._write_record(
+                        res, self.parent.repository.queryables['_all']))
+                    elif (self.parent.kvp['outputschema'] ==
+                        'http://www.opengis.net/cat/csw/2.0.2' and
+                        'csw:Record' not in self.parent.kvp['typenames']):
+                        # serialize into csw:Record model
+
+                        for prof in self.parent.profiles['loaded']:
+                            # find source typename
+                            if self.parent.profiles['loaded'][prof].typename in \
+                            self.parent.kvp['typenames']:
+                                typename = self.parent.profiles['loaded'][prof].typename
+                                break
+
+                        util.transform_mappings(self.parent.repository.queryables['_all'],
+                        self.parent.context.model['typenames'][typename]\
+                        ['mappings']['csw:Record'], reverse=True)
+
+                        searchresults.append(self._write_record(
+                        res, self.parent.repository.queryables['_all']))
+                    elif self.parent.kvp['outputschema'] in self.parent.outputschemas.keys():  # use outputschema serializer
+                        searchresults.append(self.parent.outputschemas[self.parent.kvp['outputschema']].write_record(res, self.parent.kvp['elementsetname'], self.parent.context, self.parent.config.get('server', 'url')))
+                    else:  # use profile serializer
+                        searchresults.append(
+                        self.parent.profiles['loaded'][self.parent.kvp['outputschema']].\
+                        write_record(res, self.parent.kvp['elementsetname'],
+                        self.parent.kvp['outputschema'],
+                        self.parent.repository.queryables['_all']))
+                except Exception as err:
+                    self.parent.response = self.exceptionreport(
+                    'NoApplicableCode', 'service',
+                    'Record serialization failed: %s' % str(err))
+                    return self.parent.response
+
+        if len(dsresults) > 0:  # return DistributedSearch results
+            for resultset in dsresults:
+                if isinstance(resultset, etree._Comment):
+                    searchresults.append(resultset)
+                for rec in resultset:
+                    searchresults.append(etree.fromstring(resultset[rec].xml, self.parent.context.parser))
+
+        if 'responsehandler' in self.parent.kvp:  # process the handler
+            self.parent._process_responsehandler(etree.tostring(node,
+            pretty_print=self.parent.pretty_print))
+        else:
+            return node
+
+    def getrecordbyid(self, raw=False):
+        ''' Handle GetRecordById request '''
+
+        if 'id' not in self.parent.kvp:
+            return self.exceptionreport('MissingParameterValue', 'id',
+            'Missing id parameter')
+        if len(self.parent.kvp['id']) < 1:
+            return self.exceptionreport('InvalidParameterValue', 'id',
+            'Invalid id parameter')
+        if 'outputschema' not in self.parent.kvp:
+            self.parent.kvp['outputschema'] = self.parent.context.namespaces['csw']
+
+        if self.parent.requesttype == 'GET':
+            self.parent.kvp['id'] = self.parent.kvp['id'].split(',')
+
+        if ('outputformat' in self.parent.kvp and
+            self.parent.kvp['outputformat'] not in
+            self.parent.context.model['operations']['GetRecordById']['parameters']
+            ['outputFormat']['values']):
+            return self.exceptionreport('InvalidParameterValue',
+            'outputformat', 'Invalid outputformat parameter %s' %
+            self.parent.kvp['outputformat'])
+
+        if ('outputschema' in self.parent.kvp and self.parent.kvp['outputschema'] not in
+            self.parent.context.model['operations']['GetRecordById']['parameters']
+            ['outputSchema']['values']):
+            return self.exceptionreport('InvalidParameterValue',
+            'outputschema', 'Invalid outputschema parameter %s' %
+            self.parent.kvp['outputschema'])
+
+        if 'elementsetname' not in self.parent.kvp:
+            self.parent.kvp['elementsetname'] = 'summary'
+        else:
+            if (self.parent.kvp['elementsetname'] not in
+                self.parent.context.model['operations']['GetRecordById']['parameters']
+                ['ElementSetName']['values']):
+                return self.exceptionreport('InvalidParameterValue',
+                'elementsetname', 'Invalid elementsetname parameter %s' %
+                self.parent.kvp['elementsetname'])
+
+        node = etree.Element(util.nspath_eval('csw:GetRecordByIdResponse',
+        self.parent.context.namespaces), nsmap=self.parent.context.namespaces)
+
+        node.attrib[util.nspath_eval('xsi:schemaLocation',
+        self.parent.context.namespaces)] = '%s %s/csw/2.0.2/CSW-discovery.xsd' % \
+        (self.parent.context.namespaces['csw'], self.parent.config.get('server', 'ogc_schemas_base'))
+
+        # query repository
+        LOGGER.debug('Querying repository with ids: %s.' % self.parent.kvp['id'][0])
+        results = self.parent.repository.query_ids(self.parent.kvp['id'])
+
+        if raw:  # GetRepositoryItem request
+            LOGGER.debug('GetRepositoryItem request.')
+            if len(results) > 0:
+                return etree.fromstring(util.getqattr(results[0],
+                self.parent.context.md_core_model['mappings']['pycsw:XML']), self.parent.context.parser)
+
+        for result in results:
+            if (util.getqattr(result,
+            self.parent.context.md_core_model['mappings']['pycsw:Typename']) == 'csw:Record'
+            and self.parent.kvp['outputschema'] ==
+            'http://www.opengis.net/cat/csw/2.0.2'):
+                # serialize record inline
+                node.append(self._write_record(
+                result, self.parent.repository.queryables['_all']))
+            elif (self.parent.kvp['outputschema'] ==
+                'http://www.opengis.net/cat/csw/2.0.2'):
+                # serialize into csw:Record model
+                typename = None
+
+                for prof in self.parent.profiles['loaded']:  # find source typename
+                    if self.parent.profiles['loaded'][prof].typename in \
+                    [util.getqattr(result, self.parent.context.md_core_model['mappings']['pycsw:Typename'])]:
+                        typename = self.parent.profiles['loaded'][prof].typename
+                        break
+
+                if typename is not None:
+                    util.transform_mappings(self.parent.repository.queryables['_all'],
+                    self.parent.context.model['typenames'][typename]\
+                    ['mappings']['csw:Record'], reverse=True)
+
+                node.append(self._write_record(
+                result, self.parent.repository.queryables['_all']))
+            elif self.parent.kvp['outputschema'] in self.parent.outputschemas.keys():  # use outputschema serializer
+                node.append(self.parent.outputschemas[self.parent.kvp['outputschema']].write_record(result, self.parent.kvp['elementsetname'], self.parent.context, self.parent.config.get('server', 'url')))
+            else:  # it's a profile output
+                node.append(
+                self.parent.profiles['loaded'][self.parent.kvp['outputschema']].write_record(
+                result, self.parent.kvp['elementsetname'],
+                self.parent.kvp['outputschema'], self.parent.repository.queryables['_all']))
+
+        if raw and len(results) == 0:
+            return None
+
+        return node
+
+    def getrepositoryitem(self):
+        ''' Handle GetRepositoryItem request '''
+
+        # similar to GetRecordById without csw:* wrapping
+        node = self.parent.getrecordbyid(raw=True)
+        if node is None:
+            return self.exceptionreport('NotFound', 'id',
+            'No repository item found for \'%s\'' % self.parent.kvp['id'])
+        else:
+            return node
+
+    def transaction(self):
+        ''' Handle Transaction request '''
+
+        try:
+            self.parent._test_manager()
+        except Exception as err:
+            return self.exceptionreport('NoApplicableCode', 'transaction',
+            str(err))
+
+        inserted = 0
+        updated = 0
+        deleted = 0
+
+        insertresults = []
+
+        LOGGER.debug('Transaction list: %s' % self.parent.kvp['transactions'])
+
+        for ttype in self.parent.kvp['transactions']:
+            if ttype['type'] == 'insert':
+                try:
+                    record = metadata.parse_record(self.parent.context,
+                    ttype['xml'], self.parent.repository)[0]
+                except Exception as err:
+                    return self.exceptionreport('NoApplicableCode', 'insert',
+                    'Transaction (insert) failed: record parsing failed: %s' \
+                    % str(err))
+
+                LOGGER.debug('Transaction operation: %s' % record)
+
+                if not hasattr(record,
+                self.parent.context.md_core_model['mappings']['pycsw:Identifier']):
+                    return self.exceptionreport('NoApplicableCode',
+                    'insert', 'Record requires an identifier')
+
+                # insert new record
+                try:
+                    self.parent.repository.insert(record, 'local',
+                    util.get_today_and_now())
+
+                    inserted += 1
+                    insertresults.append(
+                    {'identifier': getattr(record,
+                    self.parent.context.md_core_model['mappings']['pycsw:Identifier']),
+                    'title': getattr(record,
+                    self.parent.context.md_core_model['mappings']['pycsw:Title'])})
+                except Exception as err:
+                    return self.exceptionreport('NoApplicableCode',
+                    'insert', 'Transaction (insert) failed: %s.' % str(err))
+
+            elif ttype['type'] == 'update':
+                if 'constraint' not in ttype:
+                    # update full existing resource in repository
+                    try:
+                        record = metadata.parse_record(self.parent.context,
+                        ttype['xml'], self.parent.repository)[0]
+                        identifier = getattr(record,
+                        self.parent.context.md_core_model['mappings']['pycsw:Identifier'])
+                    except Exception as err:
+                        return self.exceptionreport('NoApplicableCode', 'insert',
+                        'Transaction (update) failed: record parsing failed: %s' \
+                        % str(err))
+
+                    # query repository to see if record already exists
+                    LOGGER.debug('checking if record exists (%s)' % \
+                    identifier)
+
+                    results = self.parent.repository.query_ids(ids=[identifier])
+
+                    if len(results) == 0:
+                        LOGGER.debug('id %s does not exist in repository' % \
+                        identifier)
+                    else:  # existing record, it's an update
+                        try:
+                            self.parent.repository.update(record)
+                            updated += 1
+                        except Exception as err:
+                            return self.exceptionreport('NoApplicableCode',
+                            'update',
+                            'Transaction (update) failed: %s.' % str(err))
+                else:  # update by record property and constraint
+                    # get / set XPath for property names
+                    for rp in ttype['recordproperty']:
+                        if rp['name'] not in self.parent.repository.queryables['_all']:
+                            # is it an XPath?
+                            if rp['name'].find('/') != -1:
+                                # scan outputschemas; if match, bind
+                                for osch in self.parent.outputschemas.values():
+                                    for key, value in osch.XPATH_MAPPINGS.items():
+                                        if value == rp['name']:  # match
+                                            rp['rp'] = {'xpath': value, 'name': key}
+                                            rp['rp']['dbcol'] = self.parent.repository.queryables['_all'][key]
+                                            break
+                            else:
+                                return self.exceptionreport('NoApplicableCode',
+                                       'update', 'Transaction (update) failed: invalid property2: %s.' % str(rp['name']))
+                        else:
+                            rp['rp']= \
+                            self.parent.repository.queryables['_all'][rp['name']]
+
+                    LOGGER.debug('Record Properties: %s.' %
+                    ttype['recordproperty'])
+                    try:
+                        updated += self.parent.repository.update(record=None,
+                        recprops=ttype['recordproperty'],
+                        constraint=ttype['constraint'])
+                    except Exception as err:
+                        return self.exceptionreport('NoApplicableCode',
+                        'update',
+                        'Transaction (update) failed: %s.' % str(err))
+
+            elif ttype['type'] == 'delete':
+                deleted += self.parent.repository.delete(ttype['constraint'])
+
+        node = etree.Element(util.nspath_eval('csw:TransactionResponse',
+        self.parent.context.namespaces), nsmap=self.parent.context.namespaces, version='2.0.2')
+
+        node.attrib[util.nspath_eval('xsi:schemaLocation',
+        self.parent.context.namespaces)] = '%s %s/csw/2.0.2/CSW-publication.xsd' % \
+        (self.parent.context.namespaces['csw'], self.parent.config.get('server', 'ogc_schemas_base'))
+
+        node.append(
+        self._write_transactionsummary(
+        inserted=inserted, updated=updated, deleted=deleted))
+
+        if (len(insertresults) > 0 and self.parent.kvp['verboseresponse']):
+            # show insert result identifiers
+            node.append(self._write_verboseresponse(insertresults))
+
+        return node
+
+    def harvest(self):
+        ''' Handle Harvest request '''
+
+        service_identifier = None
+        old_identifier = None
+        deleted = []
+
+        try:
+            self.parent._test_manager()
+        except Exception as err:
+            return self.exceptionreport('NoApplicableCode', 'harvest', str(err))
+
+        if self.parent.requesttype == 'GET':
+            if 'resourcetype' not in self.parent.kvp:
+                return self.exceptionreport('MissingParameterValue',
+                'resourcetype', 'Missing resourcetype parameter')
+            if 'source' not in self.parent.kvp:
+                return self.exceptionreport('MissingParameterValue',
+                'source', 'Missing source parameter')
+
+        # validate resourcetype
+        if (self.parent.kvp['resourcetype'] not in
+            self.parent.context.model['operations']['Harvest']['parameters']['ResourceType']
+            ['values']):
+            return self.exceptionreport('InvalidParameterValue',
+            'resourcetype', 'Invalid resource type parameter: %s.\
+            Allowable resourcetype values: %s' % (self.parent.kvp['resourcetype'],
+            ','.join(self.parent.context.model['operations']['Harvest']['parameters']
+            ['ResourceType']['values'])))
+
+        if (self.parent.kvp['resourcetype'].find('opengis.net') == -1 and
+            self.parent.kvp['resourcetype'].find('urn:geoss:waf') == -1):
+            # fetch content-based resource
+            LOGGER.debug('Fetching resource %s' % self.parent.kvp['source'])
+            try:
+                content = util.http_request('GET', self.parent.kvp['source'])
+            except Exception as err:
+                errortext = 'Error fetching resource %s.\nError: %s.' % \
+                (self.parent.kvp['source'], str(err))
+                LOGGER.debug(errortext)
+                return self.exceptionreport('InvalidParameterValue', 'source',
+                errortext)
+        else:  # it's a service URL
+            content = self.parent.kvp['source']
+            # query repository to see if service already exists
+            LOGGER.debug('checking if service exists (%s)' % content)
+            results = self.parent.repository.query_source(content)
+
+            if len(results) > 0:  # exists, keep identifier for update
+                LOGGER.debug('Service already exists, keeping identifier and results')
+                service_identifier = getattr(results[0], self.parent.context.md_core_model['mappings']['pycsw:Identifier'])
+                service_results = results
+                LOGGER.debug('Identifier is %s' % service_identifier)
+            #    return self.exceptionreport('NoApplicableCode', 'source',
+            #    'Insert failed: service %s already in repository' % content)
+
+
+        if hasattr(self.parent.repository, 'local_ingest') and self.parent.repository.local_ingest:
+            updated = 0
+            deleted = []
+            try:
+                ir = self.parent.repository.insert(self.parent.kvp['resourcetype'], self.parent.kvp['source'])
+                inserted = len(ir)
+            except Exception as err:
+                return self.exceptionreport('NoApplicableCode',
+                'source', 'Harvest (insert) failed: %s.' % str(err))
+        else:
+            # parse resource into record
+            try:
+                records_parsed = metadata.parse_record(self.parent.context,
+                content, self.parent.repository, self.parent.kvp['resourcetype'],
+                pagesize=self.parent.csw_harvest_pagesize)
+            except Exception as err:
+                LOGGER.exception(err)
+                return self.exceptionreport('NoApplicableCode', 'source',
+                'Harvest failed: record parsing failed: %s' % str(err))
+
+            inserted = 0
+            updated = 0
+            ir = []
+
+            LOGGER.debug('Total Records parsed: %d' % len(records_parsed))
+            for record in records_parsed:
+                if self.parent.kvp['resourcetype'] == 'urn:geoss:waf':
+                    src = record.source
+                else:
+                    src = self.parent.kvp['source']
+
+                setattr(record, self.parent.context.md_core_model['mappings']['pycsw:Source'],
+                        src)
+
+                setattr(record, self.parent.context.md_core_model['mappings']['pycsw:InsertDate'],
+                util.get_today_and_now())
+
+                identifier = getattr(record,
+                self.parent.context.md_core_model['mappings']['pycsw:Identifier'])
+                source = getattr(record,
+                self.parent.context.md_core_model['mappings']['pycsw:Source'])
+                insert_date = getattr(record,
+                self.parent.context.md_core_model['mappings']['pycsw:InsertDate'])
+                title = getattr(record,
+                self.parent.context.md_core_model['mappings']['pycsw:Title'])
+
+                record_type = getattr(record, self.parent.context.md_core_model['mappings']['pycsw:Type'])
+
+                record_identifier = getattr(record, self.parent.context.md_core_model['mappings']['pycsw:Identifier'])
+
+                if record_type == 'service' and service_identifier is not None:  # service endpoint
+                    LOGGER.debug('Replacing service identifier from %s to %s' % (record_identifier, service_identifier))
+                    old_identifier = record_identifier
+                    identifier = record_identifier = service_identifier
+                if (record_type != 'service' and service_identifier is not None
+                    and old_identifier is not None):  # service resource
+                    if record_identifier.find(old_identifier) != -1:
+                        new_identifier = record_identifier.replace(old_identifier, service_identifier)
+                        LOGGER.debug('Replacing service resource identifier from %s to %s' % (record_identifier, new_identifier))
+                        identifier = record_identifier = new_identifier
+
+                ir.append({'identifier': identifier, 'title': title})
+
+                results = []
+                if not self.parent.config.has_option('repository', 'source'):
+                    # query repository to see if record already exists
+                    LOGGER.debug('checking if record exists (%s)' % identifier)
+                    results = self.parent.repository.query_ids(ids=[identifier])
+
+                    if len(results) == 0:  # check for service identifier
+                        LOGGER.debug('checking if service id exists (%s)' % service_identifier)
+                        results = self.parent.repository.query_ids(ids=[service_identifier])
+
+                LOGGER.debug(str(results))
+
+                if len(results) == 0:  # new record, it's a new insert
+                    inserted += 1
+                    try:
+                        tmp = self.parent.repository.insert(record, source, insert_date)
+                        if tmp is not None: ir = tmp
+                    except Exception as err:
+                        return self.exceptionreport('NoApplicableCode',
+                        'source', 'Harvest (insert) failed: %s.' % str(err))
+                else:  # existing record, it's an update
+                    if source != results[0].source:
+                        # same identifier, but different source
+                        return self.exceptionreport('NoApplicableCode',
+                        'source', 'Insert failed: identifier %s in repository\
+                        has source %s.' % (identifier, source))
+
+                    try:
+                        self.parent.repository.update(record)
+                    except Exception as err:
+                        return self.exceptionreport('NoApplicableCode',
+                        'source', 'Harvest (update) failed: %s.' % str(err))
+                    updated += 1
+
+            if service_identifier is not None:
+                fresh_records = [str(i['identifier']) for i in ir]
+                existing_records = [str(i.identifier) for i in service_results]
+
+                deleted = set(existing_records) - set(fresh_records)
+                LOGGER.debug('Records to delete: %s' % str(deleted))
+
+                for to_delete in deleted:
+                    delete_constraint = {
+                        'type': 'filter',
+                        'values': [to_delete],
+                        'where': 'identifier = :pvalue0'
+                    }
+                    self.parent.repository.delete(delete_constraint)
+
+        node = etree.Element(util.nspath_eval('csw:HarvestResponse',
+        self.parent.context.namespaces), nsmap=self.parent.context.namespaces)
+
+        node.attrib[util.nspath_eval('xsi:schemaLocation',
+        self.parent.context.namespaces)] = \
+        '%s %s/csw/2.0.2/CSW-publication.xsd' % (self.parent.context.namespaces['csw'],
+        self.parent.config.get('server', 'ogc_schemas_base'))
+
+        node2 = etree.SubElement(node,
+        util.nspath_eval('csw:TransactionResponse',
+        self.parent.context.namespaces), version='2.0.2')
+
+        node2.append(
+        self._write_transactionsummary(inserted=len(ir), updated=updated,
+                                       deleted=len(deleted)))
+
+        if inserted > 0:
+            # show insert result identifiers
+            node2.append(self._write_verboseresponse(ir))
+
+        if 'responsehandler' in self.parent.kvp:  # process the handler
+            self.parent._process_responsehandler(etree.tostring(node,
+            pretty_print=self.parent.pretty_print))
+        else:
+            return node
+
+    def _write_record(self, recobj, queryables):
+        ''' Generate csw:Record '''
+        if self.parent.kvp['elementsetname'] == 'brief':
+            elname = 'BriefRecord'
+        elif self.parent.kvp['elementsetname'] == 'summary':
+            elname = 'SummaryRecord'
+        else:
+            elname = 'Record'
+
+        record = etree.Element(util.nspath_eval('csw:%s' % elname,
+                 self.parent.context.namespaces))
+
+        if ('elementname' in self.parent.kvp and
+            len(self.parent.kvp['elementname']) > 0):
+            for elemname in self.parent.kvp['elementname']:
+                if (elemname.find('BoundingBox') != -1 or
+                    elemname.find('Envelope') != -1):
+                    bboxel = write_boundingbox(util.getqattr(recobj,
+                    self.parent.context.md_core_model['mappings']['pycsw:BoundingBox']),
+                    self.parent.context.namespaces)
+                    if bboxel is not None:
+                        record.append(bboxel)
+                else:
+                    value = util.getqattr(recobj, queryables[elemname]['dbcol'])
+                    if value:
+                        etree.SubElement(record,
+                        util.nspath_eval(elemname,
+                        self.parent.context.namespaces)).text = value
+        elif 'elementsetname' in self.parent.kvp:
+            if (self.parent.kvp['elementsetname'] == 'full' and
+            util.getqattr(recobj, self.parent.context.md_core_model['mappings']\
+            ['pycsw:Typename']) == 'csw:Record' and
+            util.getqattr(recobj, self.parent.context.md_core_model['mappings']\
+            ['pycsw:Schema']) == 'http://www.opengis.net/cat/csw/2.0.2' and
+            util.getqattr(recobj, self.parent.context.md_core_model['mappings']\
+            ['pycsw:Type']) != 'service'):
+                # dump record as is and exit
+                return etree.fromstring(util.getqattr(recobj,
+                self.parent.context.md_core_model['mappings']['pycsw:XML']), self.parent.context.parser)
+
+            etree.SubElement(record,
+            util.nspath_eval('dc:identifier', self.parent.context.namespaces)).text = \
+            util.getqattr(recobj,
+            self.parent.context.md_core_model['mappings']['pycsw:Identifier'])
+
+            for i in ['dc:title', 'dc:type']:
+                val = util.getqattr(recobj, queryables[i]['dbcol'])
+                if not val:
+                    val = ''
+                etree.SubElement(record, util.nspath_eval(i,
+                self.parent.context.namespaces)).text = val
+
+            if self.parent.kvp['elementsetname'] in ['summary', 'full']:
+                # add summary elements
+                keywords = util.getqattr(recobj, queryables['dc:subject']['dbcol'])
+                if keywords is not None:
+                    for keyword in keywords.split(','):
+                        etree.SubElement(record,
+                        util.nspath_eval('dc:subject',
+                        self.parent.context.namespaces)).text = keyword
+
+                val = util.getqattr(recobj, self.parent.context.md_core_model['mappings']['pycsw:TopicCategory'])
+                if val:
+                    etree.SubElement(record,
+                    util.nspath_eval('dc:subject',
+                    self.parent.context.namespaces), scheme='http://www.isotc211.org/2005/resources/Codelist/gmxCodelists.xml#MD_TopicCategoryCode').text = val
+
+                val = util.getqattr(recobj, queryables['dc:format']['dbcol'])
+                if val:
+                    etree.SubElement(record,
+                    util.nspath_eval('dc:format',
+                    self.parent.context.namespaces)).text = val
+
+                # links
+                rlinks = util.getqattr(recobj,
+                self.parent.context.md_core_model['mappings']['pycsw:Links'])
+
+                if rlinks:
+                    links = rlinks.split('^')
+                    for link in links:
+                        linkset = link.split(',')
+                        etree.SubElement(record,
+                        util.nspath_eval('dct:references',
+                        self.parent.context.namespaces),
+                        scheme=linkset[2]).text = linkset[-1]
+
+                for i in ['dc:relation', 'dct:modified', 'dct:abstract']:
+                    val = util.getqattr(recobj, queryables[i]['dbcol'])
+                    if val is not None:
+                        etree.SubElement(record,
+                        util.nspath_eval(i, self.parent.context.namespaces)).text = val
+
+            if self.parent.kvp['elementsetname'] == 'full':  # add full elements
+                for i in ['dc:date', 'dc:creator', \
+                'dc:publisher', 'dc:contributor', 'dc:source', \
+                'dc:language', 'dc:rights']:
+                    val = util.getqattr(recobj, queryables[i]['dbcol'])
+                    if val:
+                        etree.SubElement(record,
+                        util.nspath_eval(i, self.parent.context.namespaces)).text = val
+
+            # always write out ows:BoundingBox
+            bboxel = write_boundingbox(getattr(recobj,
+            self.parent.context.md_core_model['mappings']['pycsw:BoundingBox']),
+            self.parent.context.namespaces)
+
+            if bboxel is not None:
+                record.append(bboxel)
+        return record
+
+    def _parse_constraint(self, element):
+        ''' Parse csw:Constraint '''
+
+        query = {}
+
+        tmp = element.find(util.nspath_eval('ogc:Filter', self.parent.context.namespaces))
+        if tmp is not None:
+            LOGGER.debug('Filter constraint specified.')
+            try:
+                query['type'] = 'filter'
+                query['where'], query['values'] = fes1.parse(tmp,
+                self.parent.repository.queryables['_all'], self.parent.repository.dbtype,
+                self.parent.context.namespaces, self.parent.orm, self.parent.language['text'], self.parent.repository.fts)
+            except Exception as err:
+                return 'Invalid Filter request: %s' % err
+        tmp = element.find(util.nspath_eval('csw:CqlText', self.parent.context.namespaces))
+        if tmp is not None:
+            LOGGER.debug('CQL specified: %s.' % tmp.text)
+            query['type'] = 'cql'
+            query['where'] = self.parent._cql_update_queryables_mappings(tmp.text,
+            self.parent.repository.queryables['_all'])
+            query['values'] = {}
+        return query
+
+    def parse_postdata(self, postdata):
+        ''' Parse POST XML '''
+
+        request = {}
+        try:
+            LOGGER.debug('Parsing %s.' % postdata)
+            doc = etree.fromstring(postdata, self.parent.context.parser)
+        except Exception as err:
+            errortext = \
+            'Exception: document not well-formed.\nError: %s.' % str(err)
+
+            LOGGER.debug(errortext)
+            return errortext
+
+        # if this is a SOAP request, get to SOAP-ENV:Body/csw:*
+        if (doc.tag == util.nspath_eval('soapenv:Envelope',
+            self.parent.context.namespaces)):
+
+            LOGGER.debug('SOAP request specified.')
+            self.parent.soap = True
+
+            doc = doc.find(
+            util.nspath_eval('soapenv:Body',
+            self.parent.context.namespaces)).xpath('child::*')[0]
+
+        if (doc.tag in [util.nspath_eval('csw:Transaction',
+            self.parent.context.namespaces), util.nspath_eval('csw:Harvest',
+            self.parent.context.namespaces)]):
+            schema = os.path.join(self.parent.config.get('server', 'home'),
+            'core', 'schemas', 'ogc', 'csw', '2.0.2', 'CSW-publication.xsd')
+        else:
+            schema = os.path.join(self.parent.config.get('server', 'home'),
+            'core', 'schemas', 'ogc', 'csw', '2.0.2', 'CSW-discovery.xsd')
+
+        try:
+            # it is virtually impossible to validate a csw:Transaction
+            # csw:Insert|csw:Update (with single child) XML document.
+            # Only validate non csw:Transaction XML
+
+            if doc.find('.//%s' % util.nspath_eval('csw:Insert',
+            self.parent.context.namespaces)) is None and \
+            len(doc.xpath('//csw:Update/child::*',
+            namespaces=self.parent.context.namespaces)) == 0:
+
+                LOGGER.debug('Validating %s.' % postdata)
+                schema = etree.XMLSchema(file=schema)
+                parser = etree.XMLParser(schema=schema, resolve_entities=False)
+                if hasattr(self.parent, 'soap') and self.parent.soap:
+                # validate the body of the SOAP request
+                    doc = etree.fromstring(etree.tostring(doc), parser)
+                else:  # validate the request normally
+                    doc = etree.fromstring(postdata, parser)
+                LOGGER.debug('Request is valid XML.')
+            else:  # parse Transaction without validation
+                doc = etree.fromstring(postdata, self.parent.context.parser)
+        except Exception as err:
+            errortext = \
+            'Exception: the document is not valid.\nError: %s' % str(err)
+            LOGGER.debug(errortext)
+            return errortext
+
+        request['request'] = util.xmltag_split(doc.tag)
+        LOGGER.debug('Request operation %s specified.' % request['request'])
+        tmp = doc.find('.').attrib.get('service')
+        if tmp is not None:
+            request['service'] = tmp
+
+        tmp = doc.find('.').attrib.get('version')
+        if tmp is not None:
+            request['version'] = tmp
+
+        tmp = doc.find('.//%s' % util.nspath_eval('ows:Version',
+        self.parent.context.namespaces))
+
+        if tmp is not None:
+            request['version'] = tmp.text
+
+        tmp = doc.find('.').attrib.get('updateSequence')
+        if tmp is not None:
+            request['updatesequence'] = tmp
+
+        # GetCapabilities
+        if request['request'] == 'GetCapabilities':
+            tmp = doc.find(util.nspath_eval('ows:Sections',
+                  self.parent.context.namespaces))
+            if tmp is not None:
+                request['sections'] = ','.join([section.text for section in \
+                doc.findall(util.nspath_eval('ows:Sections/ows:Section',
+                self.parent.context.namespaces))])
+
+        # DescribeRecord
+        if request['request'] == 'DescribeRecord':
+            request['typename'] = [typename.text for typename in \
+            doc.findall(util.nspath_eval('csw:TypeName',
+            self.parent.context.namespaces))]
+
+            tmp = doc.find('.').attrib.get('schemaLanguage')
+            if tmp is not None:
+                request['schemalanguage'] = tmp
+
+            tmp = doc.find('.').attrib.get('outputFormat')
+            if tmp is not None:
+                request['outputformat'] = tmp
+
+        # GetDomain
+        if request['request'] == 'GetDomain':
+            tmp = doc.find(util.nspath_eval('csw:ParameterName',
+                  self.parent.context.namespaces))
+            if tmp is not None:
+                request['parametername'] = tmp.text
+
+            tmp = doc.find(util.nspath_eval('csw:PropertyName',
+                  self.parent.context.namespaces))
+            if tmp is not None:
+                request['propertyname'] = tmp.text
+
+        # GetRecords
+        if request['request'] == 'GetRecords':
+            tmp = doc.find('.').attrib.get('outputSchema')
+            request['outputschema'] = tmp if tmp is not None \
+            else self.parent.context.namespaces['csw']
+
+            tmp = doc.find('.').attrib.get('resultType')
+            request['resulttype'] = tmp if tmp is not None else None
+
+            tmp = doc.find('.').attrib.get('outputFormat')
+            request['outputformat'] = tmp if tmp is not None \
+            else 'application/xml'
+
+            tmp = doc.find('.').attrib.get('startPosition')
+            request['startposition'] = tmp if tmp is not None else 1
+
+            tmp = doc.find('.').attrib.get('requestId')
+            request['requestid'] = tmp if tmp is not None else None
+
+            tmp = doc.find('.').attrib.get('maxRecords')
+            if tmp is not None:
+                request['maxrecords'] = tmp
+
+            tmp = doc.find(util.nspath_eval('csw:DistributedSearch',
+                  self.parent.context.namespaces))
+            if tmp is not None:
+                request['distributedsearch'] = True
+                hopcount = tmp.attrib.get('hopCount')
+                request['hopcount'] = int(hopcount)-1 if hopcount is not None \
+                else 1
+            else:
+                request['distributedsearch'] = False
+
+            tmp = doc.find(util.nspath_eval('csw:ResponseHandler',
+                  self.parent.context.namespaces))
+            if tmp is not None:
+                request['responsehandler'] = tmp.text
+
+            tmp = doc.find(util.nspath_eval('csw:Query/csw:ElementSetName',
+                  self.parent.context.namespaces))
+            request['elementsetname'] = tmp.text if tmp is not None else None
+
+            tmp = doc.find(util.nspath_eval(
+            'csw:Query', self.parent.context.namespaces)).attrib.get('typeNames')
+            request['typenames'] = tmp.split() if tmp is not None \
+            else 'csw:Record'
+
+            request['elementname'] = [elname.text for elname in \
+            doc.findall(util.nspath_eval('csw:Query/csw:ElementName',
+            self.parent.context.namespaces))]
+
+            request['constraint'] = {}
+            tmp = doc.find(util.nspath_eval('csw:Query/csw:Constraint',
+            self.parent.context.namespaces))
+
+            if tmp is not None:
+                request['constraint'] = self._parse_constraint(tmp)
+                if isinstance(request['constraint'], str):  # parse error
+                    return 'Invalid Constraint: %s' % request['constraint']
+            else:
+                LOGGER.debug('No csw:Constraint (ogc:Filter or csw:CqlText) \
+                specified.')
+
+            tmp = doc.find(util.nspath_eval('csw:Query/ogc:SortBy',
+                  self.parent.context.namespaces))
+            if tmp is not None:
+                LOGGER.debug('Sorted query specified.')
+                request['sortby'] = {}
+
+
+                try:
+                    elname = tmp.find(util.nspath_eval(
+                    'ogc:SortProperty/ogc:PropertyName',
+                    self.parent.context.namespaces)).text
+
+                    request['sortby']['propertyname'] = \
+                    self.parent.repository.queryables['_all'][elname]['dbcol']
+
+                    if (elname.find('BoundingBox') != -1 or
+                        elname.find('Envelope') != -1):
+                        # it's a spatial sort
+                        request['sortby']['spatial'] = True
+                except Exception as err:
+                    errortext = \
+                    'Invalid ogc:SortProperty/ogc:PropertyName: %s' % str(err)
+                    LOGGER.debug(errortext)
+                    return errortext
+
+                tmp2 =  tmp.find(util.nspath_eval(
+                'ogc:SortProperty/ogc:SortOrder', self.parent.context.namespaces))
+                request['sortby']['order'] = tmp2.text if tmp2 is not None \
+                else 'ASC'
+            else:
+                request['sortby'] = None
+
+        # GetRecordById
+        if request['request'] == 'GetRecordById':
+            request['id'] = [id1.text for id1 in \
+            doc.findall(util.nspath_eval('csw:Id', self.parent.context.namespaces))]
+
+            tmp = doc.find(util.nspath_eval('csw:ElementSetName',
+                  self.parent.context.namespaces))
+            request['elementsetname'] = tmp.text if tmp is not None \
+            else 'summary'
+
+            tmp = doc.find('.').attrib.get('outputSchema')
+            request['outputschema'] = tmp if tmp is not None \
+            else self.parent.context.namespaces['csw']
+
+            tmp = doc.find('.').attrib.get('outputFormat')
+            if tmp is not None:
+                request['outputformat'] = tmp
+
+        # Transaction
+        if request['request'] == 'Transaction':
+            request['verboseresponse'] = True
+            tmp = doc.find('.').attrib.get('verboseResponse')
+            if tmp is not None:
+                if tmp in ['false', '0']:
+                    request['verboseresponse'] = False
+
+            tmp = doc.find('.').attrib.get('requestId')
+            request['requestid'] = tmp if tmp is not None else None
+
+            request['transactions'] = []
+
+            for ttype in \
+            doc.xpath('//csw:Insert', namespaces=self.parent.context.namespaces):
+                tname = ttype.attrib.get('typeName')
+
+                for mdrec in ttype.xpath('child::*'):
+                    xml = mdrec
+                    request['transactions'].append(
+                    {'type': 'insert', 'typename': tname, 'xml': xml})
+
+            for ttype in \
+            doc.xpath('//csw:Update', namespaces=self.parent.context.namespaces):
+                child = ttype.xpath('child::*')
+                update = {'type': 'update'}
+
+                if len(child) == 1:  # it's a wholesale update
+                    update['xml'] = child[0]
+                else:  # it's a RecordProperty with Constraint Update
+                    update['recordproperty'] = []
+
+                    for recprop in ttype.findall(
+                    util.nspath_eval('csw:RecordProperty',
+                        self.parent.context.namespaces)):
+                        rpname = recprop.find(util.nspath_eval('csw:Name',
+                        self.parent.context.namespaces)).text
+                        rpvalue = recprop.find(
+                        util.nspath_eval('csw:Value',
+                        self.parent.context.namespaces)).text
+
+                        update['recordproperty'].append(
+                        {'name': rpname, 'value': rpvalue})
+
+                    update['constraint'] = self._parse_constraint(
+                    ttype.find(util.nspath_eval('csw:Constraint',
+                    self.parent.context.namespaces)))
+
+                request['transactions'].append(update)
+
+            for ttype in \
+            doc.xpath('//csw:Delete', namespaces=self.parent.context.namespaces):
+                tname = ttype.attrib.get('typeName')
+                constraint = self._parse_constraint(
+                ttype.find(util.nspath_eval('csw:Constraint',
+                self.parent.context.namespaces)))
+
+                if isinstance(constraint, str):  # parse error
+                    return 'Invalid Constraint: %s' % constraint
+
+                request['transactions'].append(
+                {'type': 'delete', 'typename': tname, 'constraint': constraint})
+
+        # Harvest
+        if request['request'] == 'Harvest':
+            request['source'] = doc.find(util.nspath_eval('csw:Source',
+            self.parent.context.namespaces)).text
+
+            request['resourcetype'] = \
+            doc.find(util.nspath_eval('csw:ResourceType',
+            self.parent.context.namespaces)).text
+
+            tmp = doc.find(util.nspath_eval('csw:ResourceFormat',
+                  self.parent.context.namespaces))
+            if tmp is not None:
+                request['resourceformat'] = tmp.text
+            else:
+                request['resourceformat'] = 'application/xml'
+
+            tmp = doc.find(util.nspath_eval('csw:HarvestInterval',
+                  self.parent.context.namespaces))
+            if tmp is not None:
+                request['harvestinterval'] = tmp.text
+
+            tmp = doc.find(util.nspath_eval('csw:ResponseHandler',
+                  self.parent.context.namespaces))
+            if tmp is not None:
+                request['responsehandler'] = tmp.text
+        return request
+
+    def _write_transactionsummary(self, inserted=0, updated=0, deleted=0):
+        ''' Write csw:TransactionSummary construct '''
+        node = etree.Element(util.nspath_eval('csw:TransactionSummary',
+               self.parent.context.namespaces))
+
+        if 'requestid' in self.parent.kvp and self.parent.kvp['requestid'] is not None:
+            node.attrib['requestId'] = self.parent.kvp['requestid']
+
+        etree.SubElement(node, util.nspath_eval('csw:totalInserted',
+        self.parent.context.namespaces)).text = str(inserted)
+
+        etree.SubElement(node, util.nspath_eval('csw:totalUpdated',
+        self.parent.context.namespaces)).text = str(updated)
+
+        etree.SubElement(node, util.nspath_eval('csw:totalDeleted',
+        self.parent.context.namespaces)).text = str(deleted)
+
+        return node
+
+    def _write_acknowledgement(self, root=True):
+        ''' Generate csw:Acknowledgement '''
+        node = etree.Element(util.nspath_eval('csw:Acknowledgement',
+               self.parent.context.namespaces),
+        nsmap = self.parent.context.namespaces, timeStamp=util.get_today_and_now())
+
+        if root:
+            node.attrib[util.nspath_eval('xsi:schemaLocation',
+            self.parent.context.namespaces)] = \
+            '%s %s/csw/2.0.2/CSW-discovery.xsd' % (self.parent.context.namespaces['csw'], \
+            self.parent.config.get('server', 'ogc_schemas_base'))
+
+        node1 = etree.SubElement(node, util.nspath_eval('csw:EchoedRequest',
+                self.parent.context.namespaces))
+        if self.parent.requesttype == 'POST':
+            node1.append(etree.fromstring(self.parent.request, self.parent.context.parser))
+        else:  # GET
+            node2 = etree.SubElement(node1, util.nspath_eval('ows:Get',
+                    self.parent.context.namespaces))
+
+            node2.text = self.parent.request
+
+        if self.parent.async:
+            etree.SubElement(node, util.nspath_eval('csw:RequestId',
+            self.parent.context.namespaces)).text = self.kvp['requestid']
+
+        return node
+
+    def _write_verboseresponse(self, insertresults):
+        ''' show insert result identifiers '''
+        insertresult = etree.Element(util.nspath_eval('csw:InsertResult',
+        self.parent.context.namespaces))
+        for ir in insertresults:
+            briefrec = etree.SubElement(insertresult,
+                       util.nspath_eval('csw:BriefRecord',
+                       self.parent.context.namespaces))
+
+            etree.SubElement(briefrec,
+            util.nspath_eval('dc:identifier',
+            self.parent.context.namespaces)).text = ir['identifier']
+
+            etree.SubElement(briefrec,
+            util.nspath_eval('dc:title',
+            self.parent.context.namespaces)).text = ir['title']
+
+        return insertresult
+
+    def exceptionreport(self, code, locator, text):
+        ''' Generate ExceptionReport '''
+        self.parent.exception = True
+        self.parent.status = 'OK'
+
+        try:
+            language = self.parent.config.get('server', 'language')
+            ogc_schemas_base = self.parent.config.get('server', 'ogc_schemas_base')
+        except:
+            language = 'en-US'
+            ogc_schemas_base = self.parent.context.ogc_schemas_base
+
+        node = etree.Element(util.nspath_eval('ows:ExceptionReport',
+        self.parent.context.namespaces), nsmap=self.parent.context.namespaces,
+        version='1.2.0', language=language)
+
+        node.attrib[util.nspath_eval('xsi:schemaLocation',
+        self.parent.context.namespaces)] = \
+        '%s %s/ows/1.0.0/owsExceptionReport.xsd' % \
+        (self.parent.context.namespaces['ows'], ogc_schemas_base)
+
+        exception = etree.SubElement(node, util.nspath_eval('ows:Exception',
+        self.parent.context.namespaces),
+        exceptionCode=code, locator=locator)
+
+        etree.SubElement(exception,
+        util.nspath_eval('ows:ExceptionText',
+        self.parent.context.namespaces)).text = text
+
+        return node
+
+def write_boundingbox(bbox, nsmap):
+    ''' Generate ows:BoundingBox '''
+
+    if bbox is not None:
+        try:
+            bbox2 = util.wkt2geom(bbox)
+        except:
+            return None
+
+        if len(bbox2) == 4:
+            boundingbox = etree.Element(util.nspath_eval('ows:BoundingBox',
+            nsmap), crs='urn:x-ogc:def:crs:EPSG:6.11:4326',
+            dimensions='2')
+
+            etree.SubElement(boundingbox, util.nspath_eval('ows:LowerCorner',
+            nsmap)).text = '%s %s' % (bbox2[1], bbox2[0])
+
+            etree.SubElement(boundingbox, util.nspath_eval('ows:UpperCorner',
+            nsmap)).text = '%s %s' % (bbox2[3], bbox2[2])
+
+            return boundingbox
+        else:
+            return None
+    else:
+        return None
diff --git a/pycsw/ogc/csw/csw3.py b/pycsw/ogc/csw/csw3.py
new file mode 100644
index 0000000..1c5f2df
--- /dev/null
+++ b/pycsw/ogc/csw/csw3.py
@@ -0,0 +1,2136 @@
+# -*- coding: utf-8 -*-
+# =================================================================
+#
+# Authors: Tom Kralidis <tomkralidis at gmail.com>
+#
+# Copyright (c) 2016 Tom Kralidis
+#
+# Permission is hereby granted, free of charge, to any person
+# obtaining a copy of this software and associated documentation
+# files (the "Software"), to deal in the Software without
+# restriction, including without limitation the rights to use,
+# copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the
+# Software is furnished to do so, subject to the following
+# conditions:
+#
+# The above copyright notice and this permission notice shall be
+# included in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+# OTHER DEALINGS IN THE SOFTWARE.
+#
+# =================================================================
+
+import os
+import sys
+import cgi
+from time import time
+from six.moves.urllib.parse import quote, unquote
+from six import StringIO
+from six.moves.configparser import SafeConfigParser
+from pycsw.core.etree import etree
+from pycsw import oaipmh, opensearch, sru
+from pycsw.plugins.profiles import profile as pprofile
+import pycsw.plugins.outputschemas
+from pycsw.core import config, log, metadata, util
+from pycsw.ogc.fes import fes2
+import logging
+
+LOGGER = logging.getLogger(__name__)
+
+
+class Csw3(object):
+    ''' CSW 3.x server '''
+    def __init__(self, server_csw):
+        ''' Initialize CSW3 '''
+
+        self.parent = server_csw
+        self.version = '3.0.0'
+
+    def getcapabilities(self):
+        ''' Handle GetCapabilities request '''
+        serviceidentification = True
+        serviceprovider = True
+        operationsmetadata = True
+        filtercaps = False
+        languages = False
+
+        # validate acceptformats
+        LOGGER.debug('Validating ows20:AcceptFormats')
+        LOGGER.debug(self.parent.context.model['operations']['GetCapabilities']['parameters']['acceptFormats']['values'])
+        if 'acceptformats' in self.parent.kvp:
+            bfound = False
+            for fmt in self.parent.kvp['acceptformats'].split(','):
+                if fmt in self.parent.context.model['operations']['GetCapabilities']['parameters']['acceptFormats']['values']:
+                    self.parent.mimetype = fmt
+                    bfound = True
+                    break
+            if not bfound:
+                return self.exceptionreport('InvalidParameterValue',
+                'acceptformats', 'Invalid acceptFormats parameter value: %s' %
+                self.parent.kvp['acceptformats'])
+
+        if 'sections' in self.parent.kvp and self.parent.kvp['sections'] != '':
+            serviceidentification = False
+            serviceprovider = False
+            operationsmetadata = False
+            for section in self.parent.kvp['sections'].split(','):
+                if section == 'ServiceIdentification':
+                    serviceidentification = True
+                if section == 'ServiceProvider':
+                    serviceprovider = True
+                if section == 'OperationsMetadata':
+                    operationsmetadata = True
+                if section == 'All':
+                    serviceidentification = True
+                    serviceprovider = True
+                    operationsmetadata = True
+                    filtercaps = True
+                    languages = True
+        else:
+            filtercaps = True
+            languages = True
+
+        # check extra parameters that may be def'd by profiles
+        if self.parent.profiles is not None:
+            for prof in self.parent.profiles['loaded'].keys():
+                result = \
+                self.parent.profiles['loaded'][prof].check_parameters(self.parent.kvp)
+                if result is not None:
+                    return self.exceptionreport(result['code'],
+                    result['locator'], result['text'])
+
+        # @updateSequence: get latest update to repository
+        try:
+            updatesequence = \
+            util.get_time_iso2unix(self.parent.repository.query_insert())
+        except:
+            updatesequence = None
+
+        node = etree.Element(util.nspath_eval('csw30:Capabilities',
+        self.parent.context.namespaces),
+        nsmap=self.parent.context.namespaces, version='3.0.0',
+        updateSequence=str(updatesequence))
+
+        if 'updatesequence' in self.parent.kvp:
+            if int(self.parent.kvp['updatesequence']) == updatesequence:
+                return node
+            elif int(self.parent.kvp['updatesequence']) > updatesequence:
+                return self.exceptionreport('InvalidUpdateSequence',
+                'updatesequence',
+                'outputsequence specified (%s) is higher than server\'s \
+                updatesequence (%s)' % (self.parent.kvp['updatesequence'],
+                updatesequence))
+
+        node.attrib[util.nspath_eval('xsi:schemaLocation',
+        self.parent.context.namespaces)] = '%s %s/csw/3.0/cswGetCapabilities.xsd' % \
+        (self.parent.context.namespaces['csw30'],
+         self.parent.config.get('server', 'ogc_schemas_base'))
+
+        metadata_main = dict(self.parent.config.items('metadata:main'))
+
+        if serviceidentification:
+            LOGGER.debug('Writing section ServiceIdentification.')
+
+            serviceidentification = etree.SubElement(node, \
+            util.nspath_eval('ows20:ServiceIdentification',
+            self.parent.context.namespaces))
+
+            etree.SubElement(serviceidentification,
+            util.nspath_eval('ows20:Title', self.parent.context.namespaces)).text = \
+            metadata_main.get('identification_title', 'missing')
+
+            etree.SubElement(serviceidentification,
+            util.nspath_eval('ows20:Abstract', self.parent.context.namespaces)).text = \
+            metadata_main.get('identification_abstract', 'missing')
+
+            keywords = etree.SubElement(serviceidentification,
+            util.nspath_eval('ows20:Keywords', self.parent.context.namespaces))
+
+            for k in \
+            metadata_main.get('identification_keywords').split(','):
+                etree.SubElement(
+                keywords, util.nspath_eval('ows20:Keyword',
+                self.parent.context.namespaces)).text = k
+
+            etree.SubElement(keywords,
+            util.nspath_eval('ows20:Type', self.parent.context.namespaces),
+            codeSpace='ISOTC211/19115').text = \
+            metadata_main.get('identification_keywords_type', 'missing')
+
+            etree.SubElement(serviceidentification,
+            util.nspath_eval('ows20:ServiceType', self.parent.context.namespaces),
+            codeSpace='OGC').text = 'CSW'
+
+            for stv in self.parent.context.model['parameters']['version']['values']:
+                etree.SubElement(serviceidentification,
+                util.nspath_eval('ows20:ServiceTypeVersion',
+                self.parent.context.namespaces)).text = stv
+
+            if self.parent.profiles is not None:
+                for prof in self.parent.profiles['loaded'].keys():
+                    prof_name = self.parent.profiles['loaded'][prof].name
+                    prof_val = self.parent.profiles['loaded'][prof].namespaces[prof_name]
+
+                    etree.SubElement(serviceidentification,
+                    util.nspath_eval('ows20:Profile',
+                    self.parent.context.namespaces)).text = prof_val
+
+            etree.SubElement(serviceidentification,
+            util.nspath_eval('ows20:Fees', self.parent.context.namespaces)).text = \
+            metadata_main.get('identification_fees', 'missing')
+
+            etree.SubElement(serviceidentification,
+            util.nspath_eval('ows20:AccessConstraints',
+            self.parent.context.namespaces)).text = \
+            metadata_main.get('identification_accessconstraints', 'missing')
+
+        if serviceprovider:
+            LOGGER.debug('Writing section ServiceProvider.')
+            serviceprovider = etree.SubElement(node,
+            util.nspath_eval('ows20:ServiceProvider', self.parent.context.namespaces))
+
+            etree.SubElement(serviceprovider,
+            util.nspath_eval('ows20:ProviderName', self.parent.context.namespaces)).text = \
+            metadata_main.get('provider_name', 'missing')
+
+            providersite = etree.SubElement(serviceprovider,
+            util.nspath_eval('ows20:ProviderSite', self.parent.context.namespaces))
+
+            providersite.attrib[util.nspath_eval('xlink:type',
+            self.parent.context.namespaces)] = 'simple'
+
+            providersite.attrib[util.nspath_eval('xlink:href',
+            self.parent.context.namespaces)] = \
+            metadata_main.get('provider_url', 'missing')
+
+            servicecontact = etree.SubElement(serviceprovider,
+            util.nspath_eval('ows20:ServiceContact', self.parent.context.namespaces))
+
+            etree.SubElement(servicecontact,
+            util.nspath_eval('ows20:IndividualName',
+            self.parent.context.namespaces)).text = \
+            metadata_main.get('contact_name', 'missing')
+
+            etree.SubElement(servicecontact,
+            util.nspath_eval('ows20:PositionName',
+            self.parent.context.namespaces)).text = \
+            metadata_main.get('contact_position', 'missing')
+
+            contactinfo = etree.SubElement(servicecontact,
+            util.nspath_eval('ows20:ContactInfo', self.parent.context.namespaces))
+
+            phone = etree.SubElement(contactinfo, util.nspath_eval('ows20:Phone',
+            self.parent.context.namespaces))
+
+            etree.SubElement(phone, util.nspath_eval('ows20:Voice',
+            self.parent.context.namespaces)).text = \
+            metadata_main.get('contact_phone', 'missing')
+
+            etree.SubElement(phone, util.nspath_eval('ows20:Facsimile',
+            self.parent.context.namespaces)).text = \
+            metadata_main.get('contact_fax', 'missing')
+
+            address = etree.SubElement(contactinfo,
+            util.nspath_eval('ows20:Address', self.parent.context.namespaces))
+
+            etree.SubElement(address,
+            util.nspath_eval('ows20:DeliveryPoint',
+            self.parent.context.namespaces)).text = \
+            metadata_main.get('contact_address', 'missing')
+
+            etree.SubElement(address, util.nspath_eval('ows20:City',
+            self.parent.context.namespaces)).text = \
+            metadata_main.get('contact_city', 'missing')
+
+            etree.SubElement(address,
+            util.nspath_eval('ows20:AdministrativeArea',
+            self.parent.context.namespaces)).text = \
+            metadata_main.get('contact_stateorprovince', 'missing')
+
+            etree.SubElement(address,
+            util.nspath_eval('ows20:PostalCode',
+            self.parent.context.namespaces)).text = \
+            metadata_main.get('contact_postalcode', 'missing')
+
+            etree.SubElement(address,
+            util.nspath_eval('ows20:Country', self.parent.context.namespaces)).text = \
+            metadata_main.get('contact_country', 'missing')
+
+            etree.SubElement(address,
+            util.nspath_eval('ows20:ElectronicMailAddress',
+            self.parent.context.namespaces)).text = \
+            metadata_main.get('contact_email', 'missing')
+
+            url = etree.SubElement(contactinfo,
+            util.nspath_eval('ows20:OnlineResource', self.parent.context.namespaces))
+
+            url.attrib[util.nspath_eval('xlink:type',
+            self.parent.context.namespaces)] = 'simple'
+
+            url.attrib[util.nspath_eval('xlink:href',
+            self.parent.context.namespaces)] = \
+            metadata_main.get('contact_url', 'missing')
+
+            etree.SubElement(contactinfo,
+            util.nspath_eval('ows20:HoursOfService',
+            self.parent.context.namespaces)).text = \
+            metadata_main.get('contact_hours', 'missing')
+
+            etree.SubElement(contactinfo,
+            util.nspath_eval('ows20:ContactInstructions',
+            self.parent.context.namespaces)).text = \
+            metadata_main.get('contact_instructions', 'missing')
+
+            etree.SubElement(servicecontact,
+            util.nspath_eval('ows20:Role', self.parent.context.namespaces),
+            codeSpace='ISOTC211/19115').text = \
+            metadata_main.get('contact_role', 'missing')
+
+        if operationsmetadata:
+            LOGGER.debug('Writing section OperationsMetadata.')
+            operationsmetadata = etree.SubElement(node,
+            util.nspath_eval('ows20:OperationsMetadata',
+            self.parent.context.namespaces))
+
+            for operation in self.parent.context.model['operations_order']:
+                oper = etree.SubElement(operationsmetadata,
+                util.nspath_eval('ows20:Operation', self.parent.context.namespaces),
+                name=operation)
+
+                dcp = etree.SubElement(oper, util.nspath_eval('ows20:DCP',
+                self.parent.context.namespaces))
+
+                http = etree.SubElement(dcp, util.nspath_eval('ows20:HTTP',
+                self.parent.context.namespaces))
+
+                if self.parent.context.model['operations'][operation]['methods']['get']:
+                    get = etree.SubElement(http, util.nspath_eval('ows20:Get',
+                    self.parent.context.namespaces))
+
+                    get.attrib[util.nspath_eval('xlink:type',\
+                    self.parent.context.namespaces)] = 'simple'
+
+                    get.attrib[util.nspath_eval('xlink:href',\
+                    self.parent.context.namespaces)] = self.parent.config.get('server', 'url')
+
+                if self.parent.context.model['operations'][operation]['methods']['post']:
+                    post = etree.SubElement(http, util.nspath_eval('ows20:Post',
+                    self.parent.context.namespaces))
+                    post.attrib[util.nspath_eval('xlink:type',
+                    self.parent.context.namespaces)] = 'simple'
+                    post.attrib[util.nspath_eval('xlink:href',
+                    self.parent.context.namespaces)] = \
+                    self.parent.config.get('server', 'url')
+
+                for parameter in \
+                sorted(self.parent.context.model['operations'][operation]['parameters']):
+                    param = etree.SubElement(oper,
+                    util.nspath_eval('ows20:Parameter',
+                    self.parent.context.namespaces), name=parameter)
+
+                    param.append(self._write_allowed_values(self.parent.context.model['operations'][operation]['parameters'][parameter]['values']))
+
+                if operation == 'GetRecords':  # advertise queryables, MaxRecordDefault
+                    for qbl in sorted(self.parent.repository.queryables.keys()):
+                        if qbl not in ['_all', 'SupportedDublinCoreQueryables']:
+                            param = etree.SubElement(oper,
+                            util.nspath_eval('ows20:Constraint',
+                            self.parent.context.namespaces), name=qbl)
+
+                            param.append(self._write_allowed_values(self.parent.repository.queryables[qbl]))
+
+                    if self.parent.profiles is not None:
+                        for con in sorted(self.parent.context.model[\
+                        'operations']['GetRecords']['constraints'].keys()):
+                            param = etree.SubElement(oper,
+                            util.nspath_eval('ows20:Constraint',
+                            self.parent.context.namespaces), name=con)
+
+                            param.append(self._write_allowed_values(self.parent.context.model['operations']['GetRecords']['constraints'][con]['values']))
+
+                    extra_constraints = {
+                        'OpenSearchDescriptionDocument': ['%s?mode=opensearch&service=CSW&version=3.0.0&request=GetCapabilities' % self.parent.config.get('server', 'url')],
+                        'MaxRecordDefault': self.parent.context.model['constraints']['MaxRecordDefault']['values'],
+                    }
+
+                    for key in sorted(extra_constraints.keys()):
+                        param = etree.SubElement(oper,
+                        util.nspath_eval('ows20:Constraint',
+                        self.parent.context.namespaces), name=key)
+                        param.append(self._write_allowed_values(extra_constraints[key]))
+
+                    if 'FederatedCatalogues' in self.parent.context.model['constraints']:
+                        param = etree.SubElement(oper,
+                        util.nspath_eval('ows20:Constraint',
+                        self.parent.context.namespaces), name='FederatedCatalogues')
+                        param.append(self._write_allowed_values(self.parent.context.model['constraints']['FederatedCatalogues']['values']))
+
+            for parameter in sorted(self.parent.context.model['parameters'].keys()):
+                param = etree.SubElement(operationsmetadata,
+                util.nspath_eval('ows20:Parameter', self.parent.context.namespaces),
+                name=parameter)
+
+                param.append(self._write_allowed_values(self.parent.context.model['parameters'][parameter]['values']))
+
+            for qbl in sorted(self.parent.repository.queryables.keys()):
+                if qbl == 'SupportedDublinCoreQueryables':
+                    param = etree.SubElement(operationsmetadata,
+                    util.nspath_eval('ows20:Constraint',
+                    self.parent.context.namespaces), name='CoreQueryables')
+                    param.append(self._write_allowed_values(self.parent.repository.queryables[qbl]))
+
+            for constraint in sorted(self.parent.context.model['constraints'].keys()):
+                param = etree.SubElement(operationsmetadata,
+                util.nspath_eval('ows20:Constraint', self.parent.context.namespaces),
+                name=constraint)
+
+                param.append(self._write_allowed_values(self.parent.context.model['constraints'][constraint]['values']))
+
+            if self.parent.profiles is not None:
+                for prof in self.parent.profiles['loaded'].keys():
+                    ecnode = \
+                    self.parent.profiles['loaded'][prof].get_extendedcapabilities()
+                    if ecnode is not None:
+                        operationsmetadata.append(ecnode)
+
+        if languages:
+            LOGGER.debug('Writing section ows:Languages')
+            langs = etree.SubElement(node,
+            util.nspath_eval('ows20:Languages', self.parent.context.namespaces))
+            etree.SubElement(langs,
+            util.nspath_eval('ows20:Language', self.parent.context.namespaces)).text = self.parent.language['639_code']
+
+        if not filtercaps:
+            return node
+
+        # always write out Filter_Capabilities
+        LOGGER.debug('Writing section Filter_Capabilities.')
+        fltcaps = etree.SubElement(node,
+        util.nspath_eval('fes20:Filter_Capabilities', self.parent.context.namespaces))
+
+        conformance = etree.SubElement(fltcaps,
+        util.nspath_eval('fes20:Conformance', self.parent.context.namespaces))
+
+        for value in fes2.MODEL['Conformance']['values']:
+            constraint = etree.SubElement(conformance,
+                                          util.nspath_eval('fes20:Constraint', self.parent.context.namespaces),
+                                          name=value)
+            etree.SubElement(constraint,
+                             util.nspath_eval('ows11:NoValues', self.parent.context.namespaces))
+            etree.SubElement(constraint,
+                             util.nspath_eval('ows11:DefaultValue', self.parent.context.namespaces)).text = 'TRUE'
+
+        idcaps = etree.SubElement(fltcaps,
+        util.nspath_eval('fes20:Id_Capabilities', self.parent.context.namespaces))
+
+        for idcap in fes2.MODEL['Ids']['values']:
+            etree.SubElement(idcaps, util.nspath_eval('fes20:ResourceIdentifier',
+            self.parent.context.namespaces), name=idcap)
+
+        scalarcaps = etree.SubElement(fltcaps,
+        util.nspath_eval('fes20:Scalar_Capabilities', self.parent.context.namespaces))
+
+        etree.SubElement(scalarcaps, util.nspath_eval('fes20:LogicalOperators',
+        self.parent.context.namespaces))
+
+        cmpops = etree.SubElement(scalarcaps,
+        util.nspath_eval('fes20:ComparisonOperators', self.parent.context.namespaces))
+
+        for cmpop in sorted(fes2.MODEL['ComparisonOperators'].keys()):
+            etree.SubElement(cmpops,
+            util.nspath_eval('fes20:ComparisonOperator',
+            self.parent.context.namespaces), name=fes2.MODEL['ComparisonOperators'][cmpop]['opname'])
+
+        spatialcaps = etree.SubElement(fltcaps,
+        util.nspath_eval('fes20:Spatial_Capabilities', self.parent.context.namespaces))
+
+        geomops = etree.SubElement(spatialcaps,
+        util.nspath_eval('fes20:GeometryOperands', self.parent.context.namespaces))
+
+        for geomtype in \
+        fes2.MODEL['GeometryOperands']['values']:
+            etree.SubElement(geomops,
+            util.nspath_eval('fes20:GeometryOperand',
+            self.parent.context.namespaces), name=geomtype)
+
+        spatialops = etree.SubElement(spatialcaps,
+        util.nspath_eval('fes20:SpatialOperators', self.parent.context.namespaces))
+
+        for spatial_comparison in \
+        fes2.MODEL['SpatialOperators']['values']:
+            etree.SubElement(spatialops,
+            util.nspath_eval('fes20:SpatialOperator', self.parent.context.namespaces),
+            name=spatial_comparison)
+
+        functions = etree.SubElement(fltcaps,
+        util.nspath_eval('fes20:Functions', self.parent.context.namespaces))
+
+        for fnop in sorted(fes2.MODEL['Functions'].keys()):
+            fn = etree.SubElement(functions,
+            util.nspath_eval('fes20:Function', self.parent.context.namespaces),
+            name=fnop)
+
+            etree.SubElement(fn, util.nspath_eval('fes20:Returns',
+                             self.parent.context.namespaces)).text = \
+                             fes2.MODEL['Functions'][fnop]['returns']
+
+        return node
+
+    def getdomain(self):
+        ''' Handle GetDomain request '''
+        if ('parametername' not in self.parent.kvp and
+            'valuereference' not in self.parent.kvp):
+            return self.exceptionreport('MissingParameterValue',
+            'parametername', 'Missing value. \
+            One of valuereference or parametername must be specified')
+
+        node = etree.Element(util.nspath_eval('csw30:GetDomainResponse',
+        self.parent.context.namespaces), nsmap=self.parent.context.namespaces)
+
+        node.attrib[util.nspath_eval('xsi:schemaLocation',
+        self.parent.context.namespaces)] = '%s %s/csw/3.0/cswGetDomain.xsd' % \
+        (self.parent.context.namespaces['csw30'],
+        self.parent.config.get('server', 'ogc_schemas_base'))
+
+        if 'parametername' in self.parent.kvp:
+            for pname in self.parent.kvp['parametername'].split(','):
+                LOGGER.debug('Parsing parametername %s.' % pname)
+                domainvalue = etree.SubElement(node,
+                util.nspath_eval('csw30:DomainValues', self.parent.context.namespaces),
+                type='csw30:Record', resultType='available')
+                etree.SubElement(domainvalue,
+                util.nspath_eval('csw30:ParameterName',
+                self.parent.context.namespaces)).text = pname
+                try:
+                    operation, parameter = pname.split('.')
+                except:
+                    return node
+                if (operation in self.parent.context.model['operations'] and
+                    parameter in self.parent.context.model['operations'][operation]['parameters']):
+                    listofvalues = etree.SubElement(domainvalue,
+                    util.nspath_eval('csw30:ListOfValues', self.parent.context.namespaces))
+                    for val in \
+                    sorted(self.parent.context.model['operations'][operation]\
+                    ['parameters'][parameter]['values']):
+                        etree.SubElement(listofvalues,
+                        util.nspath_eval('csw30:Value',
+                        self.parent.context.namespaces)).text = val
+
+        if 'valuereference' in self.parent.kvp:
+            for pname in self.parent.kvp['valuereference'].split(','):
+                LOGGER.debug('Parsing valuereference %s.' % pname)
+
+                if pname.find('/') == 0:  # it's an XPath
+                    pname2 = pname
+                else:  # it's a core queryable, map to internal typename model
+                    try:
+                        pname2 = self.parent.repository.queryables['_all'][pname]['dbcol']
+                    except:
+                        pname2 = pname
+
+                # decipher typename
+                dvtype = None
+                if self.parent.profiles is not None:
+                    for prof in self.parent.profiles['loaded'].keys():
+                        for prefix in self.parent.profiles['loaded'][prof].prefixes:
+                            if pname2.find(prefix) != -1:
+                                dvtype = self.parent.profiles['loaded'][prof].typename
+                                break
+                if not dvtype:
+                    dvtype = 'csw30:Record'
+
+                domainvalue = etree.SubElement(node,
+                util.nspath_eval('csw30:DomainValues', self.parent.context.namespaces),
+                type=dvtype, resultType='available')
+                etree.SubElement(domainvalue,
+                util.nspath_eval('csw30:ValueReference',
+                self.parent.context.namespaces)).text = pname
+
+                try:
+                    LOGGER.debug(
+                    'Querying repository property %s, typename %s, \
+                    domainquerytype %s.' % \
+                    (pname2, dvtype, self.parent.domainquerytype))
+
+                    results = self.parent.repository.query_domain(
+                    pname2, dvtype, self.parent.domainquerytype, True)
+
+                    LOGGER.debug('Results: %s' % str(len(results)))
+
+                    if self.parent.domainquerytype == 'range':
+                        rangeofvalues = etree.SubElement(domainvalue,
+                        util.nspath_eval('csw30:RangeOfValues',
+                        self.parent.context.namespaces))
+
+                        etree.SubElement(rangeofvalues,
+                        util.nspath_eval('csw30:MinValue',
+                        self.parent.context.namespaces)).text = results[0][0]
+
+                        etree.SubElement(rangeofvalues,
+                        util.nspath_eval('csw30:MaxValue',
+                        self.parent.context.namespaces)).text = results[0][1]
+                    else:
+                        listofvalues = etree.SubElement(domainvalue,
+                        util.nspath_eval('csw30:ListOfValues',
+                        self.parent.context.namespaces))
+                        for result in results:
+                            LOGGER.debug(str(result))
+                            if (result is not None and
+                                result[0] is not None):  # drop null values
+                                etree.SubElement(listofvalues,
+                                util.nspath_eval('csw30:Value',
+                                self.parent.context.namespaces),
+                                count=str(result[1])).text = result[0]
+                except Exception as err:
+                    LOGGER.debug('No results for propertyname %s: %s.' %
+                    (pname2, str(err)))
+        return node
+
+    def getrecords(self):
+        ''' Handle GetRecords request '''
+
+        timestamp = util.get_today_and_now()
+
+        if ('elementsetname' not in self.parent.kvp and
+            'elementname' not in self.parent.kvp):
+            if self.parent.requesttype == 'GET':
+                LOGGER.debug(self.parent.requesttype)
+                self.parent.kvp['elementsetname'] = 'summary'
+            else:
+                # mutually exclusive required
+                return self.exceptionreport('MissingParameterValue',
+                'elementsetname',
+                'Missing one of ElementSetName or ElementName parameter(s)')
+
+        if 'elementsetname' in self.parent.kvp and 'elementname' in self.parent.kvp:
+            # mutually exclusive required
+            return self.exceptionreport('NoApplicableCode',
+            'elementsetname',
+            'Only ONE of ElementSetName or ElementName parameter(s) is permitted')
+
+        if 'elementsetname' not in self.parent.kvp:
+                self.parent.kvp['elementsetname'] = 'summary'
+
+        if 'outputschema' not in self.parent.kvp:
+            self.parent.kvp['outputschema'] = self.parent.context.namespaces['csw30']
+
+        LOGGER.debug(self.parent.context.model['operations']['GetRecords']['parameters']['outputSchema']['values'])
+        if (self.parent.kvp['outputschema'] not in self.parent.context.model['operations']
+            ['GetRecords']['parameters']['outputSchema']['values']):
+            return self.exceptionreport('InvalidParameterValue',
+            'outputschema', 'Invalid outputSchema parameter value: %s' %
+            self.parent.kvp['outputschema'])
+
+        if 'outputformat' not in self.parent.kvp:
+            self.parent.kvp['outputformat'] = 'application/xml'
+
+        if 'HTTP_ACCEPT' in self.parent.environ:
+            LOGGER.debug('Detected HTTP Accept header: %s', self.parent.environ['HTTP_ACCEPT'])
+            formats_match = False
+            if 'outputformat' in self.parent.kvp:
+                LOGGER.debug(self.parent.kvp['outputformat'])
+                for ofmt in self.parent.environ['HTTP_ACCEPT'].split(','):
+                    LOGGER.debug('Comparing %s and %s', ofmt, self.parent.kvp['outputformat'])
+                    if ofmt.split('/')[0] in self.parent.kvp['outputformat']:
+                        LOGGER.debug('FOUND OUTPUT MATCH')
+                        formats_match = True
+                if not formats_match:
+                    return self.exceptionreport('InvalidParameterValue',
+                    'outputformat', 'HTTP Accept header (%s) and outputformat (%s) must agree' %
+                    (self.parent.environ['HTTP_ACCEPT'], self.parent.kvp['outputformat']))
+            else:
+                for ofmt in self.parent.environ['HTTP_ACCEPT'].split(','):
+                    if ofmt in self.parent.context.model['operations']['GetRecords']['parameters']['outputFormat']['values']:
+                        self.parent.kvp['outputformat'] = ofmt
+                        break
+
+
+        if (self.parent.kvp['outputformat'] not in self.parent.context.model['operations']
+            ['GetRecords']['parameters']['outputFormat']['values']):
+            return self.exceptionreport('InvalidParameterValue',
+            'outputformat', 'Invalid outputFormat parameter value: %s' %
+            self.parent.kvp['outputformat'])
+
+        if 'outputformat' in self.parent.kvp:
+            LOGGER.debug('Setting content type')
+            self.parent.contenttype = self.parent.kvp['outputformat']
+            if self.parent.kvp['outputformat'] == 'application/atom+xml':
+                self.parent.kvp['outputschema'] = self.parent.context.namespaces['atom']
+                self.parent.mode = 'opensearch'
+
+        if (('elementname' not in self.parent.kvp or
+             len(self.parent.kvp['elementname']) == 0) and
+             self.parent.kvp['elementsetname'] not in
+             self.parent.context.model['operations']['GetRecords']['parameters']
+             ['ElementSetName']['values']):
+            return self.exceptionreport('InvalidParameterValue',
+            'elementsetname', 'Invalid ElementSetName parameter value: %s' %
+            self.parent.kvp['elementsetname'])
+
+        if 'typenames' not in self.parent.kvp:
+            return self.exceptionreport('MissingParameterValue',
+            'typenames', 'Missing typenames parameter')
+
+        if ('typenames' in self.parent.kvp and
+            self.parent.requesttype == 'GET'):  # passed via GET
+            #self.parent.kvp['typenames'] = self.parent.kvp['typenames'].split(',')
+            self.parent.kvp['typenames'] = ['csw:Record' if x=='Record' else x for x in self.parent.kvp['typenames'].split(',')]
+
+        if 'namespace' in self.parent.kvp:
+            LOGGER.debug('resolving KVP namespace bindings')
+            LOGGER.debug(self.parent.kvp['typenames'])
+            self.parent.kvp['typenames'] = self.resolve_nsmap(self.parent.kvp['typenames'])
+            if 'elementname' in self.parent.kvp:
+                LOGGER.debug(self.parent.kvp['elementname'])
+                self.parent.kvp['elementname'] = self.resolve_nsmap(self.parent.kvp['elementname'].split(','))
+
+        if 'typenames' in self.parent.kvp:
+            for tname in self.parent.kvp['typenames']:
+                #if tname == 'Record':
+                #    tname = 'csw:Record'
+                if (tname not in self.parent.context.model['operations']['GetRecords']
+                    ['parameters']['typeNames']['values']):
+                    return self.exceptionreport('InvalidParameterValue',
+                    'typenames', 'Invalid typeNames parameter value: %s' %
+                    tname)
+
+        # check elementname's
+        if 'elementname' in self.parent.kvp:
+            for ename in self.parent.kvp['elementname']:
+                if ename not in self.parent.repository.queryables['_all']:
+                    return self.exceptionreport('InvalidParameterValue',
+                    'elementname', 'Invalid ElementName parameter value: %s' %
+                    ename)
+
+        maxrecords_cfg = -1  # not set in config server.maxrecords
+
+        if self.parent.config.has_option('server', 'maxrecords'):
+            maxrecords_cfg = int(self.parent.config.get('server', 'maxrecords'))
+
+        if 'maxrecords' in self.parent.kvp and self.parent.kvp['maxrecords'] == 'unlimited':
+            LOGGER.debug('Detected maxrecords=unlimited')
+            self.parent.kvp.pop('maxrecords')
+
+        if 'maxrecords' not in self.parent.kvp:  # not specified by client
+            if maxrecords_cfg > -1:  # specified in config
+                self.parent.kvp['maxrecords'] = maxrecords_cfg
+            else:  # spec default
+                self.parent.kvp['maxrecords'] = 10
+        else:  # specified by client
+            if self.parent.kvp['maxrecords'] == '':
+                self.parent.kvp['maxrecords'] = 10
+            if maxrecords_cfg > -1:  # set in config
+                if int(self.parent.kvp['maxrecords']) > maxrecords_cfg:
+                    self.parent.kvp['maxrecords'] = maxrecords_cfg
+
+        if any(x in ['bbox', 'q', 'time'] for x in self.parent.kvp):
+            LOGGER.debug('OpenSearch Geo/Time parameters detected.')
+            self.parent.kvp['constraintlanguage'] = 'FILTER'
+            try:
+                tmp_filter = opensearch.kvp2filterxml(self.parent.kvp, self.parent.context)
+            except Exception as err:
+                return self.exceptionreport('InvalidParameterValue', 'bbox', str(err))
+
+            if tmp_filter is not "":
+                self.parent.kvp['constraint'] = tmp_filter
+                LOGGER.debug('OpenSearch Geo/Time parameters to Filter: %s.' % self.parent.kvp['constraint'])
+
+        if self.parent.requesttype == 'GET':
+            if 'constraint' in self.parent.kvp:
+                # GET request
+                LOGGER.debug('csw:Constraint passed over HTTP GET.')
+                if 'constraintlanguage' not in self.parent.kvp:
+                    return self.exceptionreport('MissingParameterValue',
+                    'constraintlanguage',
+                    'constraintlanguage required when constraint specified')
+                if (self.parent.kvp['constraintlanguage'] not in
+                self.parent.context.model['operations']['GetRecords']['parameters']
+                ['CONSTRAINTLANGUAGE']['values']):
+                    return self.exceptionreport('InvalidParameterValue',
+                    'constraintlanguage', 'Invalid constraintlanguage: %s'
+                    % self.parent.kvp['constraintlanguage'])
+                if self.parent.kvp['constraintlanguage'] == 'CQL_TEXT':
+                    tmp = self.parent.kvp['constraint']
+                    self.parent.kvp['constraint'] = {}
+                    self.parent.kvp['constraint']['type'] = 'cql'
+                    self.parent.kvp['constraint']['where'] = \
+                    self.parent._cql_update_queryables_mappings(tmp,
+                    self.parent.repository.queryables['_all'])
+                    self.parent.kvp['constraint']['values'] = {}
+                elif self.parent.kvp['constraintlanguage'] == 'FILTER':
+                    # validate filter XML
+                    try:
+                        schema = os.path.join(self.parent.config.get('server', 'home'),
+                        'core', 'schemas', 'ogc', 'filter', '1.1.0', 'filter.xsd')
+                        LOGGER.debug('Validating Filter %s.' %
+                        self.parent.kvp['constraint'])
+                        schema = etree.XMLSchema(file=schema)
+                        parser = etree.XMLParser(schema=schema, resolve_entities=False)
+                        doc = etree.fromstring(self.parent.kvp['constraint'], parser)
+                        LOGGER.debug('Filter is valid XML.')
+                        self.parent.kvp['constraint'] = {}
+                        self.parent.kvp['constraint']['type'] = 'filter'
+                        self.parent.kvp['constraint']['where'], self.parent.kvp['constraint']['values'] = \
+                        fes2.parse(doc,
+                        self.parent.repository.queryables['_all'],
+                        self.parent.repository.dbtype,
+                        self.parent.context.namespaces, self.parent.orm, self.parent.language['text'], self.parent.repository.fts)
+                    except Exception as err:
+                        errortext = \
+                        'Exception: document not valid.\nError: %s.' % str(err)
+
+                        LOGGER.debug(errortext)
+                        return self.exceptionreport('InvalidParameterValue',
+                        'bbox', 'Invalid Filter query: %s' % errortext)
+            else:
+                self.parent.kvp['constraint'] = {}
+
+        if 'sortby' not in self.parent.kvp:
+            self.parent.kvp['sortby'] = None
+        elif 'sortby' in self.parent.kvp and self.parent.requesttype == 'GET':
+            LOGGER.debug('Sorted query specified.')
+            tmp = self.parent.kvp['sortby']
+            self.parent.kvp['sortby'] = {}
+
+            try:
+                name, order = tmp.rsplit(':', 1)
+            except:
+                return self.exceptionreport('InvalidParameterValue',
+                'sortby', 'Invalid SortBy value: must be in the format\
+                propertyname:A or propertyname:D')
+
+            try:
+                self.parent.kvp['sortby']['propertyname'] = \
+                self.parent.repository.queryables['_all'][name]['dbcol']
+                if name.find('BoundingBox') != -1 or name.find('Envelope') != -1:
+                    # it's a spatial sort
+                    self.parent.kvp['sortby']['spatial'] = True
+            except Exception as err:
+                return self.exceptionreport('InvalidParameterValue',
+                'sortby', 'Invalid SortBy propertyname: %s' % name)
+
+            if order not in ['A', 'D']:
+                return self.exceptionreport('InvalidParameterValue',
+                'sortby', 'Invalid SortBy value: sort order must be "A" or "D"')
+
+            if order == 'D':
+                self.parent.kvp['sortby']['order'] = 'DESC'
+            else:
+                self.parent.kvp['sortby']['order'] = 'ASC'
+
+        if 'startposition' not in self.parent.kvp:
+            self.parent.kvp['startposition'] = 1
+
+        if 'recordids' in self.parent.kvp and self.parent.kvp['recordids'] != '':
+            # query repository
+            LOGGER.debug('Querying repository with RECORD ids: %s.' % self.parent.kvp['recordids'])
+            results = self.parent.repository.query_ids(self.parent.kvp['recordids'].split(','))
+            matched = str(len(results))
+            if len(results) == 0:
+                return self.exceptionreport('NotFound', 'recordids',
+                'No records found for \'%s\'' % self.parent.kvp['recordids'])
+        else:
+            # query repository
+            LOGGER.debug('Querying repository with constraint: %s,\
+            sortby: %s, typenames: %s, maxrecords: %s, startposition: %s.' %
+            (self.parent.kvp['constraint'], self.parent.kvp['sortby'], self.parent.kvp['typenames'],
+            self.parent.kvp['maxrecords'], self.parent.kvp['startposition']))
+
+            try:
+                matched, results = self.parent.repository.query(
+                constraint=self.parent.kvp['constraint'],
+                sortby=self.parent.kvp['sortby'], typenames=self.parent.kvp['typenames'],
+                maxrecords=self.parent.kvp['maxrecords'],
+                startposition=int(self.parent.kvp['startposition'])-1)
+            except Exception as err:
+                return self.exceptionreport('InvalidParameterValue', 'constraint',
+                'Invalid query: %s' % err)
+
+        if int(matched) == 0:
+            returned = nextrecord = '0'
+        else:
+            if int(matched) < int(self.parent.kvp['maxrecords']):
+                returned = matched
+                nextrecord = '0'
+            else:
+                returned = str(self.parent.kvp['maxrecords'])
+                if int(self.parent.kvp['startposition']) + int(self.parent.kvp['maxrecords']) >= int(matched):
+                    nextrecord = '0'
+                else:
+                    nextrecord = str(int(self.parent.kvp['startposition']) + \
+                    int(self.parent.kvp['maxrecords']))
+
+        LOGGER.debug('Results: matched: %s, returned: %s, next: %s.' % \
+        (matched, returned, nextrecord))
+
+        node = etree.Element(util.nspath_eval('csw30:GetRecordsResponse',
+        self.parent.context.namespaces),
+        nsmap=self.parent.context.namespaces, version='3.0.0')
+
+        node.attrib[util.nspath_eval('xsi:schemaLocation',
+        self.parent.context.namespaces)] = \
+        '%s %s/csw/3.0/cswGetRecordsResponse.xsd' % \
+        (self.parent.context.namespaces['csw30'], self.parent.config.get('server', 'ogc_schemas_base'))
+
+        if 'requestid' in self.parent.kvp and self.parent.kvp['requestid'] is not None:
+            etree.SubElement(node, util.nspath_eval('csw:RequestId',
+            self.parent.context.namespaces)).text = self.parent.kvp['requestid']
+
+        etree.SubElement(node, util.nspath_eval('csw30:SearchStatus',
+        self.parent.context.namespaces), timestamp=timestamp)
+
+        #if 'where' not in self.parent.kvp['constraint'] and \
+        #self.parent.kvp['resulttype'] is None:
+        #    returned = '0'
+
+        searchresults = etree.SubElement(node,
+        util.nspath_eval('csw30:SearchResults', self.parent.context.namespaces),
+        numberOfRecordsMatched=matched, numberOfRecordsReturned=returned,
+        nextRecord=nextrecord, recordSchema=self.parent.kvp['outputschema'],
+        expires=timestamp, status=get_resultset_status(matched, nextrecord))
+
+        if self.parent.kvp['elementsetname'] is not None:
+            searchresults.attrib['elementSet'] = self.parent.kvp['elementsetname']
+
+        #if 'where' not in self.parent.kvp['constraint'] \
+        #and self.parent.kvp['resulttype'] is None:
+        #    LOGGER.debug('Empty result set returned.')
+        #    return node
+
+        if results is not None:
+            if len(results) < int(self.parent.kvp['maxrecords']):
+                max1 = len(results)
+            else:
+                max1 = int(self.parent.kvp['startposition']) + (int(self.parent.kvp['maxrecords'])-1)
+            LOGGER.debug('Presenting records %s - %s.' %
+            (self.parent.kvp['startposition'], max1))
+
+            for res in results:
+                try:
+                    if (self.parent.kvp['outputschema'] ==
+                        'http://www.opengis.net/cat/csw/3.0' and
+                        'csw:Record' in self.parent.kvp['typenames']):
+                        # serialize csw:Record inline
+                        searchresults.append(self._write_record(
+                        res, self.parent.repository.queryables['_all']))
+                    elif (self.parent.kvp['outputschema'] ==
+                        'http://www.opengis.net/cat/csw/3.0' and
+                        'csw:Record' not in self.parent.kvp['typenames']):
+                        # serialize into csw:Record model
+
+                        for prof in self.parent.profiles['loaded']:
+                            # find source typename
+                            if self.parent.profiles['loaded'][prof].typename in \
+                            self.parent.kvp['typenames']:
+                                typename = self.parent.profiles['loaded'][prof].typename
+                                break
+
+                        util.transform_mappings(self.parent.repository.queryables['_all'],
+                        self.parent.context.model['typenames'][typename]\
+                        ['mappings']['csw:Record'], reverse=True)
+
+                        searchresults.append(self._write_record(
+                        res, self.parent.repository.queryables['_all']))
+                    elif self.parent.kvp['outputschema'] in self.parent.outputschemas:  # use outputschema serializer
+                        searchresults.append(self.parent.outputschemas[self.parent.kvp['outputschema']].write_record(res, self.parent.kvp['elementsetname'], self.parent.context, self.parent.config.get('server', 'url')))
+                    else:  # use profile serializer
+                        searchresults.append(
+                        self.parent.profiles['loaded'][self.parent.kvp['outputschema']].\
+                        write_record(res, self.parent.kvp['elementsetname'],
+                        self.parent.kvp['outputschema'],
+                        self.parent.repository.queryables['_all']))
+                except Exception as err:
+                    self.parent.response = self.exceptionreport(
+                    'NoApplicableCode', 'service',
+                    'Record serialization failed: %s' % str(err))
+                    return self.parent.response
+
+        if (self.parent.config.has_option('server', 'federatedcatalogues') and
+            'distributedsearch' in self.parent.kvp and
+            self.parent.kvp['distributedsearch'] and self.parent.kvp['hopcount'] > 0):
+            # do distributed search
+
+            LOGGER.debug('DistributedSearch specified (hopCount: %s).' %
+            self.parent.kvp['hopcount'])
+
+            from owslib.csw import CatalogueServiceWeb
+            from owslib.ows import ExceptionReport
+            for fedcat in \
+            self.parent.config.get('server', 'federatedcatalogues').split(','):
+                LOGGER.debug('Performing distributed search on federated \
+                catalogue: %s.' % fedcat)
+                try:
+                    start_time = time()
+                    remotecsw = CatalogueServiceWeb(fedcat, skip_caps=True)
+                    remotecsw.getrecords2(xml=self.parent.request,
+                                          esn=self.parent.kvp['elementsetname'],
+                                          outputschema=self.parent.kvp['outputschema'])
+
+                    fsr = etree.SubElement(searchresults, util.nspath_eval(
+                        'csw30:FederatedSearchResult',
+                         self.parent.context.namespaces),
+                         catalogueURL=fedcat.request)
+
+                    msg = 'Distributed search results from catalogue %s: %s.' % (fedcat, remotecsw.results)
+                    LOGGER.debug(msg)
+                    fsr.append(etree.Comment(msg))
+
+                    search_result = etree.SubElement(fsr, util.nspath_eval(
+                        'csw30:searchResult', self.parent.context.namespaces),
+                        recordSchema=self.parent.kvp['outputschema'],
+                        elementSetName=self.parent.kvp['elementsetname'],
+                        numberOfRecordsMatched=fedcat.results['matches'],
+                        numberOfRecordsReturned=fedcat.results['returned'],
+                        nextRecord=fedcat.results['nextrecord'],
+                        elapsedTime=str(util.get_elapsed_time(start_time, time())),
+                        status=get_resultset_status(
+                            fedcat.results['matches'],
+                            fedcat.results['nextrecord']))
+
+                    search_result.append(remotecsw.records)
+                except ExceptionReport as err:
+                    error_string = 'remote CSW %s returned exception: ' % fedcat
+                    searchresults.append(etree.Comment(
+                    ' %s\n\n%s ' % (error_string, err)))
+                    LOGGER.debug(str(err))
+                except Exception as err:
+                    error_string = 'remote CSW %s returned error: ' % fedcat
+                    searchresults.append(etree.Comment(
+                    ' %s\n\n%s ' % (error_string, err)))
+                    LOGGER.debug(str(err))
+
+#        if len(dsresults) > 0:  # return DistributedSearch results
+#            for resultset in dsresults:
+#                if isinstance(resultset, etree._Comment):
+#                    searchresults.append(resultset)
+#                for rec in resultset:
+#                    searchresults.append(etree.fromstring(resultset[rec].xml, self.parent.context.parser))
+
+        searchresults.attrib['elapsedTime'] = str(util.get_elapsed_time(self.parent.process_time_start, time()))
+
+        if 'responsehandler' in self.parent.kvp:  # process the handler
+            self.parent._process_responsehandler(etree.tostring(node,
+            pretty_print=self.parent.pretty_print))
+        else:
+            return node
+
+    def getrecordbyid(self, raw=False):
+        ''' Handle GetRecordById request '''
+
+        if 'id' not in self.parent.kvp:
+            return self.exceptionreport('MissingParameterValue', 'id',
+            'Missing id parameter')
+        if len(self.parent.kvp['id']) < 1:
+            return self.exceptionreport('InvalidParameterValue', 'id',
+            'Invalid id parameter')
+        if 'outputschema' not in self.parent.kvp:
+            self.parent.kvp['outputschema'] = self.parent.context.namespaces['csw30']
+
+        if 'HTTP_ACCEPT' in self.parent.environ:
+            LOGGER.debug('Detected HTTP Accept header: %s', self.parent.environ['HTTP_ACCEPT'])
+            formats_match = False
+            if 'outputformat' in self.parent.kvp:
+                LOGGER.debug(self.parent.kvp['outputformat'])
+                for ofmt in self.parent.environ['HTTP_ACCEPT'].split(','):
+                    LOGGER.debug('Comparing %s and %s', ofmt, self.parent.kvp['outputformat'])
+                    if ofmt.split('/')[0] in self.parent.kvp['outputformat']:
+                        LOGGER.debug('FOUND OUTPUT MATCH')
+                        formats_match = True
+                if not formats_match:
+                    return self.exceptionreport('InvalidParameterValue',
+                    'outputformat', 'HTTP Accept header (%s) and outputformat (%s) must agree' %
+                    (self.parent.environ['HTTP_ACCEPT'], self.parent.kvp['outputformat']))
+            else:
+                for ofmt in self.parent.environ['HTTP_ACCEPT'].split(','):
+                    if ofmt in self.parent.context.model['operations']['GetRecords']['parameters']['outputFormat']['values']:
+                        self.parent.kvp['outputformat'] = ofmt
+                        break
+
+        if ('outputformat' in self.parent.kvp and
+            self.parent.kvp['outputformat'] not in
+            self.parent.context.model['operations']['GetRecordById']['parameters']
+            ['outputFormat']['values']):
+            return self.exceptionreport('InvalidParameterValue',
+            'outputformat', 'Invalid outputformat parameter %s' %
+            self.parent.kvp['outputformat'])
+
+        if ('outputschema' in self.parent.kvp and self.parent.kvp['outputschema'] not in
+            self.parent.context.model['operations']['GetRecordById']['parameters']
+            ['outputSchema']['values']):
+            return self.exceptionreport('InvalidParameterValue',
+            'outputschema', 'Invalid outputschema parameter %s' %
+            self.parent.kvp['outputschema'])
+
+        if 'outputformat' in self.parent.kvp:
+            self.parent.contenttype = self.parent.kvp['outputformat']
+            if self.parent.kvp['outputformat'] == 'application/atom+xml':
+                self.parent.kvp['outputschema'] = self.parent.context.namespaces['atom']
+                self.parent.mode = 'opensearch'
+
+        if 'elementsetname' not in self.parent.kvp:
+            self.parent.kvp['elementsetname'] = 'summary'
+        else:
+            if (self.parent.kvp['elementsetname'] not in
+                self.parent.context.model['operations']['GetRecordById']['parameters']
+                ['ElementSetName']['values']):
+                return self.exceptionreport('InvalidParameterValue',
+                'elementsetname', 'Invalid elementsetname parameter %s' %
+                self.parent.kvp['elementsetname'])
+
+        # query repository
+        LOGGER.debug('Querying repository with ids: %s.' % self.parent.kvp['id'])
+        results = self.parent.repository.query_ids([self.parent.kvp['id']])
+
+        if raw:  # GetRepositoryItem request
+            LOGGER.debug('GetRepositoryItem request.')
+            if len(results) > 0:
+                return etree.fromstring(util.getqattr(results[0],
+                self.parent.context.md_core_model['mappings']['pycsw:XML']), self.parent.context.parser)
+
+        for result in results:
+            if (util.getqattr(result,
+            self.parent.context.md_core_model['mappings']['pycsw:Typename']) == 'csw:Record'
+            and self.parent.kvp['outputschema'] ==
+            'http://www.opengis.net/cat/csw/3.0'):
+                # serialize record inline
+                node = self._write_record(
+                result, self.parent.repository.queryables['_all'])
+            elif (self.parent.kvp['outputschema'] ==
+                'http://www.opengis.net/cat/csw/3.0'):
+                # serialize into csw:Record model
+                typename = None
+
+                for prof in self.parent.profiles['loaded']:  # find source typename
+                    if self.parent.profiles['loaded'][prof].typename in \
+                    [util.getqattr(result, self.parent.context.md_core_model['mappings']['pycsw:Typename'])]:
+                        typename = self.parent.profiles['loaded'][prof].typename
+                        break
+
+                if typename is not None:
+                    util.transform_mappings(self.parent.repository.queryables['_all'],
+                    self.parent.context.model['typenames'][typename]\
+                    ['mappings']['csw:Record'], reverse=True)
+
+                node = self._write_record( result, self.parent.repository.queryables['_all'])
+            elif self.parent.kvp['outputschema'] in self.parent.outputschemas:  # use outputschema serializer
+                node = self.parent.outputschemas[self.parent.kvp['outputschema']].write_record(result, self.parent.kvp['elementsetname'], self.parent.context, self.parent.config.get('server', 'url'))
+            else:  # it's a profile output
+                node = self.parent.profiles['loaded'][self.parent.kvp['outputschema']].write_record(
+                result, self.parent.kvp['elementsetname'],
+                self.parent.kvp['outputschema'], self.parent.repository.queryables['_all'])
+
+        if raw and len(results) == 0:
+            return None
+
+        if len(results) == 0:
+            return self.exceptionreport('NotFound', 'id',
+            'No repository item found for \'%s\'' % self.parent.kvp['id'])
+
+        return node
+
+    def getrepositoryitem(self):
+        ''' Handle GetRepositoryItem request '''
+
+        # similar to GetRecordById without csw:* wrapping
+        node = self.parent.getrecordbyid(raw=True)
+        if node is None:
+            return self.exceptionreport('NotFound', 'id',
+            'No repository item found for \'%s\'' % self.parent.kvp['id'])
+        else:
+            return node
+
+    def transaction(self):
+        ''' Handle Transaction request '''
+
+        try:
+            self.parent._test_manager()
+        except Exception as err:
+            return self.exceptionreport('NoApplicableCode', 'transaction',
+            str(err))
+
+        inserted = 0
+        updated = 0
+        deleted = 0
+
+        insertresults = []
+
+        LOGGER.debug('Transaction list: %s' % self.parent.kvp['transactions'])
+
+        for ttype in self.parent.kvp['transactions']:
+            if ttype['type'] == 'insert':
+                try:
+                    record = metadata.parse_record(self.parent.context,
+                    ttype['xml'], self.parent.repository)[0]
+                except Exception as err:
+                    return self.exceptionreport('NoApplicableCode', 'insert',
+                    'Transaction (insert) failed: record parsing failed: %s' \
+                    % str(err))
+
+                LOGGER.debug('Transaction operation: %s' % record)
+
+                if not hasattr(record,
+                self.parent.context.md_core_model['mappings']['pycsw:Identifier']):
+                    return self.exceptionreport('NoApplicableCode',
+                    'insert', 'Record requires an identifier')
+
+                # insert new record
+                try:
+                    self.parent.repository.insert(record, 'local',
+                    util.get_today_and_now())
+
+                    inserted += 1
+                    insertresults.append(
+                    {'identifier': getattr(record,
+                    self.parent.context.md_core_model['mappings']['pycsw:Identifier']),
+                    'title': getattr(record,
+                    self.parent.context.md_core_model['mappings']['pycsw:Title'])})
+                except Exception as err:
+                    return self.exceptionreport('NoApplicableCode',
+                    'insert', 'Transaction (insert) failed: %s.' % str(err))
+
+            elif ttype['type'] == 'update':
+                if 'constraint' not in ttype:
+                    # update full existing resource in repository
+                    try:
+                        record = metadata.parse_record(self.parent.context,
+                        ttype['xml'], self.parent.repository)[0]
+                        identifier = getattr(record,
+                        self.parent.context.md_core_model['mappings']['pycsw:Identifier'])
+                    except Exception as err:
+                        return self.exceptionreport('NoApplicableCode', 'insert',
+                        'Transaction (update) failed: record parsing failed: %s' \
+                        % str(err))
+
+                    # query repository to see if record already exists
+                    LOGGER.debug('checking if record exists (%s)' % \
+                    identifier)
+
+                    results = self.parent.repository.query_ids(ids=[identifier])
+
+                    if len(results) == 0:
+                        LOGGER.debug('id %s does not exist in repository' % \
+                        identifier)
+                    else:  # existing record, it's an update
+                        try:
+                            self.parent.repository.update(record)
+                            updated += 1
+                        except Exception as err:
+                            return self.exceptionreport('NoApplicableCode',
+                            'update',
+                            'Transaction (update) failed: %s.' % str(err))
+                else:  # update by record property and constraint
+                    # get / set XPath for property names
+                    for rp in ttype['recordproperty']:
+                        if rp['name'] not in self.parent.repository.queryables['_all']:
+                            # is it an XPath?
+                            if rp['name'].find('/') != -1:
+                                # scan outputschemas; if match, bind
+                                for osch in self.parent.outputschemas.values():
+                                    for key, value in osch.XPATH_MAPPINGS.items():
+                                        if value == rp['name']:  # match
+                                            rp['rp'] = {'xpath': value, 'name': key}
+                                            rp['rp']['dbcol'] = self.parent.repository.queryables['_all'][key]
+                                            break
+                            else:
+                                return self.exceptionreport('NoApplicableCode',
+                                       'update', 'Transaction (update) failed: invalid property2: %s.' % str(rp['name']))
+                        else:
+                            rp['rp']= \
+                            self.parent.repository.queryables['_all'][rp['name']]
+
+                    LOGGER.debug('Record Properties: %s.' %
+                    ttype['recordproperty'])
+                    try:
+                        updated += self.parent.repository.update(record=None,
+                        recprops=ttype['recordproperty'],
+                        constraint=ttype['constraint'])
+                    except Exception as err:
+                        return self.exceptionreport('NoApplicableCode',
+                        'update',
+                        'Transaction (update) failed: %s.' % str(err))
+
+            elif ttype['type'] == 'delete':
+                deleted += self.parent.repository.delete(ttype['constraint'])
+
+        node = etree.Element(util.nspath_eval('csw30:TransactionResponse',
+        self.parent.context.namespaces), nsmap=self.parent.context.namespaces, version='3.0.0')
+
+        node.attrib[util.nspath_eval('xsi:schemaLocation',
+        self.parent.context.namespaces)] = '%s %s/csw/3.0/cswTransaction.xsd' % \
+        (self.parent.context.namespaces['csw30'], self.parent.config.get('server', 'ogc_schemas_base'))
+
+        node.append(
+        self._write_transactionsummary(
+        inserted=inserted, updated=updated, deleted=deleted))
+
+        if (len(insertresults) > 0 and self.parent.kvp['verboseresponse']):
+            # show insert result identifiers
+            node.append(self._write_verboseresponse(insertresults))
+
+        return node
+
+    def harvest(self):
+        ''' Handle Harvest request '''
+
+        service_identifier = None
+        old_identifier = None
+        deleted = []
+
+        try:
+            self.parent._test_manager()
+        except Exception as err:
+            return self.exceptionreport('NoApplicableCode', 'harvest', str(err))
+
+        if self.parent.requesttype == 'GET':
+            if 'resourcetype' not in self.parent.kvp:
+                return self.exceptionreport('MissingParameterValue',
+                'resourcetype', 'Missing resourcetype parameter')
+            if 'source' not in self.parent.kvp:
+                return self.exceptionreport('MissingParameterValue',
+                'source', 'Missing source parameter')
+
+        # validate resourcetype
+        if (self.parent.kvp['resourcetype'] not in
+            self.parent.context.model['operations']['Harvest']['parameters']['ResourceType']
+            ['values']):
+            return self.exceptionreport('InvalidParameterValue',
+            'resourcetype', 'Invalid resource type parameter: %s.\
+            Allowable resourcetype values: %s' % (self.parent.kvp['resourcetype'],
+            ','.join(self.parent.context.model['operations']['Harvest']['parameters']
+            ['ResourceType']['values'])))
+
+        if (self.parent.kvp['resourcetype'].find('opengis.net') == -1 and
+            self.parent.kvp['resourcetype'].find('urn:geoss:waf') == -1):
+            # fetch content-based resource
+            LOGGER.debug('Fetching resource %s' % self.parent.kvp['source'])
+            try:
+                content = util.http_request('GET', self.parent.kvp['source'])
+            except Exception as err:
+                errortext = 'Error fetching resource %s.\nError: %s.' % \
+                (self.parent.kvp['source'], str(err))
+                LOGGER.debug(errortext)
+                return self.exceptionreport('InvalidParameterValue', 'source',
+                errortext)
+        else:  # it's a service URL
+            content = self.parent.kvp['source']
+            # query repository to see if service already exists
+            LOGGER.debug('checking if service exists (%s)' % content)
+            results = self.parent.repository.query_source(content)
+
+            if len(results) > 0:  # exists, keep identifier for update
+                LOGGER.debug('Service already exists, keeping identifier and results')
+                service_identifier = getattr(results[0], self.parent.context.md_core_model['mappings']['pycsw:Identifier'])
+                service_results = results
+                LOGGER.debug('Identifier is %s' % service_identifier)
+            #    return self.exceptionreport('NoApplicableCode', 'source',
+            #    'Insert failed: service %s already in repository' % content)
+
+
+        if hasattr(self.parent.repository, 'local_ingest') and self.parent.repository.local_ingest:
+            updated = 0
+            deleted = []
+            try:
+                ir = self.parent.repository.insert(self.parent.kvp['resourcetype'], self.parent.kvp['source'])
+                inserted = len(ir)
+            except Exception as err:
+                return self.exceptionreport('NoApplicableCode',
+                'source', 'Harvest (insert) failed: %s.' % str(err))
+        else:
+            # parse resource into record
+            try:
+                records_parsed = metadata.parse_record(self.parent.context,
+                content, self.parent.repository, self.parent.kvp['resourcetype'],
+                pagesize=self.parent.csw_harvest_pagesize)
+            except Exception as err:
+                LOGGER.exception(err)
+                return self.exceptionreport('NoApplicableCode', 'source',
+                'Harvest failed: record parsing failed: %s' % str(err))
+
+            inserted = 0
+            updated = 0
+            ir = []
+
+            LOGGER.debug('Total Records parsed: %d' % len(records_parsed))
+            for record in records_parsed:
+                if self.parent.kvp['resourcetype'] == 'urn:geoss:waf':
+                    src = record.source
+                else:
+                    src = self.parent.kvp['source']
+
+                setattr(record, self.parent.context.md_core_model['mappings']['pycsw:Source'],
+                        src)
+
+                setattr(record, self.parent.context.md_core_model['mappings']['pycsw:InsertDate'],
+                util.get_today_and_now())
+
+                identifier = getattr(record,
+                self.parent.context.md_core_model['mappings']['pycsw:Identifier'])
+                source = getattr(record,
+                self.parent.context.md_core_model['mappings']['pycsw:Source'])
+                insert_date = getattr(record,
+                self.parent.context.md_core_model['mappings']['pycsw:InsertDate'])
+                title = getattr(record,
+                self.parent.context.md_core_model['mappings']['pycsw:Title'])
+
+                record_type = getattr(record, self.parent.context.md_core_model['mappings']['pycsw:Type'])
+
+                record_identifier = getattr(record, self.parent.context.md_core_model['mappings']['pycsw:Identifier'])
+
+                if record_type == 'service' and service_identifier is not None:  # service endpoint
+                    LOGGER.debug('Replacing service identifier from %s to %s' % (record_identifier, service_identifier))
+                    old_identifier = record_identifier
+                    identifier = record_identifier = service_identifier
+                if (record_type != 'service' and service_identifier is not None
+                    and old_identifier is not None):  # service resource
+                    if record_identifier.find(old_identifier) != -1:
+                        new_identifier = record_identifier.replace(old_identifier, service_identifier)
+                        LOGGER.debug('Replacing service resource identifier from %s to %s' % (record_identifier, new_identifier))
+                        identifier = record_identifier = new_identifier
+
+                ir.append({'identifier': identifier, 'title': title})
+
+                results = []
+                if not self.parent.config.has_option('repository', 'source'):
+                    # query repository to see if record already exists
+                    LOGGER.debug('checking if record exists (%s)' % identifier)
+                    results = self.parent.repository.query_ids(ids=[identifier])
+
+                    if len(results) == 0:  # check for service identifier
+                        LOGGER.debug('checking if service id exists (%s)' % service_identifier)
+                        results = self.parent.repository.query_ids(ids=[service_identifier])
+
+                LOGGER.debug(str(results))
+
+                if len(results) == 0:  # new record, it's a new insert
+                    inserted += 1
+                    try:
+                        tmp = self.parent.repository.insert(record, source, insert_date)
+                        if tmp is not None: ir = tmp
+                    except Exception as err:
+                        return self.exceptionreport('NoApplicableCode',
+                        'source', 'Harvest (insert) failed: %s.' % str(err))
+                else:  # existing record, it's an update
+                    if source != results[0].source:
+                        # same identifier, but different source
+                        return self.exceptionreport('NoApplicableCode',
+                        'source', 'Insert failed: identifier %s in repository\
+                        has source %s.' % (identifier, source))
+
+                    try:
+                        self.parent.repository.update(record)
+                    except Exception as err:
+                        return self.exceptionreport('NoApplicableCode',
+                        'source', 'Harvest (update) failed: %s.' % str(err))
+                    updated += 1
+
+            if service_identifier is not None:
+                fresh_records = [str(i['identifier']) for i in ir]
+                existing_records = [str(i.identifier) for i in service_results]
+
+                deleted = set(existing_records) - set(fresh_records)
+                LOGGER.debug('Records to delete: %s' % str(deleted))
+
+                for to_delete in deleted:
+                    delete_constraint = {
+                        'type': 'filter',
+                        'values': [to_delete],
+                        'where': 'identifier = :pvalue0'
+                    }
+                    self.parent.repository.delete(delete_constraint)
+
+        node = etree.Element(util.nspath_eval('csw:HarvestResponse',
+        self.parent.context.namespaces), nsmap=self.parent.context.namespaces)
+
+        node.attrib[util.nspath_eval('xsi:schemaLocation',
+        self.parent.context.namespaces)] = \
+        '%s %s/csw/2.0.2/CSW-publication.xsd' % (self.parent.context.namespaces['csw'],
+        self.parent.config.get('server', 'ogc_schemas_base'))
+
+        node2 = etree.SubElement(node,
+        util.nspath_eval('csw:TransactionResponse',
+        self.parent.context.namespaces), version='2.0.2')
+
+        node2.append(
+        self._write_transactionsummary(inserted=len(ir), updated=updated,
+                                       deleted=len(deleted)))
+
+        if inserted > 0:
+            # show insert result identifiers
+            node2.append(self._write_verboseresponse(ir))
+
+        if 'responsehandler' in self.parent.kvp:  # process the handler
+            self.parent._process_responsehandler(etree.tostring(node,
+            pretty_print=self.parent.pretty_print))
+        else:
+            return node
+
+    def _write_record(self, recobj, queryables):
+        ''' Generate csw30:Record '''
+        if self.parent.kvp['elementsetname'] == 'brief':
+            elname = 'BriefRecord'
+        elif self.parent.kvp['elementsetname'] == 'summary':
+            elname = 'SummaryRecord'
+        else:
+            elname = 'Record'
+
+        record = etree.Element(util.nspath_eval('csw30:%s' % elname,
+                 self.parent.context.namespaces), nsmap=self.parent.context.namespaces)
+
+        if ('elementname' in self.parent.kvp and
+            len(self.parent.kvp['elementname']) > 0):
+            for req_term in ['dc:identifier', 'dc:title']:
+                if req_term not in self.parent.kvp['elementname']:
+                    value = util.getqattr(recobj, queryables[req_term]['dbcol'])
+                    etree.SubElement(record,
+                    util.nspath_eval(req_term,
+                    self.parent.context.namespaces)).text = value
+            for elemname in self.parent.kvp['elementname']:
+                if (elemname.find('BoundingBox') != -1 or
+                    elemname.find('Envelope') != -1):
+                    bboxel = write_boundingbox(util.getqattr(recobj,
+                    self.parent.context.md_core_model['mappings']['pycsw:BoundingBox']),
+                    self.parent.context.namespaces)
+                    if bboxel is not None:
+                        record.append(bboxel)
+                else:
+                    value = util.getqattr(recobj, queryables[elemname]['dbcol'])
+                    elem = etree.SubElement(record,
+                           util.nspath_eval(elemname,
+                           self.parent.context.namespaces))
+                    if value:
+                        elem.text = value
+        elif 'elementsetname' in self.parent.kvp:
+            if (self.parent.kvp['elementsetname'] == 'full' and
+            util.getqattr(recobj, self.parent.context.md_core_model['mappings']\
+            ['pycsw:Typename']) == 'csw:Record' and
+            util.getqattr(recobj, self.parent.context.md_core_model['mappings']\
+            ['pycsw:Schema']) == 'http://www.opengis.net/cat/csw/3.0' and
+            util.getqattr(recobj, self.parent.context.md_core_model['mappings']\
+            ['pycsw:Type']) != 'service'):
+                # dump record as is and exit
+                return etree.fromstring(util.getqattr(recobj,
+                self.parent.context.md_core_model['mappings']['pycsw:XML']), self.parent.context.parser)
+
+            etree.SubElement(record,
+            util.nspath_eval('dc:identifier', self.parent.context.namespaces)).text = \
+            util.getqattr(recobj,
+            self.parent.context.md_core_model['mappings']['pycsw:Identifier'])
+
+            for i in ['dc:title', 'dc:type']:
+                val = util.getqattr(recobj, queryables[i]['dbcol'])
+                if not val:
+                    val = ''
+                etree.SubElement(record, util.nspath_eval(i,
+                self.parent.context.namespaces)).text = val
+
+            if self.parent.kvp['elementsetname'] in ['summary', 'full']:
+                # add summary elements
+                keywords = util.getqattr(recobj, queryables['dc:subject']['dbcol'])
+                if keywords is not None:
+                    for keyword in keywords.split(','):
+                        etree.SubElement(record,
+                        util.nspath_eval('dc:subject',
+                        self.parent.context.namespaces)).text = keyword
+
+                val = util.getqattr(recobj, self.parent.context.md_core_model['mappings']['pycsw:TopicCategory'])
+                if val:
+                    etree.SubElement(record,
+                    util.nspath_eval('dc:subject',
+                    self.parent.context.namespaces), scheme='http://www.isotc211.org/2005/resources/Codelist/gmxCodelists.xml#MD_TopicCategoryCode').text = val
+
+                val = util.getqattr(recobj, queryables['dc:format']['dbcol'])
+                if val:
+                    etree.SubElement(record,
+                    util.nspath_eval('dc:format',
+                    self.parent.context.namespaces)).text = val
+
+                # links
+                rlinks = util.getqattr(recobj,
+                self.parent.context.md_core_model['mappings']['pycsw:Links'])
+
+                if rlinks:
+                    links = rlinks.split('^')
+                    for link in links:
+                        linkset = link.split(',')
+                        etree.SubElement(record,
+                        util.nspath_eval('dct:references',
+                        self.parent.context.namespaces),
+                        scheme=linkset[2]).text = linkset[-1]
+
+                for i in ['dc:relation', 'dct:modified', 'dct:abstract']:
+                    val = util.getqattr(recobj, queryables[i]['dbcol'])
+                    if val is not None:
+                        etree.SubElement(record,
+                        util.nspath_eval(i, self.parent.context.namespaces)).text = val
+
+            if self.parent.kvp['elementsetname'] == 'full':  # add full elements
+                for i in ['dc:date', 'dc:creator', \
+                'dc:publisher', 'dc:contributor', 'dc:source', \
+                'dc:language', 'dc:rights']:
+                    val = util.getqattr(recobj, queryables[i]['dbcol'])
+                    if val:
+                        etree.SubElement(record,
+                        util.nspath_eval(i, self.parent.context.namespaces)).text = val
+
+            # always write out ows:BoundingBox
+            bboxel = write_boundingbox(getattr(recobj,
+            self.parent.context.md_core_model['mappings']['pycsw:BoundingBox']),
+            self.parent.context.namespaces)
+
+            if bboxel is not None:
+                record.append(bboxel)
+
+            if self.parent.kvp['elementsetname'] != 'brief':  # add temporal extent
+                begin = util.getqattr(record, self.parent.context.md_core_model['mappings']['pycsw:TempExtent_begin'])
+                end = util.getqattr(record, self.parent.context.md_core_model['mappings']['pycsw:TempExtent_end'])
+
+                if begin or end:
+                    tempext = etree.SubElement(record, util.nspath_eval('csw30:TemporalExtent', self.parent.context.namespaces))
+                    if begin:
+                        etree.SubElement(record, util.nspath_eval('csw30:begin', self.parent.context.namespaces)).text = begin
+                    if end:
+                        etree.SubElement(record, util.nspath_eval('csw30:end', self.parent.context.namespaces)).text = end
+
+        return record
+
+    def _parse_constraint(self, element):
+        ''' Parse csw:Constraint '''
+
+        query = {}
+
+        tmp = element.find(util.nspath_eval('fes20:Filter', self.parent.context.namespaces))
+        if tmp is not None:
+            LOGGER.debug('Filter constraint specified.')
+            try:
+                query['type'] = 'filter'
+                query['where'], query['values'] = fes2.parse(tmp,
+                self.parent.repository.queryables['_all'], self.parent.repository.dbtype,
+                self.parent.context.namespaces, self.parent.orm, self.parent.language['text'], self.parent.repository.fts)
+            except Exception as err:
+                return 'Invalid Filter request: %s' % err
+        tmp = element.find(util.nspath_eval('csw30:CqlText', self.parent.context.namespaces))
+        if tmp is not None:
+            LOGGER.debug('CQL specified: %s.' % tmp.text)
+            query['type'] = 'cql'
+            query['where'] = self.parent._cql_update_queryables_mappings(tmp.text,
+            self.parent.repository.queryables['_all'])
+            query['values'] = {}
+        return query
+
+    def parse_postdata(self, postdata):
+        ''' Parse POST XML '''
+
+        request = {}
+        try:
+            LOGGER.debug('Parsing %s.' % postdata)
+            doc = etree.fromstring(postdata, self.parent.context.parser)
+        except Exception as err:
+            errortext = \
+            'Exception: document not well-formed.\nError: %s.' % str(err)
+
+            LOGGER.debug(errortext)
+            return errortext
+
+        # if this is a SOAP request, get to SOAP-ENV:Body/csw:*
+        if (doc.tag == util.nspath_eval('soapenv:Envelope',
+            self.parent.context.namespaces)):
+
+            LOGGER.debug('SOAP request specified.')
+            self.parent.soap = True
+
+            doc = doc.find(
+            util.nspath_eval('soapenv:Body',
+            self.parent.context.namespaces)).xpath('child::*')[0]
+
+        xsd_filename = 'csw%s.xsd' % util.xmltag_split(doc.tag)
+        schema = os.path.join(self.parent.config.get('server', 'home'),
+        'core', 'schemas', 'ogc', 'csw', '3.0', xsd_filename)
+
+        try:
+            # it is virtually impossible to validate a csw:Transaction
+            # csw:Insert|csw:Update (with single child) XML document.
+            # Only validate non csw:Transaction XML
+
+            if doc.find('.//%s' % util.nspath_eval('csw30:Insert',
+            self.parent.context.namespaces)) is None and \
+            len(doc.xpath('//csw30:Update/child::*',
+            namespaces=self.parent.context.namespaces)) == 0:
+
+                LOGGER.debug('Validating %s.' % postdata)
+                schema = etree.XMLSchema(file=schema)
+                parser = etree.XMLParser(schema=schema, resolve_entities=False)
+                if hasattr(self.parent, 'soap') and self.parent.soap:
+                # validate the body of the SOAP request
+                    doc = etree.fromstring(etree.tostring(doc), parser)
+                else:  # validate the request normally
+                    doc = etree.fromstring(postdata, parser)
+                LOGGER.debug('Request is valid XML.')
+            else:  # parse Transaction without validation
+                doc = etree.fromstring(postdata, self.parent.context.parser)
+        except Exception as err:
+            errortext = \
+            'Exception: the document is not valid.\nError: %s' % str(err)
+            LOGGER.debug(errortext)
+            return errortext
+
+        request['request'] = util.xmltag_split(doc.tag)
+        LOGGER.debug('Request operation %s specified.' % request['request'])
+        tmp = doc.find('.').attrib.get('service')
+        if tmp is not None:
+            request['service'] = tmp
+
+        tmp = doc.find('.').attrib.get('version')
+        if tmp is not None:
+            request['version'] = tmp
+
+        tmp = doc.find('.//%s' % util.nspath_eval('ows20:Version',
+        self.parent.context.namespaces))
+
+        if tmp is not None:
+            request['version'] = tmp.text
+
+        tmp = doc.find('.').attrib.get('updateSequence')
+        if tmp is not None:
+            request['updatesequence'] = tmp
+
+        # GetCapabilities
+        if request['request'] == 'GetCapabilities':
+            tmp = doc.find(util.nspath_eval('ows20:Sections',
+                  self.parent.context.namespaces))
+            if tmp is not None:
+                request['sections'] = ','.join([section.text for section in \
+                doc.findall(util.nspath_eval('ows20:Sections/ows20:Section',
+                self.parent.context.namespaces))])
+
+            tmp = doc.find(util.nspath_eval('ows20:AcceptFormats',
+                  self.parent.context.namespaces))
+            if tmp is not None:
+                request['acceptformats'] = ','.join([aformat.text for aformat in \
+                doc.findall(util.nspath_eval('ows20:AcceptFormats/ows20:OutputFormat',
+                self.parent.context.namespaces))])
+
+            tmp = doc.find(util.nspath_eval('ows20:AcceptVersions',
+                  self.parent.context.namespaces))
+            if tmp is not None:
+                request['acceptversions'] = ','.join([version.text for version in \
+                doc.findall(util.nspath_eval('ows20:AcceptVersions/ows20:Version',
+                self.parent.context.namespaces))])
+
+        # GetDomain
+        if request['request'] == 'GetDomain':
+            tmp = doc.find(util.nspath_eval('csw30:ParameterName',
+                  self.parent.context.namespaces))
+            if tmp is not None:
+                request['parametername'] = tmp.text
+
+            tmp = doc.find(util.nspath_eval('csw30:ValueReference',
+                  self.parent.context.namespaces))
+            if tmp is not None:
+                request['valuereference'] = tmp.text
+
+        # GetRecords
+        if request['request'] == 'GetRecords':
+            tmp = doc.find('.').attrib.get('outputSchema')
+            request['outputschema'] = tmp if tmp is not None \
+            else self.parent.context.namespaces['csw30']
+
+            tmp = doc.find('.').attrib.get('outputFormat')
+            request['outputformat'] = tmp if tmp is not None \
+            else 'application/xml'
+
+            tmp = doc.find('.').attrib.get('startPosition')
+            request['startposition'] = tmp if tmp is not None else 1
+
+            tmp = doc.find('.').attrib.get('requestId')
+            request['requestid'] = tmp if tmp is not None else None
+
+            tmp = doc.find('.').attrib.get('maxRecords')
+            if tmp is not None:
+                request['maxrecords'] = tmp
+
+            tmp = doc.find(util.nspath_eval('csw30:DistributedSearch',
+                  self.parent.context.namespaces))
+            if tmp is not None:
+                request['distributedsearch'] = True
+                hopcount = tmp.attrib.get('hopCount')
+                request['hopcount'] = int(hopcount)-1 if hopcount is not None \
+                else 1
+            else:
+                request['distributedsearch'] = False
+
+            tmp = doc.find(util.nspath_eval('csw30:ResponseHandler',
+                  self.parent.context.namespaces))
+            if tmp is not None:
+                request['responsehandler'] = tmp.text
+
+            tmp = doc.find(util.nspath_eval('csw30:Query/csw30:ElementSetName',
+                  self.parent.context.namespaces))
+            request['elementsetname'] = tmp.text if tmp is not None else None
+
+            tmp = doc.find(util.nspath_eval(
+            'csw30:Query', self.parent.context.namespaces)).attrib.get('typeNames')
+            request['typenames'] = tmp.split() if tmp is not None \
+            else 'csw:Record'
+
+            request['elementname'] = [elname.text for elname in \
+            doc.findall(util.nspath_eval('csw30:Query/csw30:ElementName',
+            self.parent.context.namespaces))]
+
+            request['constraint'] = {}
+            tmp = doc.find(util.nspath_eval('csw30:Query/csw30:Constraint',
+            self.parent.context.namespaces))
+
+            if tmp is not None:
+                request['constraint'] = self._parse_constraint(tmp)
+                if isinstance(request['constraint'], str):  # parse error
+                    return 'Invalid Constraint: %s' % request['constraint']
+            else:
+                LOGGER.debug('No csw30:Constraint (fes20:Filter or csw30:CqlText) \
+                specified.')
+
+            tmp = doc.find(util.nspath_eval('csw30:Query/fes20:SortBy',
+                  self.parent.context.namespaces))
+            if tmp is not None:
+                LOGGER.debug('Sorted query specified.')
+                request['sortby'] = {}
+
+
+                try:
+                    elname = tmp.find(util.nspath_eval(
+                    'fes20:SortProperty/fes20:ValueReference',
+                    self.parent.context.namespaces)).text
+
+                    request['sortby']['propertyname'] = \
+                    self.parent.repository.queryables['_all'][elname]['dbcol']
+
+                    if (elname.find('BoundingBox') != -1 or
+                        elname.find('Envelope') != -1):
+                        # it's a spatial sort
+                        request['sortby']['spatial'] = True
+                except Exception as err:
+                    errortext = \
+                    'Invalid fes20:SortProperty/fes20:ValueReference: %s' % str(err)
+                    LOGGER.debug(errortext)
+                    return errortext
+
+                tmp2 =  tmp.find(util.nspath_eval(
+                'fes20:SortProperty/fes20:SortOrder', self.parent.context.namespaces))
+                request['sortby']['order'] = tmp2.text if tmp2 is not None \
+                else 'ASC'
+            else:
+                request['sortby'] = None
+
+        # GetRecordById
+        if request['request'] == 'GetRecordById':
+            request['id'] = None
+            tmp = doc.find(util.nspath_eval('csw30:Id', self.parent.context.namespaces))
+            if tmp is not None:
+                request['id'] = tmp.text
+
+            tmp = doc.find(util.nspath_eval('csw30:ElementSetName',
+                  self.parent.context.namespaces))
+            request['elementsetname'] = tmp.text if tmp is not None \
+            else 'summary'
+
+            tmp = doc.find('.').attrib.get('outputSchema')
+            request['outputschema'] = tmp if tmp is not None \
+            else self.parent.context.namespaces['csw30']
+
+            tmp = doc.find('.').attrib.get('outputFormat')
+            if tmp is not None:
+                request['outputformat'] = tmp
+
+        # Transaction
+        if request['request'] == 'Transaction':
+            request['verboseresponse'] = True
+            tmp = doc.find('.').attrib.get('verboseResponse')
+            if tmp is not None:
+                if tmp in ['false', '0']:
+                    request['verboseresponse'] = False
+
+            tmp = doc.find('.').attrib.get('requestId')
+            request['requestid'] = tmp if tmp is not None else None
+
+            request['transactions'] = []
+
+            for ttype in \
+            doc.xpath('//csw30:Insert', namespaces=self.parent.context.namespaces):
+                tname = ttype.attrib.get('typeName')
+
+                for mdrec in ttype.xpath('child::*'):
+                    xml = mdrec
+                    request['transactions'].append(
+                    {'type': 'insert', 'typename': tname, 'xml': xml})
+
+            for ttype in \
+            doc.xpath('//csw30:Update', namespaces=self.parent.context.namespaces):
+                child = ttype.xpath('child::*')
+                update = {'type': 'update'}
+
+                if len(child) == 1:  # it's a wholesale update
+                    update['xml'] = child[0]
+                else:  # it's a RecordProperty with Constraint Update
+                    update['recordproperty'] = []
+
+                    for recprop in ttype.findall(
+                    util.nspath_eval('csw:RecordProperty',
+                        self.parent.context.namespaces)):
+                        rpname = recprop.find(util.nspath_eval('csw30:Name',
+                        self.parent.context.namespaces)).text
+                        rpvalue = recprop.find(
+                        util.nspath_eval('csw30:Value',
+                        self.parent.context.namespaces)).text
+
+                        update['recordproperty'].append(
+                        {'name': rpname, 'value': rpvalue})
+
+                    update['constraint'] = self._parse_constraint(
+                    ttype.find(util.nspath_eval('csw30:Constraint',
+                    self.parent.context.namespaces)))
+
+                request['transactions'].append(update)
+
+            for ttype in \
+            doc.xpath('//csw30:Delete', namespaces=self.parent.context.namespaces):
+                tname = ttype.attrib.get('typeName')
+                constraint = self._parse_constraint(
+                ttype.find(util.nspath_eval('csw30:Constraint',
+                self.parent.context.namespaces)))
+
+                if isinstance(constraint, str):  # parse error
+                    return 'Invalid Constraint: %s' % constraint
+
+                request['transactions'].append(
+                {'type': 'delete', 'typename': tname, 'constraint': constraint})
+
+        # Harvest
+        if request['request'] == 'Harvest':
+            request['source'] = doc.find(util.nspath_eval('csw30:Source',
+            self.parent.context.namespaces)).text
+
+            request['resourcetype'] = \
+            doc.find(util.nspath_eval('csw30:ResourceType',
+            self.parent.context.namespaces)).text
+
+            tmp = doc.find(util.nspath_eval('csw30:ResourceFormat',
+                  self.parent.context.namespaces))
+            if tmp is not None:
+                request['resourceformat'] = tmp.text
+            else:
+                request['resourceformat'] = 'application/xml'
+
+            tmp = doc.find(util.nspath_eval('csw30:HarvestInterval',
+                  self.parent.context.namespaces))
+            if tmp is not None:
+                request['harvestinterval'] = tmp.text
+
+            tmp = doc.find(util.nspath_eval('csw30:ResponseHandler',
+                  self.parent.context.namespaces))
+            if tmp is not None:
+                request['responsehandler'] = tmp.text
+        return request
+
+    def _write_transactionsummary(self, inserted=0, updated=0, deleted=0):
+        ''' Write csw:TransactionSummary construct '''
+        node = etree.Element(util.nspath_eval('csw30:TransactionSummary',
+               self.parent.context.namespaces))
+
+        if 'requestid' in self.parent.kvp and self.parent.kvp['requestid'] is not None:
+            node.attrib['requestId'] = self.parent.kvp['requestid']
+
+        etree.SubElement(node, util.nspath_eval('csw30:totalInserted',
+        self.parent.context.namespaces)).text = str(inserted)
+
+        etree.SubElement(node, util.nspath_eval('csw30:totalUpdated',
+        self.parent.context.namespaces)).text = str(updated)
+
+        etree.SubElement(node, util.nspath_eval('csw30:totalDeleted',
+        self.parent.context.namespaces)).text = str(deleted)
+
+        return node
+
+    def _write_acknowledgement(self, root=True):
+        ''' Generate csw:Acknowledgement '''
+        node = etree.Element(util.nspath_eval('csw30:Acknowledgement',
+               self.parent.context.namespaces),
+        nsmap = self.parent.context.namespaces, timeStamp=util.get_today_and_now())
+
+        if root:
+            node.attrib[util.nspath_eval('xsi:schemaLocation',
+            self.parent.context.namespaces)] = \
+            '%s %s/csw/3.0/cswAll.xsd' % (self.parent.context.namespaces['csw30'], \
+            self.parent.config.get('server', 'ogc_schemas_base'))
+
+        node1 = etree.SubElement(node, util.nspath_eval('csw30:EchoedRequest',
+                self.parent.context.namespaces))
+        if self.parent.requesttype == 'POST':
+            node1.append(etree.fromstring(self.parent.request, self.parent.context.parser))
+        else:  # GET
+            node2 = etree.SubElement(node1, util.nspath_eval('ows:Get',
+                    self.parent.context.namespaces))
+
+            node2.text = self.parent.request
+
+        if self.parent.async:
+            etree.SubElement(node, util.nspath_eval('csw30:RequestId',
+            self.parent.context.namespaces)).text = self.parent.kvp['requestid']
+
+        return node
+
+    def _write_verboseresponse(self, insertresults):
+        ''' show insert result identifiers '''
+        insertresult = etree.Element(util.nspath_eval('csw30:InsertResult',
+        self.parent.context.namespaces))
+        for ir in insertresults:
+            briefrec = etree.SubElement(insertresult,
+                       util.nspath_eval('csw30:BriefRecord',
+                       self.parent.context.namespaces))
+
+            etree.SubElement(briefrec,
+            util.nspath_eval('dc:identifier',
+            self.parent.context.namespaces)).text = ir['identifier']
+
+            etree.SubElement(briefrec,
+            util.nspath_eval('dc:title',
+            self.parent.context.namespaces)).text = ir['title']
+
+        return insertresult
+
+    def _write_allowed_values(self, values):
+        ''' design pattern to write ows20:AllowedValues '''
+
+        allowed_values = etree.Element(util.nspath_eval('ows20:AllowedValues',
+                                       self.parent.context.namespaces))
+
+        for value in sorted(values):
+            etree.SubElement(allowed_values,
+                             util.nspath_eval('ows20:Value',
+                             self.parent.context.namespaces)).text = value
+        return allowed_values
+
+    def exceptionreport(self, code, locator, text):
+        ''' Generate ExceptionReport '''
+        self.parent.exception = True
+        self.parent.status = code
+
+        try:
+            language = self.parent.config.get('server', 'language')
+            ogc_schemas_base = self.parent.config.get('server', 'ogc_schemas_base')
+        except:
+            language = 'en-US'
+            ogc_schemas_base = self.parent.context.ogc_schemas_base
+
+        node = etree.Element(util.nspath_eval('ows20:ExceptionReport',
+        self.parent.context.namespaces), nsmap=self.parent.context.namespaces,
+        version='3.0.0')
+
+        node.attrib['{http://www.w3.org/XML/1998/namespace}lang'] = language
+
+        node.attrib[util.nspath_eval('xsi:schemaLocation',
+        self.parent.context.namespaces)] = \
+        '%s %s/ows/2.0/owsExceptionReport.xsd' % \
+        (self.parent.context.namespaces['ows20'], ogc_schemas_base)
+
+        exception = etree.SubElement(node, util.nspath_eval('ows20:Exception',
+        self.parent.context.namespaces),
+        exceptionCode=code, locator=locator)
+
+        etree.SubElement(exception,
+        util.nspath_eval('ows20:ExceptionText',
+        self.parent.context.namespaces)).text = text
+
+        return node
+
+    def resolve_nsmap(self, list_):
+        '''' Resolve typename bindings based on default and KVP namespaces '''
+
+        nsmap = {}
+
+        tns = []
+
+        LOGGER.debug('Namespace list pairs: %s', list_)
+
+        # bind KVP namespaces into typenames
+        for ns in self.parent.kvp['namespace'].split(','):
+            nspair = ns.split('(')[1].split(')')[0].split('=')
+            if len(nspair) == 1:  # default namespace
+                nsmap['csw'] = nspair[1]
+            else:
+                nsmap[nspair[0]] = nspair[1]
+
+        LOGGER.debug('Namespace pairs: %s', nsmap)
+
+        for tn in list_:
+            LOGGER.debug(tn)
+            if tn.find(':') != -1:  # resolve prefix
+                prefix = tn.split(':')[0]
+                if prefix in nsmap.keys():  # get uri
+                    uri = nsmap[prefix]
+                    newprefix = next(k for k, v in self.parent.context.namespaces.items() if v == uri)
+                    LOGGER.debug(uri)
+                    LOGGER.debug(prefix)
+                    LOGGER.debug(newprefix)
+                    #if prefix == 'csw30': newprefix = 'csw'
+                    newvalue = tn.replace(prefix, newprefix).replace('csw30', 'csw')
+                else:
+                    newvalue = tn
+            else:  # default namespace
+                newvalue = tn
+
+            tns.append(newvalue)
+
+
+        LOGGER.debug(tns)
+        return tns
+
+def write_boundingbox(bbox, nsmap):
+    ''' Generate ows20:BoundingBox '''
+
+    if bbox is not None:
+        try:
+            bbox2 = util.wkt2geom(bbox)
+        except:
+            return None
+
+        if len(bbox2) == 4:
+            boundingbox = etree.Element(util.nspath_eval('ows20:BoundingBox',
+            nsmap), crs='http://www.opengis.net/def/crs/EPSG/0/4326',
+            dimensions='2')
+
+            etree.SubElement(boundingbox, util.nspath_eval('ows20:LowerCorner',
+            nsmap)).text = '%s %s' % (bbox2[1], bbox2[0])
+
+            etree.SubElement(boundingbox, util.nspath_eval('ows20:UpperCorner',
+            nsmap)).text = '%s %s' % (bbox2[3], bbox2[2])
+
+            return boundingbox
+        else:
+            return None
+    else:
+        return None
+        if nextrecord == 0:
+            searchresult_status = 'complete'
+        elif nextrecord > 0:
+            searchresult_status = 'subset'
+        elif matched == 0:
+            searchresult_status = 'none'
+
+def get_resultset_status(matched, nextrecord):
+    ''' Helper function to assess status of a result set '''
+
+    status = 'subset'  # default
+
+    if nextrecord == 0:
+        status = 'complete'
+    elif matched == 0:
+       status = 'none'
+
+    return status
diff --git a/pycsw/plugins/profiles/__init__.py b/pycsw/ogc/fes/__init__.py
similarity index 95%
copy from pycsw/plugins/profiles/__init__.py
copy to pycsw/ogc/fes/__init__.py
index f98f82b..08a4c3d 100644
--- a/pycsw/plugins/profiles/__init__.py
+++ b/pycsw/ogc/fes/__init__.py
@@ -1,9 +1,9 @@
-# -*- coding: ISO-8859-15 -*-
+# -*- coding: utf-8 -*-
 # =================================================================
 #
 # Authors: Tom Kralidis <tomkralidis at gmail.com>
 #
-# Copyright (c) 2011 Tom Kralidis
+# Copyright (c) 2015 Tom Kralidis
 #
 # Permission is hereby granted, free of charge, to any person
 # obtaining a copy of this software and associated documentation
diff --git a/pycsw/fes.py b/pycsw/ogc/fes/fes1.py
similarity index 98%
copy from pycsw/fes.py
copy to pycsw/ogc/fes/fes1.py
index 70d30c1..4b104a7 100644
--- a/pycsw/fes.py
+++ b/pycsw/ogc/fes/fes1.py
@@ -1,11 +1,11 @@
-# -*- coding: iso-8859-15 -*-
+# -*- coding: utf-8 -*-
 # =================================================================
 #
 # Authors: Tom Kralidis <tomkralidis at gmail.com>
 #          Angelos Tzotsos <tzotsos at gmail.com>
 #
-# Copyright (c) 2010 Tom Kralidis
-# Copyright (c) 2014 Angelos Tzotsos
+# Copyright (c) 2015 Tom Kralidis
+# Copyright (c) 2015 Angelos Tzotsos
 #
 # Permission is hereby granted, free of charge, to any person
 # obtaining a copy of this software and associated documentation
@@ -31,13 +31,14 @@
 # =================================================================
 
 import logging
-from pycsw import gml, util
+from pycsw.core import util
+from pycsw.ogc.gml import gml3
 
 LOGGER = logging.getLogger(__name__)
 
 MODEL = {
     'GeometryOperands': {
-        'values': gml.TYPES
+        'values': gml3.TYPES
     },
     'SpatialOperators': {
         'values': ['BBOX', 'Beyond', 'Contains', 'Crosses', 'Disjoint',
@@ -307,8 +308,8 @@ def _get_spatial_operator(geomattr, element, dbtype, nsmap, postgis_geometry_col
         raise RuntimeError('Invalid ogc:PropertyName in spatial filter: %s' %
                            property_name.text)
 
-    geometry = gml.Geometry(element, nsmap)
-    
+    geometry = gml3.Geometry(element, nsmap)
+
     #make decision to apply spatial ranking to results
     set_spatial_ranking(geometry)
 
@@ -351,7 +352,7 @@ def _get_spatial_operator(geomattr, element, dbtype, nsmap, postgis_geometry_col
             spatial_query = "st_%s(st_geomfromtext(%s), \
             st_geomfromtext('%s'))" % \
                 (spatial_predicate, geomattr, geometry.wkt)
-                
+
     elif dbtype == 'postgresql+postgis+native':  # adjust spatial query for PostGIS with native geometry
         LOGGER.debug('Adjusting spatial query for PostgreSQL+PostGIS+native')
         if spatial_predicate == 'bbox':
@@ -369,7 +370,7 @@ def _get_spatial_operator(geomattr, element, dbtype, nsmap, postgis_geometry_col
             spatial_query = "st_%s(%s, \
             st_geomfromtext('%s',4326))" % \
                 (spatial_predicate, postgis_geometry_column, geometry.wkt)
-                
+
     else:
         LOGGER.debug('Adjusting spatial query')
         spatial_query = "query_spatial(%s,'%s','%s','%s')" % \
@@ -384,9 +385,9 @@ def _get_comparison_operator(element):
     return MODEL['ComparisonOperators']['ogc:%s' % util.xmltag_split(element.tag)]['opvalue']
 
 def set_spatial_ranking(geometry):
-    """Given that we have a spatial query in ogc:Filter we check the type of geometry 
+    """Given that we have a spatial query in ogc:Filter we check the type of geometry
     and set the ranking variables"""
-    
+
     if util.ranking_enabled:
         if geometry.type in ['Polygon', 'Envelope']:
             util.ranking_pass = True
diff --git a/pycsw/fes.py b/pycsw/ogc/fes/fes2.py
similarity index 89%
rename from pycsw/fes.py
rename to pycsw/ogc/fes/fes2.py
index 70d30c1..ce2271c 100644
--- a/pycsw/fes.py
+++ b/pycsw/ogc/fes/fes2.py
@@ -1,11 +1,11 @@
-# -*- coding: iso-8859-15 -*-
+# -*- coding: utf-8 -*-
 # =================================================================
 #
 # Authors: Tom Kralidis <tomkralidis at gmail.com>
 #          Angelos Tzotsos <tzotsos at gmail.com>
 #
-# Copyright (c) 2010 Tom Kralidis
-# Copyright (c) 2014 Angelos Tzotsos
+# Copyright (c) 2015 Tom Kralidis
+# Copyright (c) 2015 Angelos Tzotsos
 #
 # Permission is hereby granted, free of charge, to any person
 # obtaining a copy of this software and associated documentation
@@ -31,41 +31,61 @@
 # =================================================================
 
 import logging
-from pycsw import gml, util
+from pycsw.core import util
+from pycsw.ogc.gml import gml3
 
 LOGGER = logging.getLogger(__name__)
 
 MODEL = {
+    'Conformance': {
+        'values': [
+            'ImplementsQuery',
+            'ImplementsAdHocQuery',
+            'ImplementsFunctions',
+            'ImplementsResourceld',
+            'ImplementsMinStandardFilter',
+            'ImplementsStandardFilter',
+            'ImplementsMinSpatialFilter',
+            'ImplementsSpatialFilter',
+            'ImplementsMinTemporalFilter',
+            'ImplementsTemporalFilter',
+            'ImplementsVersionNav',
+            'ImplementsSorting',
+            'ImplementsExtendedOperators',
+            'ImplementsMinimumXPath',
+            'ImplementsSchemaElementFunc'
+        ]
+    },
     'GeometryOperands': {
-        'values': gml.TYPES
+        'values': gml3.TYPES
     },
     'SpatialOperators': {
         'values': ['BBOX', 'Beyond', 'Contains', 'Crosses', 'Disjoint',
         'DWithin', 'Equals', 'Intersects', 'Overlaps', 'Touches', 'Within']
     },
     'ComparisonOperators': {
-        'ogc:PropertyIsBetween': {'opname': 'Between', 'opvalue': 'and'},
-        'ogc:PropertyIsEqualTo': {'opname': 'EqualTo', 'opvalue': '='},
-        'ogc:PropertyIsGreaterThan': {'opname': 'GreaterThan', 'opvalue': '>'},
+        'ogc:PropertyIsBetween': {'opname': 'PropertyIsBetween', 'opvalue': 'and'},
+        'ogc:PropertyIsEqualTo': {'opname': 'PropertyIsEqualTo', 'opvalue': '='},
+        'ogc:PropertyIsGreaterThan': {'opname': 'PropertyIsGreaterThan', 'opvalue': '>'},
         'ogc:PropertyIsGreaterThanOrEqualTo': {
-            'opname': 'GreaterThanEqualTo', 'opvalue': '>='},
-        'ogc:PropertyIsLessThan': {'opname': 'LessThan', 'opvalue': '<'},
+            'opname': 'PropertyIsGreaterThanOrEqualTo', 'opvalue': '>='},
+        'ogc:PropertyIsLessThan': {'opname': 'PropertyIsLessThan', 'opvalue': '<'},
         'ogc:PropertyIsLessThanOrEqualTo': {
-            'opname': 'LessThanEqualTo', 'opvalue': '<='},
-        'ogc:PropertyIsLike': {'opname': 'Like', 'opvalue': 'like'},
-        'ogc:PropertyIsNotEqualTo': {'opname': 'NotEqualTo', 'opvalue': '!='},
-        'ogc:PropertyIsNull': {'opname': 'NullCheck', 'opvalue': 'is null'},
+            'opname': 'PropertyIsLessThanOrEqualTo', 'opvalue': '<='},
+        'ogc:PropertyIsLike': {'opname': 'PropertyIsLike', 'opvalue': 'like'},
+        'ogc:PropertyIsNotEqualTo': {'opname': 'PropertyIsNotEqualTo', 'opvalue': '!='},
+        'ogc:PropertyIsNull': {'opname': 'PropertyIsNull', 'opvalue': 'is null'},
     },
     'Functions': {
-        'length': {'args': '1'},
-        'lower': {'args': '1'},
-        'ltrim': {'args': '1'},
-        'rtrim': {'args': '1'},
-        'trim': {'args': '1'},
-        'upper': {'args': '1'},
+        'length': {'returns': 'xs:string'},
+        'lower': {'returns': 'xs:string'},
+        'ltrim': {'returns': 'xs:string'},
+        'rtrim': {'returns': 'xs:string'},
+        'trim': {'returns': 'xs:string'},
+        'upper': {'returns': 'xs:string'},
     },
     'Ids': {
-        'values': ['EID', 'FID']
+        'values': ['csw30:id']
     }
 }
 
@@ -307,8 +327,8 @@ def _get_spatial_operator(geomattr, element, dbtype, nsmap, postgis_geometry_col
         raise RuntimeError('Invalid ogc:PropertyName in spatial filter: %s' %
                            property_name.text)
 
-    geometry = gml.Geometry(element, nsmap)
-    
+    geometry = gml3.Geometry(element, nsmap)
+
     #make decision to apply spatial ranking to results
     set_spatial_ranking(geometry)
 
@@ -351,7 +371,7 @@ def _get_spatial_operator(geomattr, element, dbtype, nsmap, postgis_geometry_col
             spatial_query = "st_%s(st_geomfromtext(%s), \
             st_geomfromtext('%s'))" % \
                 (spatial_predicate, geomattr, geometry.wkt)
-                
+
     elif dbtype == 'postgresql+postgis+native':  # adjust spatial query for PostGIS with native geometry
         LOGGER.debug('Adjusting spatial query for PostgreSQL+PostGIS+native')
         if spatial_predicate == 'bbox':
@@ -369,7 +389,7 @@ def _get_spatial_operator(geomattr, element, dbtype, nsmap, postgis_geometry_col
             spatial_query = "st_%s(%s, \
             st_geomfromtext('%s',4326))" % \
                 (spatial_predicate, postgis_geometry_column, geometry.wkt)
-                
+
     else:
         LOGGER.debug('Adjusting spatial query')
         spatial_query = "query_spatial(%s,'%s','%s','%s')" % \
@@ -384,9 +404,9 @@ def _get_comparison_operator(element):
     return MODEL['ComparisonOperators']['ogc:%s' % util.xmltag_split(element.tag)]['opvalue']
 
 def set_spatial_ranking(geometry):
-    """Given that we have a spatial query in ogc:Filter we check the type of geometry 
+    """Given that we have a spatial query in ogc:Filter we check the type of geometry
     and set the ranking variables"""
-    
+
     if util.ranking_enabled:
         if geometry.type in ['Polygon', 'Envelope']:
             util.ranking_pass = True
diff --git a/pycsw/plugins/profiles/__init__.py b/pycsw/ogc/gml/__init__.py
similarity index 95%
copy from pycsw/plugins/profiles/__init__.py
copy to pycsw/ogc/gml/__init__.py
index f98f82b..08a4c3d 100644
--- a/pycsw/plugins/profiles/__init__.py
+++ b/pycsw/ogc/gml/__init__.py
@@ -1,9 +1,9 @@
-# -*- coding: ISO-8859-15 -*-
+# -*- coding: utf-8 -*-
 # =================================================================
 #
 # Authors: Tom Kralidis <tomkralidis at gmail.com>
 #
-# Copyright (c) 2011 Tom Kralidis
+# Copyright (c) 2015 Tom Kralidis
 #
 # Permission is hereby granted, free of charge, to any person
 # obtaining a copy of this software and associated documentation
diff --git a/pycsw/gml.py b/pycsw/ogc/gml/gml3.py
similarity index 98%
rename from pycsw/gml.py
rename to pycsw/ogc/gml/gml3.py
index 21bd0dc..990dca3 100644
--- a/pycsw/gml.py
+++ b/pycsw/ogc/gml/gml3.py
@@ -1,9 +1,9 @@
-# -*- coding: iso-8859-15 -*-
+# -*- coding: utf-8 -*-
 # =================================================================
 #
 # Authors: Tom Kralidis <tomkralidis at gmail.com>
 #
-# Copyright (c) 2010 Tom Kralidis
+# Copyright (c) 2015 Tom Kralidis
 #
 # Permission is hereby granted, free of charge, to any person
 # obtaining a copy of this software and associated documentation
@@ -28,9 +28,10 @@
 #
 # =================================================================
 
+from six.moves import zip
 import logging
-from pycsw import util
 from owslib import crs
+from pycsw.core import util
 
 LOGGER = logging.getLogger(__name__)
 
diff --git a/pycsw/opensearch.py b/pycsw/opensearch.py
index 198e52c..40c7e31 100644
--- a/pycsw/opensearch.py
+++ b/pycsw/opensearch.py
@@ -1,10 +1,11 @@
-# -*- coding: iso-8859-15 -*-
+# -*- coding: utf-8 -*-
 # =================================================================
 #
 # Authors: Tom Kralidis <tomkralidis at gmail.com>
 #          Angelos Tzotsos <tzotsos at gmail.com>
 #
-# Copyright (c) 2014 Tom Kralidis, Angelos Tzotsos
+# Copyright (c) 2015 Tom Kralidis
+# Copyright (c) 2015 Angelos Tzotsos
 #
 # Permission is hereby granted, free of charge, to any person
 # obtaining a copy of this software and associated documentation
@@ -29,9 +30,10 @@
 #
 # =================================================================
 
-from lxml import etree
-from pycsw import util
+import six
 import logging
+from pycsw.core import util
+from pycsw.core.etree import etree
 
 LOGGER = logging.getLogger(__name__)
 
@@ -49,7 +51,7 @@ class OpenSearch(object):
         }
 
         self.context = context
-        #self.context.namespaces.update(self.namespaces)
+        self.context.namespaces.update(self.namespaces)
 
     def response_csw2opensearch(self, element, cfg):
         """transform a CSW response into an OpenSearch response"""
@@ -59,82 +61,196 @@ class OpenSearch(object):
             return element
 
         LOGGER.debug('RESPONSE: %s', root_tag)
+        try:
+            version = element.xpath('//@version')[0]
+        except Exception as err:
+            version = '3.0.0'
+
+        self.exml = element
+        self.cfg = cfg
+        self.bind_url = util.bind_url(self.cfg.get('server', 'url'))
+
+        if version == '2.0.2':
+            return self._csw2_2_os()
+        elif version == '3.0.0':
+            return self._csw3_2_os()
+
+    def _csw2_2_os(self):
+        """CSW 2.0.2 Capabilities to OpenSearch Description"""
 
-        if util.xmltag_split(element.tag) == 'GetRecordsResponse':
+        if util.xmltag_split(self.exml.tag) == 'GetRecordsResponse':
 
-            startindex = int(element.xpath('//@nextRecord')[0]) - int(
-                        element.xpath('//@numberOfRecordsReturned')[0])
+            startindex = int(self.exml.xpath('//@nextRecord')[0]) - int(
+                        self.exml.xpath('//@numberOfRecordsReturned')[0])
             if startindex < 1:
                 startindex = 1
 
             node = etree.Element(util.nspath_eval('atom:feed',
                        self.context.namespaces), nsmap=self.namespaces)
             etree.SubElement(node, util.nspath_eval('atom:id',
-                       self.context.namespaces)).text = cfg.get('server', 'url')
+                       self.context.namespaces)).text = self.cfg.get('server', 'url')
             etree.SubElement(node, util.nspath_eval('atom:title',
-                       self.context.namespaces)).text = cfg.get('metadata:main',
+                       self.context.namespaces)).text = self.cfg.get('metadata:main',
                        'identification_title')
             #etree.SubElement(node, util.nspath_eval('atom:updated',
-            #  self.context.namespaces)).text = element.xpath('//@timestamp')[0]
+            #  self.context.namespaces)).text = self.exml.xpath('//@timestamp')[0]
 
             etree.SubElement(node, util.nspath_eval('os:totalResults',
-                        self.context.namespaces)).text = element.xpath(
+                        self.context.namespaces)).text = self.exml.xpath(
                         '//@numberOfRecordsMatched')[0]
             etree.SubElement(node, util.nspath_eval('os:startIndex',
                         self.context.namespaces)).text = str(startindex)
             etree.SubElement(node, util.nspath_eval('os:itemsPerPage',
-                        self.context.namespaces)).text = element.xpath(
+                        self.context.namespaces)).text = self.exml.xpath(
                         '//@numberOfRecordsReturned')[0]
 
-            for rec in element.xpath('//atom:entry',
+            for rec in self.exml.xpath('//atom:entry',
                         namespaces=self.context.namespaces):
                 node.append(rec)
-        elif util.xmltag_split(element.tag) == 'Capabilities':
-            node = etree.Element('OpenSearchDescription', nsmap={None: self.namespaces['os']})
-            etree.SubElement(node, 'ShortName').text = element.xpath('//ows:Title', namespaces=self.context.namespaces)[0].text
-            etree.SubElement(node, 'LongName').text = element.xpath('//ows:Title', namespaces=self.context.namespaces)[0].text
-            etree.SubElement(node, 'Description').text = element.xpath('//ows:Abstract', namespaces=self.context.namespaces)[0].text
-            etree.SubElement(node, 'Tags').text = ' '.join(x.text for x in element.xpath('//ows:Keyword', namespaces=self.context.namespaces))
-
-            node1 = etree.SubElement(node, 'Url')
+        elif util.xmltag_split(self.exml.tag) == 'Capabilities':
+            node = etree.Element(util.nspath_eval('os:OpenSearchDescription', self.namespaces), nsmap=self.namespaces)
+            etree.SubElement(node, util.nspath_eval('os:ShortName', self.namespaces)).text = self.exml.xpath('//ows:Title', namespaces=self.context.namespaces)[0].text
+            etree.SubElement(node, util.nspath_eval('os:LongName', self.namespaces)).text = self.exml.xpath('//ows:Title', namespaces=self.context.namespaces)[0].text
+            etree.SubElement(node, util.nspath_eval('os:Description', self.namespaces)).text = self.exml.xpath('//ows:Abstract', namespaces=self.context.namespaces)[0].text
+            etree.SubElement(node, util.nspath_eval('os:Tags', self.namespaces)).text = ' '.join(x.text for x in self.exml.xpath('//ows:Keyword', namespaces=self.context.namespaces))
+
+            node1 = etree.SubElement(node, util.nspath_eval('os:Url', self.namespaces))
             node1.set('type', 'application/atom+xml')
             node1.set('method', 'get')
-            node1.set('template', '%s?mode=opensearch&service=CSW&version=2.0.2&request=GetRecords&elementsetname=full&typenames=csw:Record&resulttype=results&q={searchTerms?}&bbox={geo:box?}&time={time:start?}/{time:end?}&startposition={startIndex?}&maxrecords={count?}' % element.xpath('//ows:Get/@xlink:href', namespaces=self.context.namespaces)[0])
+            node1.set('template', '%smode=opensearch&service=CSW&version=2.0.2&request=GetRecords&elementsetname=full&typenames=csw:Record&resulttype=results&q={searchTerms?}&bbox={geo:box?}&time={time:start?}/{time:end?}&startposition={startIndex?}&maxrecords={count?}' % self.bind_url)
 
-            node1 = etree.SubElement(node, 'Image')
+            node1 = etree.SubElement(node, util.nspath_eval('os:Image', self.namespaces))
             node1.set('type', 'image/vnd.microsoft.icon')
             node1.set('width', '16')
             node1.set('height', '16')
             node1.text = 'http://pycsw.org/img/favicon.ico'
 
-            etree.SubElement(node, 'Developer').text = element.xpath('//ows:IndividualName', namespaces=self.context.namespaces)[0].text
-            etree.SubElement(node, 'Contact').text = element.xpath('//ows:ElectronicMailAddress', namespaces=self.context.namespaces)[0].text
-            etree.SubElement(node, 'Attribution').text = element.xpath('//ows:ProviderName', namespaces=self.context.namespaces)[0].text
-        elif util.xmltag_split(element.tag) == 'ExceptionReport':
-            node = element
+            etree.SubElement(node, util.nspath_eval('os:Developer', self.namespaces)).text = self.exml.xpath('//ows:IndividualName', namespaces=self.context.namespaces)[0].text
+            etree.SubElement(node, util.nspath_eval('os:Context', self.namespaces)).text = self.exml.xpath('//ows:ElectronicMailAddress', namespaces=self.context.namespaces)[0].text
+            etree.SubElement(node, util.nspath_eval('os:Attribution', self.namespaces)).text = self.exml.xpath('//ows:ProviderName', namespaces=self.context.namespaces)[0].text
+        elif util.xmltag_split(self.exml.tag) == 'ExceptionReport':
+            node = self.exml
         else:  # return Description document
             node = etree.Element(util.nspath_eval('os:Description', self.context.namespaces))
 
         return node
 
+    def _csw3_2_os(self):
+        """CSW 3.0.0 Capabilities to OpenSearch Description"""
+
+        if util.xmltag_split(self.exml.tag) == 'GetRecordsResponse':
+
+            startindex = int(self.exml.xpath('//@nextRecord')[0]) - int(
+                        self.exml.xpath('//@numberOfRecordsReturned')[0])
+            if startindex < 1:
+                startindex = 1
+
+            node = etree.Element(util.nspath_eval('atom:feed',
+                       self.context.namespaces), nsmap=self.namespaces)
+            etree.SubElement(node, util.nspath_eval('atom:id',
+                       self.context.namespaces)).text = self.cfg.get('server', 'url')
+            etree.SubElement(node, util.nspath_eval('atom:title',
+                       self.context.namespaces)).text = self.cfg.get('metadata:main',
+                       'identification_title')
+            author = etree.SubElement(node, util.nspath_eval('atom:author', self.context.namespaces))
+            etree.SubElement(author, util.nspath_eval('atom:name', self.context.namespaces)).text = self.cfg.get('metadata:main',
+                       'provider_name')
+            etree.SubElement(node, util.nspath_eval('atom:link',
+                       self.context.namespaces), rel='search',
+                           type='application/opensearchdescription+xml',
+                           href='%smode=opensearch&service=CSW&version=3.0.0&request=GetCapabilities' % self.bind_url)
+
+            etree.SubElement(node, util.nspath_eval('atom:updated',
+                self.context.namespaces)).text = self.exml.xpath('//@timestamp')[0]
+
+            etree.SubElement(node, util.nspath_eval('os:Query', self.context.namespaces), role='request')
+
+            etree.SubElement(node, util.nspath_eval('os:totalResults',
+                        self.context.namespaces)).text = self.exml.xpath(
+                        '//@numberOfRecordsMatched')[0]
+            etree.SubElement(node, util.nspath_eval('os:startIndex',
+                        self.context.namespaces)).text = str(startindex)
+            etree.SubElement(node, util.nspath_eval('os:itemsPerPage',
+                        self.context.namespaces)).text = self.exml.xpath(
+                        '//@numberOfRecordsReturned')[0]
+
+            for rec in self.exml.xpath('//atom:entry',
+                        namespaces=self.context.namespaces):
+                node.append(rec)
+        elif util.xmltag_split(self.exml.tag) == 'Capabilities':
+            node = etree.Element(util.nspath_eval('os:OpenSearchDescription', self.namespaces), nsmap=self.namespaces)
+            etree.SubElement(node, util.nspath_eval('os:ShortName', self.namespaces)).text = self.exml.xpath('//ows20:Title', namespaces=self.context.namespaces)[0].text[:16]
+            etree.SubElement(node, util.nspath_eval('os:LongName', self.namespaces)).text = self.exml.xpath('//ows20:Title', namespaces=self.context.namespaces)[0].text
+            etree.SubElement(node, util.nspath_eval('os:Description', self.namespaces)).text = self.exml.xpath('//ows20:Abstract', namespaces=self.context.namespaces)[0].text
+            etree.SubElement(node, util.nspath_eval('os:Tags', self.namespaces)).text = ' '.join(x.text for x in self.exml.xpath('//ows20:Keyword', namespaces=self.context.namespaces))
+
+            # Requirement-022
+            node1 = etree.SubElement(node, util.nspath_eval('os:Url', self.namespaces))
+            node1.set('type', 'application/xml')
+            node1.set('template', '%sservice=CSW&version=3.0.0&request=GetRecords&elementsetname=full&typenames=csw:Record&resulttype=results&q={searchTerms?}&bbox={geo:box?}&time={time:start?}/{time:end?}&outputformat=application/xml&outputschema=http://www.opengis.net/cat/csw/3.0&startposition={startIndex?}&maxrecords={count?}&recordids={geo:uid}' % self.bind_url)
+
+            # Requirement-023
+            node1 = etree.SubElement(node, util.nspath_eval('os:Url', self.namespaces))
+            node1.set('type', 'application/atom+xml')
+            node1.set('template', '%smode=opensearch&service=CSW&version=3.0.0&request=GetRecords&elementsetname=full&typenames=csw:Record&resulttype=results&q={searchTerms?}&bbox={geo:box?}&time={time:start?}/{time:end?}&outputformat=application/atom+xml&&startposition={startIndex?}&maxrecords={count?}&recordids={geo:uid}' % self.bind_url)
+
+            node1 = etree.SubElement(node, util.nspath_eval('os:Image', self.namespaces))
+            node1.set('type', 'image/vnd.microsoft.icon')
+            node1.set('width', '16')
+            node1.set('height', '16')
+            node1.text = 'http://pycsw.org/img/favicon.ico'
+
+            os_query = etree.SubElement(node, util.nspath_eval('os:Query', self.namespaces), role='example')
+            os_query.attrib[util.nspath_eval('geo:box', self.namespaces)] = '-180,-90,180,90'
+
+            etree.SubElement(node, util.nspath_eval('os:Developer', self.namespaces)).text = self.exml.xpath('//ows20:IndividualName', namespaces=self.context.namespaces)[0].text
+            etree.SubElement(node, util.nspath_eval('os:Contact', self.namespaces)).text = self.exml.xpath('//ows20:ElectronicMailAddress', namespaces=self.context.namespaces)[0].text
+            etree.SubElement(node, util.nspath_eval('os:Attribution', self.namespaces)).text = self.exml.xpath('//ows20:ProviderName', namespaces=self.context.namespaces)[0].text
+        elif util.xmltag_split(self.exml.tag) == 'ExceptionReport':
+            node = self.exml
+        else:  # GetRecordById output
+            node = etree.Element(util.nspath_eval('atom:feed',
+                       self.context.namespaces), nsmap=self.namespaces)
+            etree.SubElement(node, util.nspath_eval('atom:id',
+                       self.context.namespaces)).text = self.cfg.get('server', 'url')
+            etree.SubElement(node, util.nspath_eval('atom:title',
+                       self.context.namespaces)).text = self.cfg.get('metadata:main',
+                       'identification_title')
+            #etree.SubElement(node, util.nspath_eval('atom:updated',
+            #  self.context.namespaces)).text = self.exml.xpath('//@timestamp')[0]
+
+            etree.SubElement(node, util.nspath_eval('os:totalResults',
+                        self.context.namespaces)).text = '1'
+            etree.SubElement(node, util.nspath_eval('os:startIndex',
+                        self.context.namespaces)).text = '1'
+            etree.SubElement(node, util.nspath_eval('os:itemsPerPage',
+                        self.context.namespaces)).text = '1'
+
+            for rec in self.exml.xpath('//atom:entry', namespaces=self.context.namespaces):
+                #node.append(rec)
+                node = rec
+        return node
+
 
 def kvp2filterxml(kvp, context):
+    ''' transform kvp to filter XML string '''
 
-    filter_xml = ""
-    valid_xml = ""
+    bbox_element = None
+    time_element = None
+    anytext_elements = []
 
     # Count parameters
     par_count = 0
     for p in ['q','bbox','time']:
-        if p in kvp:
+        if p in kvp and kvp[p] != '':
             par_count += 1
 
     # Create root element for FilterXML
-    root = etree.Element(util.nspath_eval('ogc:Filter',
-                context.namespaces))
+    root = etree.Element(util.nspath_eval('ogc:Filter', context.namespaces))
 
     # bbox to FilterXML
-    if 'bbox' in kvp:
+    if 'bbox' in kvp and kvp['bbox'] != '':
+        LOGGER.debug('Detected bbox parameter')
         bbox_list = [x.strip() for x in kvp['bbox'].split(',')]
         bbox_element = etree.Element(util.nspath_eval('ogc:BBOX',
                     context.namespaces))
@@ -146,6 +262,18 @@ def kvp2filterxml(kvp, context):
                     context.namespaces))
         el = etree.Element(util.nspath_eval('gml:lowerCorner',
                     context.namespaces))
+
+        if len(bbox_list) == 5:  # add srsName
+            LOGGER.debug('Found CRS')
+            env.attrib['srsName'] = bbox_list[4]
+        else:
+            LOGGER.debug('Assuming 4326')
+            env.attrib['srsName'] = 'urn:ogc:def:crs:OGC:1.3:CRS84'
+            if not util.validate_4326(bbox_list):
+                msg = '4326 coordinates out of range: %s' % bbox_list
+                LOGGER.debug(msg)
+                raise RuntimeError(msg)
+
         try:
             el.text = "%s %s" % (bbox_list[0], bbox_list[1])
         except Exception as err:
@@ -163,25 +291,38 @@ def kvp2filterxml(kvp, context):
         bbox_element.append(env)
 
     # q to FilterXML
-    if 'q' in kvp:
-        anytext_element = etree.Element(util.nspath_eval('ogc:PropertyIsEqualTo',
-                    context.namespaces))
-        el = etree.Element(util.nspath_eval('ogc:PropertyName',
-                    context.namespaces))
-        el.text = 'csw:AnyText'
-        anytext_element.append(el)
-        el = etree.Element(util.nspath_eval('ogc:Literal',
-                    context.namespaces))
-        el.text = kvp['q']
-        anytext_element.append(el)
+    if 'q' in kvp and kvp['q'] != '':
+        LOGGER.debug('Detected q parameter')
+        qvals = kvp['q'].split()
+        LOGGER.debug(qvals)
+        if len(qvals) > 1:
+            par_count += 1
+        for qval in qvals:
+            LOGGER.debug('processing q token')
+            anytext_element = etree.Element(util.nspath_eval('ogc:PropertyIsEqualTo',
+                        context.namespaces))
+            el = etree.Element(util.nspath_eval('ogc:PropertyName',
+                        context.namespaces))
+            el.text = 'csw:AnyText'
+            anytext_element.append(el)
+            el = etree.Element(util.nspath_eval('ogc:Literal',
+                        context.namespaces))
+            if six.PY2:
+                el.text = qval.decode('utf8')
+            else:
+                el.text = qval
+            anytext_element.append(el)
+            anytext_elements.append(anytext_element)
 
     # time to FilterXML
-    if 'time' in kvp:
+    if 'time' in kvp and kvp['time'] != '':
+        LOGGER.debug('Detected time parameter %s', kvp['time'])
         time_list = kvp['time'].split("/")
-        time_element = None
         if (len(time_list) == 2):
+            LOGGER.debug('TIMELIST: %s', time_list)
             # This is a normal request
             if '' not in time_list:
+                LOGGER.debug('Both dates present')
                 # Both dates are present
                 time_element = etree.Element(util.nspath_eval('ogc:PropertyIsBetween',
                             context.namespaces))
@@ -204,8 +345,10 @@ def kvp2filterxml(kvp, context):
                 el.append(el2)
                 time_element.append(el)
             else:
+                if time_list == ['', '']:
+                    par_count -= 1
                 # One of two is empty
-                if time_list[1] is '':
+                elif time_list[1] is '':
                     time_element = etree.Element(util.nspath_eval('ogc:PropertyIsGreaterThanOrEqualTo',
                                 context.namespaces))
                     el = etree.Element(util.nspath_eval('ogc:PropertyName',
@@ -244,25 +387,33 @@ def kvp2filterxml(kvp, context):
             errortext = 'Exception: OpenSearch time not valid: %s.' % str(kvp['time'])
             LOGGER.debug(errortext)
 
-    if (par_count == 1):
+    if par_count == 0:
+        return ''
+    elif par_count == 1:
+        LOGGER.debug('Single predicate filter')
         # Only one OpenSearch parameter exists
-        if 'bbox' in kvp:
+        if 'bbox' in kvp and kvp['bbox'] != '':
+            LOGGER.debug('Adding bbox')
             root.append(bbox_element)
-        elif 'time' in kvp:
+        elif time_element is not None:
+            LOGGER.debug('Adding time')
             root.append(time_element)
-        elif 'q' in kvp:
-            root.append(anytext_element)
+        elif anytext_elements:
+            LOGGER.debug('Adding anytext')
+            root.extend(anytext_elements)
     elif (par_count > 1):
+        LOGGER.debug('ogc:And query (%d predicates)', par_count)
         # Since more than 1 parameter, append the AND logical operator
         logical_and = etree.Element(util.nspath_eval('ogc:And',
                 context.namespaces))
-        if 'bbox' in kvp:
+        if bbox_element is not None:
             logical_and.append(bbox_element)
-        if 'time' in kvp:
+        if time_element is not None:
             logical_and.append(time_element)
-        if 'q' in kvp:
-            logical_and.append(anytext_element)
+        if anytext_elements is not None:
+            logical_and.extend(anytext_elements)
         root.append(logical_and)
 
     # Render etree to string XML
-    return etree.tostring(root)
+    LOGGER.debug(etree.tostring(root, encoding='unicode'))
+    return etree.tostring(root, encoding='unicode')
diff --git a/pycsw/plugins/__init__.py b/pycsw/plugins/__init__.py
index f98f82b..08a4c3d 100644
--- a/pycsw/plugins/__init__.py
+++ b/pycsw/plugins/__init__.py
@@ -1,9 +1,9 @@
-# -*- coding: ISO-8859-15 -*-
+# -*- coding: utf-8 -*-
 # =================================================================
 #
 # Authors: Tom Kralidis <tomkralidis at gmail.com>
 #
-# Copyright (c) 2011 Tom Kralidis
+# Copyright (c) 2015 Tom Kralidis
 #
 # Permission is hereby granted, free of charge, to any person
 # obtaining a copy of this software and associated documentation
diff --git a/pycsw/plugins/outputschemas/__init__.py b/pycsw/plugins/outputschemas/__init__.py
index 067ff50..84afbdd 100644
--- a/pycsw/plugins/outputschemas/__init__.py
+++ b/pycsw/plugins/outputschemas/__init__.py
@@ -1,9 +1,9 @@
-# -*- coding: ISO-8859-15 -*-
+# -*- coding: utf-8 -*-
 # =================================================================
 #
 # Authors: Tom Kralidis <tomkralidis at gmail.com>
 #
-# Copyright (c) 2013 Tom Kralidis
+# Copyright (c) 2015 Tom Kralidis
 #
 # Permission is hereby granted, free of charge, to any person
 # obtaining a copy of this software and associated documentation
@@ -27,4 +27,5 @@
 # OTHER DEALINGS IN THE SOFTWARE.
 #
 # =================================================================
-__all__ = ['atom', 'dif', 'fgdc']
+
+__all__ = ['atom', 'dif', 'fgdc', 'gm03']
diff --git a/pycsw/plugins/outputschemas/atom.py b/pycsw/plugins/outputschemas/atom.py
index 28c4d12..0fa8232 100644
--- a/pycsw/plugins/outputschemas/atom.py
+++ b/pycsw/plugins/outputschemas/atom.py
@@ -1,9 +1,9 @@
-# -*- coding: iso-8859-15 -*-
+# -*- coding: utf-8 -*-
 # =================================================================
 #
 # Authors: Tom Kralidis <tomkralidis at gmail.com>
 #
-# Copyright (c) 2012 Tom Kralidis
+# Copyright (c) 2015 Tom Kralidis
 #
 # Permission is hereby granted, free of charge, to any person
 # obtaining a copy of this software and associated documentation
@@ -29,8 +29,8 @@
 # =================================================================
 
 import os
-from lxml import etree
-from pycsw import util
+from pycsw.core import util
+from pycsw.core.etree import etree
 
 NAMESPACE = 'http://www.w3.org/2005/Atom'
 NAMESPACES = {'atom': NAMESPACE, 'georss': 'http://www.georss.org/georss'}
@@ -63,33 +63,50 @@ def write_record(result, esn, context, url=None):
 
     # author
     val = util.getqattr(result, context.md_core_model['mappings']['pycsw:Creator'])
-     
     if val:
-        etree.SubElement(node, util.nspath_eval('atom:author', NAMESPACES)).text = val
+        author = etree.SubElement(node, util.nspath_eval('atom:author', NAMESPACES))
+        etree.SubElement(author, util.nspath_eval('atom:name', NAMESPACES)).text = val
 
     # category
     val = util.getqattr(result, context.md_core_model['mappings']['pycsw:Keywords'])
 
     if val:
         for kw in val.split(','):
-            etree.SubElement(node, util.nspath_eval('atom:category', NAMESPACES)).text = kw
+            etree.SubElement(node, util.nspath_eval('atom:category', NAMESPACES), term=kw)
 
 
     for qval in ['pycsw:Contributor', 'pycsw:Identifier']:
         val = util.getqattr(result, context.md_core_model['mappings'][qval])
         if val:
             etree.SubElement(node, util.nspath_eval(XPATH_MAPPINGS[qval], NAMESPACES)).text = val
+            if qval == 'pycsw:Identifier':
+                etree.SubElement(node, util.nspath_eval('dc:identifier', context.namespaces)).text = val
 
     rlinks = util.getqattr(result, context.md_core_model['mappings']['pycsw:Links'])
     if rlinks:
         for link in rlinks.split('^'):
             linkset = link.split(',')
-       
+
             url2 = etree.SubElement(node, util.nspath_eval('atom:link', NAMESPACES), href=linkset[-1], type=linkset[2], title=linkset[1])
 
     etree.SubElement(node, util.nspath_eval('atom:link', NAMESPACES), href='%s?service=CSW&version=2.0.2&request=GetRepositoryItem&id=%s' % (url, util.getqattr(result, context.md_core_model['mappings']['pycsw:Identifier'])))
 
-    for qval in ['pycsw:PublicationDate', 'pycsw:AccessConstraints', 'pycsw:Source', 'pycsw:Abstract', 'pycsw:Title', 'pycsw:Modified']:
+    # atom:title
+    el = etree.SubElement(node, util.nspath_eval(XPATH_MAPPINGS['pycsw:Title'], NAMESPACES))
+    val = util.getqattr(result, context.md_core_model['mappings']['pycsw:Title'])
+    if val:
+        el.text =val
+
+    # atom:updated
+    el = etree.SubElement(node, util.nspath_eval(XPATH_MAPPINGS['pycsw:Modified'], NAMESPACES))
+    val = util.getqattr(result, context.md_core_model['mappings']['pycsw:Modified'])
+    if val:
+        el.text =val
+    else:
+        val = util.getqattr(result, context.md_core_model['mappings']['pycsw:InsertDate'])
+        el.text = val
+
+    for qval in ['pycsw:PublicationDate', 'pycsw:AccessConstraints', 'pycsw:Source', 'pycsw:Abstract']:
         val = util.getqattr(result, context.md_core_model['mappings'][qval])
         if val:
             etree.SubElement(node, util.nspath_eval(XPATH_MAPPINGS[qval], NAMESPACES)).text = val
@@ -104,19 +121,16 @@ def write_record(result, esn, context, url=None):
 
 def write_extent(bbox, nsmap):
     ''' Generate BBOX extent '''
-    
+
     if bbox is not None:
         try:
-            bbox2 = util.wkt2geom(bbox, bounds=False)
+            bbox2 = util.wkt2geom(bbox)
         except:
             return None
-
         where = etree.Element(util.nspath_eval('georss:where', NAMESPACES))
-        polygon = etree.SubElement(where, util.nspath_eval('gml:Polygon', nsmap), srsName='urn:x-ogc:def:crs:EPSG:6.11:4326')
-        exterior = etree.SubElement(polygon, util.nspath_eval('gml:exterior', nsmap))
-        lring = etree.SubElement(exterior, util.nspath_eval('gml:LinearRing', nsmap))
-        poslist = etree.SubElement(lring, util.nspath_eval('gml:posList', nsmap)).text = \
-        ' '.join(['%s %s' % (str(i[1]), str(i[0])) for i in list(bbox2.exterior.coords)])
-    
+        envelope = etree.SubElement(where, util.nspath_eval('gml:Envelope', nsmap), srsName='http://www.opengis.net/def/crs/EPSG/0/4326')
+        etree.SubElement(envelope, util.nspath_eval('gml:lowerCorner', nsmap)).text = '%s %s' % (bbox2[1], bbox2[0])
+        etree.SubElement(envelope, util.nspath_eval('gml:upperCorner', nsmap)).text = '%s %s' % (bbox2[3], bbox2[2])
+
         return where
     return None
diff --git a/pycsw/plugins/outputschemas/dif.py b/pycsw/plugins/outputschemas/dif.py
index ad38aaa..d978ffb 100644
--- a/pycsw/plugins/outputschemas/dif.py
+++ b/pycsw/plugins/outputschemas/dif.py
@@ -1,9 +1,9 @@
-# -*- coding: iso-8859-15 -*-
+# -*- coding: utf-8 -*-
 # =================================================================
 #
 # Authors: Tom Kralidis <tomkralidis at gmail.com>
 #
-# Copyright (c) 2011 Tom Kralidis
+# Copyright (c) 2015 Tom Kralidis
 #
 # Permission is hereby granted, free of charge, to any person
 # obtaining a copy of this software and associated documentation
@@ -28,27 +28,27 @@
 #
 # =================================================================
 
-from lxml import etree
-from pycsw import util
+from pycsw.core import util
+from pycsw.core.etree import etree
 
 NAMESPACE = 'http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/'
 NAMESPACES = {'dif': NAMESPACE}
 
 XPATH_MAPPINGS = {
-    'pycsw:Title': 'dif:Entry_Title', 
-    'pycsw:Creator': 'dif:Data_Set_Citation/dif:Dataset_Creator', 
-    'pycsw:TopicCategory': 'dif:ISO_Topic_Category', 
+    'pycsw:Title': 'dif:Entry_Title',
+    'pycsw:Creator': 'dif:Data_Set_Citation/dif:Dataset_Creator',
+    'pycsw:TopicCategory': 'dif:ISO_Topic_Category',
     'pycsw:Keywords': 'dif:Keyword',
-    'pycsw:Abstract': 'dif:Summary', 
-    'pycsw:Publisher': 'dif:Data_Set_Citation/dif:Dataset_Publisher', 
+    'pycsw:Abstract': 'dif:Summary',
+    'pycsw:Publisher': 'dif:Data_Set_Citation/dif:Dataset_Publisher',
     'pycsw:OrganizationName': 'dif:Originating_Center',
-    'pycsw:CreationDate': 'dif:DIF_Creation_Date','pycsw:PublicationDate': 'dif:Data_Set_Citation/dif:Dataset_Release_Date', 
-    'pycsw:Format': 'dif:Data_Set_Citation/dif:Data_Presentation_Form', 
+    'pycsw:CreationDate': 'dif:DIF_Creation_Date','pycsw:PublicationDate': 'dif:Data_Set_Citation/dif:Dataset_Release_Date',
+    'pycsw:Format': 'dif:Data_Set_Citation/dif:Data_Presentation_Form',
     'pycsw:ResourceLanguage': 'dif:Data_Set_Language',
-    'pycsw:Relation': 'dif:Related_URL/dif:URL', 
+    'pycsw:Relation': 'dif:Related_URL/dif:URL',
     'pycsw:AccessConstraints': 'dif:Access_Constraints',
-    'pycsw:TempExtent_begin': 'dif:Temporal_Coverage/dif:Start_Date', 
-    'pycsw:TempExtent_end': 'dif:Temporal_Coverage/dif:Stop_Date', 
+    'pycsw:TempExtent_begin': 'dif:Temporal_Coverage/dif:Start_Date',
+    'pycsw:TempExtent_end': 'dif:Temporal_Coverage/dif:Stop_Date',
 }
 
 def write_record(result, esn, context, url=None):
@@ -107,7 +107,7 @@ def write_record(result, esn, context, url=None):
     temporal = etree.SubElement(node, util.nspath_eval('dif:Temporal_Coverage', NAMESPACES))
     val = util.getqattr(result, context.md_core_model['mappings']['pycsw:TempExtent_begin'])
     val2 = util.getqattr(result, context.md_core_model['mappings']['pycsw:TempExtent_end'])
-    etree.SubElement(temporal, util.nspath_eval('dif:Start_Date', NAMESPACES)).text = val 
+    etree.SubElement(temporal, util.nspath_eval('dif:Start_Date', NAMESPACES)).text = val
     etree.SubElement(temporal, util.nspath_eval('dif:End_Date', NAMESPACES)).text = val2
 
     # bbox extent
@@ -134,7 +134,7 @@ def write_record(result, esn, context, url=None):
         val = ''
     etree.SubElement(node, util.nspath_eval('dif:Summary', NAMESPACES)).text = val
 
-    # date 
+    # date
     val = util.getqattr(result, context.md_core_model['mappings']['pycsw:CreationDate'])
     etree.SubElement(node, util.nspath_eval('dif:DIF_Creation_Date', NAMESPACES)).text = val
 
@@ -147,7 +147,7 @@ def write_record(result, esn, context, url=None):
     if rlinks:
         for link in rlinks.split('^'):
             linkset = link.split(',')
-       
+
             url2 = etree.SubElement(node, util.nspath_eval('dif:Related_URL', NAMESPACES))
 
             urltype = etree.SubElement(url2, util.nspath_eval('dif:URL_Content_Type', NAMESPACES))
@@ -163,9 +163,9 @@ def write_record(result, esn, context, url=None):
 
 def write_extent(bbox, nsmap):
     ''' Generate BBOX extent '''
-    
+
     from shapely.wkt import loads
-    
+
     if bbox is not None:
         try:
             bbox2 = util.wkt2geom(bbox)
diff --git a/pycsw/plugins/outputschemas/fgdc.py b/pycsw/plugins/outputschemas/fgdc.py
index d16da44..bca4f63 100644
--- a/pycsw/plugins/outputschemas/fgdc.py
+++ b/pycsw/plugins/outputschemas/fgdc.py
@@ -1,9 +1,9 @@
-# -*- coding: iso-8859-15 -*-
+# -*- coding: utf-8 -*-
 # =================================================================
 #
 # Authors: Tom Kralidis <tomkralidis at gmail.com>
 #
-# Copyright (c) 2011 Tom Kralidis
+# Copyright (c) 2015 Tom Kralidis
 #
 # Permission is hereby granted, free of charge, to any person
 # obtaining a copy of this software and associated documentation
@@ -28,8 +28,8 @@
 #
 # =================================================================
 
-from lxml import etree
-from pycsw import util
+from pycsw.core import util
+from pycsw.core.etree import etree
 
 #NAMESPACE = 'http://www.fgdc.gov/metadata/csdgm'
 NAMESPACE = 'http://www.opengis.net/cat/csw/csdgm'
@@ -163,7 +163,7 @@ def write_record(recobj, esn, context, url=None):
 
 def write_extent(bbox):
     ''' Generate BBOX extent '''
-    
+
     if bbox is not None:
         try:
             bbox2 = util.wkt2geom(bbox)
diff --git a/pycsw/plugins/outputschemas/gm03.py b/pycsw/plugins/outputschemas/gm03.py
new file mode 100644
index 0000000..cffb2b8
--- /dev/null
+++ b/pycsw/plugins/outputschemas/gm03.py
@@ -0,0 +1,240 @@
+# -*- coding: utf-8 -*-
+# =================================================================
+#
+# Authors: Tom Kralidis <tomkralidis at gmail.com>
+#
+# Copyright (c) 2015 Tom Kralidis
+#
+# Permission is hereby granted, free of charge, to any person
+# obtaining a copy of this software and associated documentation
+# files (the "Software"), to deal in the Software without
+# restriction, including without limitation the rights to use,
+# copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the
+# Software is furnished to do so, subject to the following
+# conditions:
+#
+# The above copyright notice and this permission notice shall be
+# included in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+# OTHER DEALINGS IN THE SOFTWARE.
+#
+# =================================================================
+
+from pycsw.core import util
+from pycsw.core.etree import etree
+
+NAMESPACE = 'http://www.interlis.ch/INTERLIS2.3'
+NAMESPACES = {'gm03': NAMESPACE}
+
+XPATH_MAPPINGS = {}
+
+def write_record(result, esn, context, url=None):
+    ''' Return csw:SearchResults child as lxml.etree.Element '''
+
+    typename = util.getqattr(result, context.md_core_model['mappings']['pycsw:Typename'])
+
+    if typename == 'gm03:TRANSFER':
+        # dump record as is and exit
+        # TODO: provide brief and summary elementsetname's
+        return etree.fromstring(util.getqattr(result, context.md_core_model['mappings']['pycsw:XML']), context.parser)
+
+    node = etree.Element(util.nspath_eval('gm03:TRANSFER', NAMESPACES), nsmap=NAMESPACES)
+
+    header = etree.SubElement(node, util.nspath_eval('gm03:HEADERSECTION', NAMESPACES))
+    header.attrib['version'] = '2.3'
+    header.attrib['sender'] = 'pycsw'
+
+    etree.SubElement(header, util.nspath_eval('gm03:MODELS', NAMESPACES))
+
+    data = etree.SubElement(node, util.nspath_eval('gm03:DATASECTION', NAMESPACES))
+
+    core = etree.SubElement(data, util.nspath_eval('gm03:GM03_2_1Core.Core', NAMESPACES))
+    core_meta = etree.SubElement(core, util.nspath_eval('gm03:GM03_2_1Core.Core.MD_Metadata', NAMESPACES))
+
+    val = util.getqattr(result, context.md_core_model['mappings']['pycsw:Identifier'])
+    etree.SubElement(core_meta, util.nspath_eval('gm03:fileIdentifier', NAMESPACES)).text = val
+
+    language = util.getqattr(result, context.md_core_model['mappings']['pycsw:Language'])
+    etree.SubElement(core_meta, util.nspath_eval('gm03:language', NAMESPACES)).text = language
+
+    val = util.getqattr(result, context.md_core_model['mappings']['pycsw:Modified'])
+    etree.SubElement(core_meta, util.nspath_eval('gm03:dateStamp', NAMESPACES)).text = val
+
+    hierarchy_level_val = util.getqattr(result, context.md_core_model['mappings']['pycsw:Type'])
+
+    # metadata standard name
+    standard = etree.SubElement(core_meta, util.nspath_eval('gm03:metadataStandardName', NAMESPACES)).text = 'GM03'
+
+    # metadata standard version
+    standardver = etree.SubElement(core_meta, util.nspath_eval('gm03:metadataStandardVersion', NAMESPACES)).text = '2.3'
+
+    # hierarchy level
+    hierarchy_level = etree.SubElement(core_meta, util.nspath_eval('gm03:hierarchyLevel', NAMESPACES))
+    scope_code = etree.SubElement(hierarchy_level, util.nspath_eval('gm03:GM03_2_1Core.Core.MD_ScopeCode_', NAMESPACES))
+    etree.SubElement(scope_code, util.nspath_eval('gm03:value', NAMESPACES)).text = hierarchy_level_val
+
+    # parent identifier
+    val = util.getqattr(result, context.md_core_model['mappings']['pycsw:ParentIdentifier'])
+    parent_identifier = etree.SubElement(core_meta, util.nspath_eval('gm03:parentIdentifier', NAMESPACES))
+    scope_code = etree.SubElement(parent_identifier, util.nspath_eval('gm03:GM03_2_1Core.Core.MD_ScopeCode_', NAMESPACES))
+    etree.SubElement(scope_code, util.nspath_eval('gm03:value', NAMESPACES)).text = val
+
+    # title
+    val = util.getqattr(result, context.md_core_model['mappings']['pycsw:Title'])
+    citation = etree.SubElement(core, util.nspath_eval('gm03:GM03_2_1Core.Core.CI_Citation', NAMESPACES))
+    title = etree.SubElement(citation, util.nspath_eval('gm03:title', NAMESPACES))
+    title.append(_get_pt_freetext(val, language))
+
+    # abstract
+    val = util.getqattr(result, context.md_core_model['mappings']['pycsw:Abstract'])
+    data_ident = etree.SubElement(core, util.nspath_eval('gm03:GM03_2_1Core.Core.MD_DataIdentification', NAMESPACES))
+    abstract = etree.SubElement(data_ident, util.nspath_eval('gm03:abstract', NAMESPACES))
+    abstract.append(_get_pt_freetext(val, language))
+
+    # resource language
+    val = util.getqattr(result, context.md_core_model['mappings']['pycsw:ResourceLanguage'])
+    if val:
+        topicategory = etree.SubElement(data_ident, util.nspath_eval('gm03:language', NAMESPACES))
+        cat_code = etree.SubElement(topicategory, util.nspath_eval('gm03:CodeISO.LanguageCodeISO_', NAMESPACES))
+        etree.SubElement(cat_code, util.nspath_eval('gm03:value', NAMESPACES)).text = val
+
+    # topic category
+    val = util.getqattr(result, context.md_core_model['mappings']['pycsw:TopicCategory'])
+    if val:
+        topicategory = etree.SubElement(data_ident, util.nspath_eval('gm03:topicCategory', NAMESPACES))
+        cat_code = etree.SubElement(topicategory, util.nspath_eval('gm03:GM03_2_1Core.Core.MD_TopicCategoryCode_', NAMESPACES))
+        etree.SubElement(cat_code, util.nspath_eval('gm03:value', NAMESPACES)).text = val
+
+    # keywords
+    keywords_val = util.getqattr(result, context.md_core_model['mappings']['pycsw:Keywords'])
+
+    if keywords_val:
+        md_keywords = etree.SubElement(core, util.nspath_eval('gm03:GM03_2_1Core.Core.MD_Keywords', NAMESPACES))
+
+        val = util.getqattr(result, context.md_core_model['mappings']['pycsw:KeywordType'])
+        if val:
+            etree.SubElement(md_keywords, util.nspath_eval('gm03:type', NAMESPACES)).text = val
+
+        keyword = etree.SubElement(md_keywords, util.nspath_eval('gm03:keyword', NAMESPACES))
+        for kw in keywords_val.split(','):
+            keyword.append(_get_pt_freetext(kw, language))
+
+    # format
+    val = util.getqattr(result, context.md_core_model['mappings']['pycsw:Format'])
+    if val:
+        md_format = etree.SubElement(core, util.nspath_eval('gm03:GM03_2_1Core.Core.MD_Format', NAMESPACES))
+        etree.SubElement(md_format, util.nspath_eval('gm03:name', NAMESPACES)).text = val
+
+    # creation date
+    val = util.getqattr(result, context.md_core_model['mappings']['pycsw:CreationDate'])
+    if val:
+        ci_date = etree.SubElement(core, util.nspath_eval('gm03:GM03_2_1Core.Core.CI_Date', NAMESPACES))
+        etree.SubElement(ci_date, util.nspath_eval('gm03:date', NAMESPACES)).text = val
+        etree.SubElement(ci_date, util.nspath_eval('gm03:dateType', NAMESPACES)).text = 'creation'
+
+    # revision date
+    val = util.getqattr(result, context.md_core_model['mappings']['pycsw:RevisionDate'])
+    if val:
+        ci_date = etree.SubElement(core, util.nspath_eval('gm03:GM03_2_1Core.Core.CI_Date', NAMESPACES))
+        etree.SubElement(ci_date, util.nspath_eval('gm03:date', NAMESPACES)).text = val
+        etree.SubElement(ci_date, util.nspath_eval('gm03:dateType', NAMESPACES)).text = 'revision'
+
+    # publication date
+    val = util.getqattr(result, context.md_core_model['mappings']['pycsw:PublicationDate'])
+    if val:
+        ci_date = etree.SubElement(core, util.nspath_eval('gm03:GM03_2_1Core.Core.CI_Date', NAMESPACES))
+        etree.SubElement(ci_date, util.nspath_eval('gm03:date', NAMESPACES)).text = val
+        etree.SubElement(ci_date, util.nspath_eval('gm03:dateType', NAMESPACES)).text = 'publication'
+
+    # bbox extent
+    val = util.getqattr(result, context.md_core_model['mappings']['pycsw:BoundingBox'])
+    bboxel = write_extent(val, context.namespaces)
+    if bboxel is not None:
+        core.append(bboxel)
+
+    # geographic description
+    val = util.getqattr(result, context.md_core_model['mappings']['pycsw:GeographicDescriptionCode'])
+    if val:
+        geo_desc = etree.SubElement(core, util.nspath_eval('gm03:GM03_2_1Core.Core.EX_GeographicDescription', NAMESPACES))
+        etree.SubElement(geo_desc, util.nspath_eval('gm03:geographicIdentifier', NAMESPACES)).text = val
+
+    # crs
+    val = util.getqattr(result, context.md_core_model['mappings']['pycsw:CRS'])
+    if val:
+        rs_identifier = etree.SubElement(core, util.nspath_eval('gm03:GM03_2_1Core.Core.RS_Identifier', NAMESPACES))
+        rs_code = etree.SubElement(rs_identifier, util.nspath_eval('gm03:code', NAMESPACES))
+        rs_code.append(_get_pt_freetext(val, language))
+
+    # temporal extent
+    time_begin = util.getqattr(result, context.md_core_model['mappings']['pycsw:TempExtent_begin'])
+    time_end = util.getqattr(result, context.md_core_model['mappings']['pycsw:TempExtent_end'])
+    if time_begin:
+        temp_ext = etree.SubElement(core, util.nspath_eval('gm03:GM03_2_1Core.Core.EX_TemporalExtent', NAMESPACES))
+        extent = etree.SubElement(temp_ext, util.nspath_eval('gm03:extent', NAMESPACES))
+        tm_primitive = etree.SubElement(extent, util.nspath_eval('gm03:GM03_2_1Core.Core.TM_Primitive', NAMESPACES))
+        etree.SubElement(tm_primitive, util.nspath_eval('gm03:begin', NAMESPACES)).text = time_begin
+        if time_end:
+            etree.SubElement(tm_primitive, util.nspath_eval('gm03:end', NAMESPACES)).text = time_end
+
+    # links
+    rlinks = util.getqattr(result, context.md_core_model['mappings']['pycsw:Links'])
+    if rlinks:
+        for link in rlinks.split('^'):
+            name, description, protocol, url = link.split(',')
+            online_resource = etree.SubElement(core, util.nspath_eval('gm03:GM03_2_1Core.Core.OnlineResource', NAMESPACES))
+            if protocol:
+                etree.SubElement(online_resource, util.nspath_eval('gm03:protocol', NAMESPACES)).text = protocol
+            if description:
+                desc = etree.SubElement(online_resource, util.nspath_eval('gm03:description', NAMESPACES))
+                desc.append(_get_pt_freetext(description, language))
+            if name:
+                name_el = etree.SubElement(online_resource, util.nspath_eval('gm03:name', NAMESPACES))
+                name_el.append(_get_pt_freetext(name, language))
+            linkage = etree.SubElement(online_resource, util.nspath_eval('gm03:linkage', NAMESPACES))
+            linkage.append(_get_pt_freeurl(url, language))
+
+    return node
+
+def _get_pt_freetext(val, language):
+    freetext = etree.Element(util.nspath_eval('gm03:GM03_2_1Core.Core.PT_FreeText', NAMESPACES))
+    textgroup = etree.SubElement(freetext, util.nspath_eval('gm03:textGroup', NAMESPACES))
+    ptgroup = etree.SubElement(textgroup, util.nspath_eval('gm03:GM03_2_1Core.Core.PT_Group', NAMESPACES))
+    if language:
+        etree.SubElement(ptgroup, util.nspath_eval('gm03:language', NAMESPACES)).text = language
+    etree.SubElement(ptgroup, util.nspath_eval('gm03:plainText', NAMESPACES)).text = val
+
+    return freetext
+
+def _get_pt_freeurl(val, language):
+    freeurl = etree.Element(util.nspath_eval('gm03:GM03_2_1Core.Core.PT_FreeURL', NAMESPACES))
+    urlgroup = etree.SubElement(freeurl, util.nspath_eval('gm03:URLGroup', NAMESPACES))
+    ptgroup = etree.SubElement(urlgroup, util.nspath_eval('gm03:GM03_2_1Core.Core.PT_URLGroup', NAMESPACES))
+    if language:
+        etree.SubElement(ptgroup, util.nspath_eval('gm03:language', NAMESPACES)).text = language
+    etree.SubElement(ptgroup, util.nspath_eval('gm03:plainURL', NAMESPACES)).text = val
+
+    return freeurl
+
+def write_extent(bbox, nsmap):
+    ''' Generate BBOX extent '''
+    
+    if bbox is not None:
+        try:
+            bbox2 = util.wkt2geom(bbox)
+        except:
+            return None
+        bounding_box = etree.Element(util.nspath_eval('gm03:GM03_2_1Core.Core.EX_GeographicBoundingBox', NAMESPACES))
+        etree.SubElement(bounding_box, util.nspath_eval('gm03:northBoundLatitude', nsmap)).text = str(bbox2[3])
+        etree.SubElement(bounding_box, util.nspath_eval('gm03:southBoundLatitude', nsmap)).text = str(bbox2[1])
+        etree.SubElement(bounding_box, util.nspath_eval('gm03:eastBoundLongitude', nsmap)).text = str(bbox2[0])
+        etree.SubElement(bounding_box, util.nspath_eval('gm03:westBoundLongitude', nsmap)).text = str(bbox2[2])
+        return bounding_box
+    return None
diff --git a/pycsw/plugins/profiles/__init__.py b/pycsw/plugins/profiles/__init__.py
index f98f82b..08a4c3d 100644
--- a/pycsw/plugins/profiles/__init__.py
+++ b/pycsw/plugins/profiles/__init__.py
@@ -1,9 +1,9 @@
-# -*- coding: ISO-8859-15 -*-
+# -*- coding: utf-8 -*-
 # =================================================================
 #
 # Authors: Tom Kralidis <tomkralidis at gmail.com>
 #
-# Copyright (c) 2011 Tom Kralidis
+# Copyright (c) 2015 Tom Kralidis
 #
 # Permission is hereby granted, free of charge, to any person
 # obtaining a copy of this software and associated documentation
diff --git a/pycsw/plugins/profiles/apiso/__init__.py b/pycsw/plugins/profiles/apiso/__init__.py
index f98f82b..08a4c3d 100644
--- a/pycsw/plugins/profiles/apiso/__init__.py
+++ b/pycsw/plugins/profiles/apiso/__init__.py
@@ -1,9 +1,9 @@
-# -*- coding: ISO-8859-15 -*-
+# -*- coding: utf-8 -*-
 # =================================================================
 #
 # Authors: Tom Kralidis <tomkralidis at gmail.com>
 #
-# Copyright (c) 2011 Tom Kralidis
+# Copyright (c) 2015 Tom Kralidis
 #
 # Permission is hereby granted, free of charge, to any person
 # obtaining a copy of this software and associated documentation
diff --git a/pycsw/plugins/profiles/apiso/apiso.py b/pycsw/plugins/profiles/apiso/apiso.py
index e0307ea..4e34e93 100644
--- a/pycsw/plugins/profiles/apiso/apiso.py
+++ b/pycsw/plugins/profiles/apiso/apiso.py
@@ -1,11 +1,11 @@
-# -*- coding: iso-8859-15 -*-
+# -*- coding: utf-8 -*-
 # =================================================================
 #
 # Authors: Tom Kralidis <tomkralidis at gmail.com>
-#                Angelos Tzotsos <tzotsos at gmail.com>
+#          Angelos Tzotsos <tzotsos at gmail.com>
 #
-# Copyright (c) 2011 Tom Kralidis
-# Copyright (c) 2011 Angelos Tzotsos
+# Copyright (c) 2015 Tom Kralidis
+# Copyright (c) 2015 Angelos Tzotsos
 #
 # Permission is hereby granted, free of charge, to any person
 # obtaining a copy of this software and associated documentation
@@ -31,8 +31,8 @@
 # =================================================================
 
 import os
-from lxml import etree
-from pycsw import config, util
+from pycsw.core import config, util
+from pycsw.core.etree import etree
 from pycsw.plugins.profiles import profile
 
 CODELIST = 'http://www.isotc211.org/2005/resources/Codelist/gmxCodelists.xml'
@@ -351,9 +351,10 @@ class APISO(profile.Profile):
         schemaLanguage='XMLSCHEMA', targetNamespace=self.namespace,
         parentSchema='gmd.xsd')
 
-        schema_file = os.path.join(self.context.pycsw_home,
-                                   'plugins', 'profiles', 'apiso', 'schemas', 'ogc', 'iso',
-                                   '19139', '20060504', 'gmd', 'identification.xsd')
+        schema_file = os.path.join(self.context.pycsw_home, 'plugins',
+                                   'profiles', 'apiso', 'schemas', 'ogc',
+                                   'iso', '19139', '20060504', 'gmd',
+                                   'identification.xsd')
 
         schema = etree.parse(schema_file, self.context.parser).getroot()
 
@@ -365,8 +366,9 @@ class APISO(profile.Profile):
         parentSchema='gmd.xsd')
 
         schema_file = os.path.join(self.context.pycsw_home, 'plugins',
-                                   'profiles', 'apiso', 'schemas', 'ogc', 'iso', '19139',
-                                   '20060504', 'srv', 'serviceMetadata.xsd')
+                                   'profiles', 'apiso', 'schemas', 'ogc',
+                                   'iso', '19139', '20060504', 'srv',
+                                   'serviceMetadata.xsd')
 
         schema = etree.parse(schema_file, self.context.parser).getroot()
 
@@ -384,7 +386,7 @@ class APISO(profile.Profile):
         is_iso_anyway = False
 
         xml_blob = util.getqattr(result, self.context.md_core_model['mappings']['pycsw:XML'])
-        if caps is None and xml_blob is not None and xml_blob.startswith('<gmd:MD_Metadata'):
+        if caps is None and xml_blob is not None and xml_blob.startswith(b'<gmd:MD_Metadata'):
             is_iso_anyway = True
 
         if (esn == 'full' and (typename == 'gmd:MD_Metadata' or is_iso_anyway)):
@@ -414,7 +416,7 @@ class APISO(profile.Profile):
         # hierarchyLevel
         mtype = util.getqattr(result, queryables['apiso:Type']['dbcol']) or None
 
-        if mtype is not None: 
+        if mtype is not None:
             if mtype == 'http://purl.org/dc/dcmitype/Dataset':
                 mtype = 'dataset'
             hierarchy = etree.SubElement(node, util.nspath_eval('gmd:hierarchyLevel', self.namespaces))
@@ -424,7 +426,7 @@ class APISO(profile.Profile):
             # contact
             contact = etree.SubElement(node, util.nspath_eval('gmd:contact', self.namespaces))
             if caps is not None:
-                CI_resp = etree.SubElement(contact, util.nspath_eval('gmd:CI_ResponsibleParty', self.namespaces)) 
+                CI_resp = etree.SubElement(contact, util.nspath_eval('gmd:CI_ResponsibleParty', self.namespaces))
                 if hasattr(caps.provider.contact, 'name'):
                     ind_name = etree.SubElement(CI_resp, util.nspath_eval('gmd:individualName', self.namespaces))
                     etree.SubElement(ind_name, util.nspath_eval('gco:CharacterString', self.namespaces)).text = caps.provider.contact.name
@@ -438,35 +440,35 @@ class APISO(profile.Profile):
                 if hasattr(caps.provider.contact, 'position'):
                     pos_name = etree.SubElement(CI_resp, util.nspath_eval('gmd:positionName', self.namespaces))
                     etree.SubElement(pos_name, util.nspath_eval('gco:CharacterString', self.namespaces)).text = caps.provider.contact.position
-                contact_info = etree.SubElement(CI_resp, util.nspath_eval('gmd:contactInfo', self.namespaces)) 
-                ci_contact = etree.SubElement(contact_info, util.nspath_eval('gmd:CI_Contact', self.namespaces)) 
+                contact_info = etree.SubElement(CI_resp, util.nspath_eval('gmd:contactInfo', self.namespaces))
+                ci_contact = etree.SubElement(contact_info, util.nspath_eval('gmd:CI_Contact', self.namespaces))
                 if hasattr(caps.provider.contact, 'phone'):
-                    phone = etree.SubElement(ci_contact, util.nspath_eval('gmd:phone', self.namespaces)) 
-                    ci_phone = etree.SubElement(phone, util.nspath_eval('gmd:CI_Telephone', self.namespaces)) 
-                    voice = etree.SubElement(ci_phone, util.nspath_eval('gmd:voice', self.namespaces)) 
+                    phone = etree.SubElement(ci_contact, util.nspath_eval('gmd:phone', self.namespaces))
+                    ci_phone = etree.SubElement(phone, util.nspath_eval('gmd:CI_Telephone', self.namespaces))
+                    voice = etree.SubElement(ci_phone, util.nspath_eval('gmd:voice', self.namespaces))
                     etree.SubElement(voice, util.nspath_eval('gco:CharacterString', self.namespaces)).text = caps.provider.contact.phone
                     if hasattr(caps.provider.contact, 'fax'):
-                        fax = etree.SubElement(ci_phone, util.nspath_eval('gmd:facsimile', self.namespaces)) 
+                        fax = etree.SubElement(ci_phone, util.nspath_eval('gmd:facsimile', self.namespaces))
                         etree.SubElement(fax, util.nspath_eval('gco:CharacterString', self.namespaces)).text = caps.provider.contact.fax
-                address = etree.SubElement(ci_contact, util.nspath_eval('gmd:address', self.namespaces)) 
-                ci_address = etree.SubElement(address, util.nspath_eval('gmd:CI_Address', self.namespaces)) 
+                address = etree.SubElement(ci_contact, util.nspath_eval('gmd:address', self.namespaces))
+                ci_address = etree.SubElement(address, util.nspath_eval('gmd:CI_Address', self.namespaces))
                 if hasattr(caps.provider.contact, 'address'):
-                    delivery_point = etree.SubElement(ci_address, util.nspath_eval('gmd:deliveryPoint', self.namespaces)) 
+                    delivery_point = etree.SubElement(ci_address, util.nspath_eval('gmd:deliveryPoint', self.namespaces))
                     etree.SubElement(delivery_point, util.nspath_eval('gco:CharacterString', self.namespaces)).text = caps.provider.contact.address
                 if hasattr(caps.provider.contact, 'city'):
-                    city = etree.SubElement(ci_address, util.nspath_eval('gmd:city', self.namespaces)) 
+                    city = etree.SubElement(ci_address, util.nspath_eval('gmd:city', self.namespaces))
                     etree.SubElement(city, util.nspath_eval('gco:CharacterString', self.namespaces)).text = caps.provider.contact.city
                 if hasattr(caps.provider.contact, 'region'):
-                    admin_area = etree.SubElement(ci_address, util.nspath_eval('gmd:administrativeArea', self.namespaces)) 
+                    admin_area = etree.SubElement(ci_address, util.nspath_eval('gmd:administrativeArea', self.namespaces))
                     etree.SubElement(admin_area, util.nspath_eval('gco:CharacterString', self.namespaces)).text = caps.provider.contact.region
                 if hasattr(caps.provider.contact, 'postcode'):
-                    postal_code = etree.SubElement(ci_address, util.nspath_eval('gmd:postalCode', self.namespaces)) 
+                    postal_code = etree.SubElement(ci_address, util.nspath_eval('gmd:postalCode', self.namespaces))
                     etree.SubElement(postal_code, util.nspath_eval('gco:CharacterString', self.namespaces)).text = caps.provider.contact.postcode
                 if hasattr(caps.provider.contact, 'country'):
-                    country = etree.SubElement(ci_address, util.nspath_eval('gmd:country', self.namespaces)) 
+                    country = etree.SubElement(ci_address, util.nspath_eval('gmd:country', self.namespaces))
                     etree.SubElement(country, util.nspath_eval('gco:CharacterString', self.namespaces)).text = caps.provider.contact.country
                 if hasattr(caps.provider.contact, 'email'):
-                    email = etree.SubElement(ci_address, util.nspath_eval('gmd:electronicMailAddress', self.namespaces)) 
+                    email = etree.SubElement(ci_address, util.nspath_eval('gmd:electronicMailAddress', self.namespaces))
                     etree.SubElement(email, util.nspath_eval('gco:CharacterString', self.namespaces)).text = caps.provider.contact.email
 
                 contact_url = None
@@ -476,12 +478,12 @@ class APISO(profile.Profile):
                     contact_url = caps.provider.contact.url
 
                 if contact_url is not None:
-                    online_resource = etree.SubElement(ci_contact, util.nspath_eval('gmd:onlineResource', self.namespaces)) 
-                    gmd_linkage = etree.SubElement(online_resource, util.nspath_eval('gmd:linkage', self.namespaces)) 
+                    online_resource = etree.SubElement(ci_contact, util.nspath_eval('gmd:onlineResource', self.namespaces))
+                    gmd_linkage = etree.SubElement(online_resource, util.nspath_eval('gmd:linkage', self.namespaces))
                     etree.SubElement(gmd_linkage, util.nspath_eval('gmd:URL', self.namespaces)).text = contact_url
 
                 if hasattr(caps.provider.contact, 'role'):
-                    role = etree.SubElement(CI_resp, util.nspath_eval('gmd:role', self.namespaces)) 
+                    role = etree.SubElement(CI_resp, util.nspath_eval('gmd:role', self.namespaces))
                     role_val = caps.provider.contact.role
                     if role_val is None:
                         role_val = 'pointOfContact'
@@ -525,7 +527,7 @@ class APISO(profile.Profile):
            restagname = 'srv:SV_ServiceIdentification'
         else:
            restagname = 'gmd:MD_DataIdentification'
-          
+
         resident = etree.SubElement(identification, util.nspath_eval(restagname, self.namespaces), id=idval)
         tmp2 = etree.SubElement(resident, util.nspath_eval('gmd:citation', self.namespaces))
         tmp3 = etree.SubElement(tmp2, util.nspath_eval('gmd:CI_Citation', self.namespaces))
@@ -602,7 +604,7 @@ class APISO(profile.Profile):
             if kw is not None:
                 srv_keywords = etree.SubElement(resident, util.nspath_eval('srv:keywords', self.namespaces))
                 srv_keywords.append(write_keywords(kw, self.namespaces))
-                 
+
             if bboxel is not None:
                 bboxel.tag = util.nspath_eval('srv:extent', self.namespaces)
                 resident.append(bboxel)
@@ -636,10 +638,10 @@ class APISO(profile.Profile):
                         etree.SubElement(tmp2, util.nspath_eval('gco:CharacterString', self.namespaces)).text = i
 
                         tmp3 = etree.SubElement(tmp, util.nspath_eval('srv:DCP', self.namespaces))
-                        etree.SubElement(tmp3, util.nspath_eval('srv:DCPList', self.namespaces), codeList='%s#DCPList' % CODELIST, codeListValue='HTTPGet').text = 'HTTPGet' 
+                        etree.SubElement(tmp3, util.nspath_eval('srv:DCPList', self.namespaces), codeList='%s#DCPList' % CODELIST, codeListValue='HTTPGet').text = 'HTTPGet'
 
                         tmp4 = etree.SubElement(tmp, util.nspath_eval('srv:DCP', self.namespaces))
-                        etree.SubElement(tmp4, util.nspath_eval('srv:DCPList', self.namespaces), codeList='%s#DCPList' % CODELIST, codeListValue='HTTPPost').text = 'HTTPPost' 
+                        etree.SubElement(tmp4, util.nspath_eval('srv:DCPList', self.namespaces), codeList='%s#DCPList' % CODELIST, codeListValue='HTTPPost').text = 'HTTPPost'
 
                         connectpoint = etree.SubElement(tmp, util.nspath_eval('srv:connectPoint', self.namespaces))
                         onlineres = etree.SubElement(connectpoint, util.nspath_eval('gmd:CI_OnlineResource', self.namespaces))
@@ -731,7 +733,7 @@ def _get_resource_opname(operations):
     return None
 
 def _write_codelist_element(codelist_element, codelist_value, nsmap):
-    namespace, codelist = codelist_element.split(':')    
+    namespace, codelist = codelist_element.split(':')
 
     element = etree.Element(util.nspath_eval(codelist_element, nsmap),
     codeSpace=CODESPACE, codeList='%s#%s' % (CODELIST, codelist),
diff --git a/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gco/basicTypes.xsd b/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gco/basicTypes.xsd
index 803f899..fb1b776 100644
--- a/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gco/basicTypes.xsd
+++ b/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gco/basicTypes.xsd
@@ -6,7 +6,7 @@
 	</xs:annotation>
 	<!-- ================================== Imports ================================== -->
 	<xs:import namespace="http://www.opengis.net/gml" schemaLocation="../gml/gml.xsd"/>
-	<xs:import namespace="http://www.w3.org/1999/xlink" schemaLocation="../../../../../../../../../../pycsw/schemas/w3c/1999/xlink.xsd"/>
+	<xs:import namespace="http://www.w3.org/1999/xlink" schemaLocation="../../../../../../../../../core/schemas/w3c/1999/xlink.xsd"/>
 	<xs:include schemaLocation="../gco/gcoBase.xsd"/>
 	<!-- ########################################################################### -->
 	<!-- ########################################################################### -->
diff --git a/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gco/gcoBase.xsd b/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gco/gcoBase.xsd
index 4f6f796..9a0d5f6 100644
--- a/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gco/gcoBase.xsd
+++ b/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gco/gcoBase.xsd
@@ -7,7 +7,7 @@
 		2. Some XML types representing that do not follow the general encoding rules.</xs:documentation>
 	</xs:annotation>
 	<!-- ================================== Imports ================================== -->
-	<xs:import namespace="http://www.w3.org/1999/xlink" schemaLocation="../../../../../../../../../../pycsw/schemas/w3c/1999/xlink.xsd"/>
+	<xs:import namespace="http://www.w3.org/1999/xlink" schemaLocation="../../../../../../../../../core/schemas/w3c/1999/xlink.xsd"/>
 	<xs:import namespace="http://www.opengis.net/gml" schemaLocation="../gml/gml.xsd"/>
 	<!-- ########################################################################### -->
 	<!-- ########################################################################### -->
diff --git a/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gml/gmlBase.xsd b/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gml/gmlBase.xsd
index ddb0b1c..c502bb9 100644
--- a/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gml/gmlBase.xsd
+++ b/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gml/gmlBase.xsd
@@ -22,7 +22,7 @@ The gmlBase schema components establish the GML model and syntax, in particular
 -	components for constructing definitions and dictionaries.</documentation>
 	</annotation>
 	<include schemaLocation="basicTypes.xsd"/>
-	<import namespace="http://www.w3.org/1999/xlink" schemaLocation="../../../../../../../../../../pycsw/schemas/w3c/1999/xlink.xsd"/>
+	<import namespace="http://www.w3.org/1999/xlink" schemaLocation="../../../../../../../../../core/schemas/w3c/1999/xlink.xsd"/>
 	<element name="AbstractObject" abstract="true">
 		<annotation>
 			<documentation>This element has no type defined, and is therefore implicitly (according to the rules of W3C XML Schema) an XML Schema anyType. It is used as the head of an XML Schema substitution group which unifies complex content and certain simple content elements used for datatypes in GML, including the gml:AbstractGML substitution group.</documentation>
diff --git a/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gmx/extendedTypes.xsd b/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gmx/extendedTypes.xsd
index 19553f2..26526c0 100644
--- a/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gmx/extendedTypes.xsd
+++ b/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gmx/extendedTypes.xsd
@@ -6,7 +6,7 @@
 	</xs:annotation>
 	<!-- ================================== Imports ================================== -->
 	<xs:import namespace="http://www.isotc211.org/2005/gco" schemaLocation="../gco/gco.xsd"/>
-	<xs:import namespace="http://www.w3.org/1999/xlink" schemaLocation="../../../../../../../../../../pycsw/schemas/w3c/1999/xlink.xsd"/>
+	<xs:import namespace="http://www.w3.org/1999/xlink" schemaLocation="../../../../../../../../../core/schemas/w3c/1999/xlink.xsd"/>
 	<!-- ########################################################################### -->
 	<!-- ########################################################################### -->
 	<!-- ================================== Classes ================================= -->
diff --git a/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/resources/Codelist/ML_gmxCodelists.xml b/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/resources/Codelist/ML_gmxCodelists.xml
index 3400509..6e62c5f 100644
--- a/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/resources/Codelist/ML_gmxCodelists.xml
+++ b/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/resources/Codelist/ML_gmxCodelists.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<CT_CodelistCatalogue xmlns="http://www.isotc211.org/2005/gmx" xmlns:gco="http://www.isotc211.org/2005/gco" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.isotc211.org/2005/gmx ../../gmx/gmx.xsd http://www.isotc211.org/2005/gmd ../../gmd/gmd.xsd http://www.isotc211.org/2005/gco ../../gco/gco.xsd http://www.w3.org/1999/xlink . [...]
+<CT_CodelistCatalogue xmlns="http://www.isotc211.org/2005/gmx" xmlns:gco="http://www.isotc211.org/2005/gco" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.isotc211.org/2005/gmx ../../gmx/gmx.xsd http://www.isotc211.org/2005/gmd ../../gmd/gmd.xsd http://www.isotc211.org/2005/gco ../../gco/gco.xsd http://www.w3.org/1999/xlink h [...]
 	<!--=====Catalogue description=====-->
 	<name>
 		<gco:CharacterString>ML_gmxCodelists</gco:CharacterString>
diff --git a/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/resources/Codelist/gmxCodelists.xml b/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/resources/Codelist/gmxCodelists.xml
index 9da91d5..6f485f2 100644
--- a/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/resources/Codelist/gmxCodelists.xml
+++ b/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/resources/Codelist/gmxCodelists.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<CT_CodelistCatalogue xmlns="http://www.isotc211.org/2005/gmx" xmlns:gco="http://www.isotc211.org/2005/gco" xmlns:gml="http://www.opengis.net/gml" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.isotc211.org/2005/gmx ../../gmx/gmx.xsd http://www.isotc211.org/2005/gco ../../gco/gco.xsd http://www.opengis.net/gml ../../gml/gml.xsd http://www.w3.org/1999/xlink ../../../../../../../../pycsw/schemas/w3c/xlink/xlink.xsd">
+<CT_CodelistCatalogue xmlns="http://www.isotc211.org/2005/gmx" xmlns:gco="http://www.isotc211.org/2005/gco" xmlns:gml="http://www.opengis.net/gml" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.isotc211.org/2005/gmx ../../gmx/gmx.xsd http://www.isotc211.org/2005/gco ../../gco/gco.xsd http://www.opengis.net/gml ../../gml/gml.xsd http://www.w3.org/1999/xlink http://www.w3.org/1999/xlink.xsd">
 	<!--=====Catalogue description=====-->
 	<name>
 		<gco:CharacterString>gmxCodelists</gco:CharacterString>
diff --git a/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/resources/crs/ML_gmxCrs.xml b/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/resources/crs/ML_gmxCrs.xml
index ce3020a..0b8548b 100644
--- a/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/resources/crs/ML_gmxCrs.xml
+++ b/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/resources/crs/ML_gmxCrs.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<CT_CrsCatalogue xmlns="http://www.isotc211.org/2005/gmx" xmlns:gco="http://www.isotc211.org/2005/gco" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.isotc211.org/2005/gmx ../../gmx/gmx.xsd http://www.isotc211.org/2005/gmd ../../gmd/gmd.xsd http://www.isotc211.org/2005/gco ../../gco/gco.xsd http://www.w3.org/1999/xlink ../../ [...]
+<CT_CrsCatalogue xmlns="http://www.isotc211.org/2005/gmx" xmlns:gco="http://www.isotc211.org/2005/gco" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.isotc211.org/2005/gmx ../../gmx/gmx.xsd http://www.isotc211.org/2005/gmd ../../gmd/gmd.xsd http://www.isotc211.org/2005/gco ../../gco/gco.xsd http://www.w3.org/1999/xlink http:/ [...]
 	<!--=====Catalogue description=====-->
 	<name><gco:CharacterString>ML_gmxCrs</gco:CharacterString></name>
 	<scope xsi:type="gmd:PT_FreeText_PropertyType">
diff --git a/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/resources/crs/gmxCrs.xml b/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/resources/crs/gmxCrs.xml
index 456218e..9c54544 100644
--- a/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/resources/crs/gmxCrs.xml
+++ b/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/resources/crs/gmxCrs.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<CT_CrsCatalogue xmlns="http://www.isotc211.org/2005/gmx" xmlns:gco="http://www.isotc211.org/2005/gco" xmlns:gml="http://www.opengis.net/gml" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.isotc211.org/2005/gmx ../../gmx/gmx.xsd http://www.isotc211.org/2005/gmd ../../gmd/gmd.xsd http://www.isotc211.org/2005/gco ../../gco/gco.xsd http://www.w3.org/1999/xlink ../../ [...]
+<CT_CrsCatalogue xmlns="http://www.isotc211.org/2005/gmx" xmlns:gco="http://www.isotc211.org/2005/gco" xmlns:gml="http://www.opengis.net/gml" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.isotc211.org/2005/gmx ../../gmx/gmx.xsd http://www.isotc211.org/2005/gmd ../../gmd/gmd.xsd http://www.isotc211.org/2005/gco ../../gco/gco.xsd http://www.w3.org/1999/xlink http:/ [...]
 	<!--=====Catalogue description=====-->
 	<name><gco:CharacterString>gmxCrs</gco:CharacterString></name>
 	<scope><gco:CharacterString>CRS parameters dictionary</gco:CharacterString></scope>
diff --git a/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/resources/example/fr-fr.xml b/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/resources/example/fr-fr.xml
index fade933..5224f78 100644
--- a/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/resources/example/fr-fr.xml
+++ b/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/resources/example/fr-fr.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<PT_LocaleContainer xmlns="http://www.isotc211.org/2005/gmd" xmlns:gco="http://www.isotc211.org/2005/gco" xmlns:gml="http://www.opengis.net/gml" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.isotc211.org/2005/gmd ../../gmd/gmd.xsd http://www.isotc211.org/2005/gco ../../gco/gco.xsd http://www.opengis.net/gml ../../gml/gml.xsd http://www.w3.org/1999/xlink ../../../../../../../../pycsw/schemas/w3c/1999/xlink.xsd">
+<PT_LocaleContainer xmlns="http://www.isotc211.org/2005/gmd" xmlns:gco="http://www.isotc211.org/2005/gco" xmlns:gml="http://www.opengis.net/gml" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.isotc211.org/2005/gmd ../../gmd/gmd.xsd http://www.isotc211.org/2005/gco ../../gco/gco.xsd http://www.opengis.net/gml ../../gml/gml.xsd http://www.w3.org/1999/xlink http://www.w3.org/1999/xlink.xsd">
 	<!--==========================================-->
 	<!--===========Translation file Header ============-->
 	<!--===Text description===-->
diff --git a/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/resources/uom/ML_gmxUom.xml b/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/resources/uom/ML_gmxUom.xml
index 1df1e88..0ada1c7 100644
--- a/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/resources/uom/ML_gmxUom.xml
+++ b/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/resources/uom/ML_gmxUom.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<CT_UomCatalogue xmlns="http://www.isotc211.org/2005/gmx" xmlns:gco="http://www.isotc211.org/2005/gco" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.isotc211.org/2005/gmx ../../gmx/gmx.xsd http://www.isotc211.org/2005/gmd ../../gmd/gmd.xsd http://www.isotc211.org/2005/gco ../../gco/gco.xsd http://www.opengis.net/gml ../../gm [...]
+<CT_UomCatalogue xmlns="http://www.isotc211.org/2005/gmx" xmlns:gco="http://www.isotc211.org/2005/gco" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.isotc211.org/2005/gmx ../../gmx/gmx.xsd http://www.isotc211.org/2005/gmd ../../gmd/gmd.xsd http://www.isotc211.org/2005/gco ../../gco/gco.xsd http://www.opengis.net/gml ../../gm [...]
 	<!--=====Catalogue description=====-->
 	<name><gco:CharacterString>uom</gco:CharacterString></name>
 	<scope xsi:type="gmd:PT_FreeText_PropertyType">
diff --git a/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/resources/uom/gmxUom.xml b/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/resources/uom/gmxUom.xml
index daac9af..07e7030 100644
--- a/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/resources/uom/gmxUom.xml
+++ b/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/resources/uom/gmxUom.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<CT_UomCatalogue xmlns="http://www.isotc211.org/2005/gmx" xmlns:gco="http://www.isotc211.org/2005/gco" xmlns:gml="http://www.opengis.net/gml" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.isotc211.org/2005/gmx ../../gmx/gmx.xsd http://www.isotc211.org/2005/gco ../../gco/gco.xsd http://www.opengis.net/gml ../../gml/gml.xsd http://www.w3.org/1999/xlink ../../../../../../../../pycsw/schemas/w3c/1999/xlink.xsd">
+<CT_UomCatalogue xmlns="http://www.isotc211.org/2005/gmx" xmlns:gco="http://www.isotc211.org/2005/gco" xmlns:gml="http://www.opengis.net/gml" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.isotc211.org/2005/gmx ../../gmx/gmx.xsd http://www.isotc211.org/2005/gco ../../gco/gco.xsd http://www.opengis.net/gml ../../gml/gml.xsd http://www.w3.org/1999/xlink http://www.w3.org/1999/xlink.xsd">
 	<!--=====Catalogue description=====-->
 	<name><gco:CharacterString>gmxUom</gco:CharacterString></name>
 	<scope><gco:CharacterString>units of measure dictionary compliant with SI definitions</gco:CharacterString></scope>
diff --git a/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/ReadMe.txt b/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/ReadMe.txt
new file mode 100644
index 0000000..8a1ac7c
--- /dev/null
+++ b/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/ReadMe.txt
@@ -0,0 +1,26 @@
+ISO(c) ReadMe.txt
+------------------------------------------------------------------------------
+
+Geographic Information - Metadata - XML Schema Implementation
+
+This XML Schema implementation is composed of the following namespaces:
+- Geographic Common (GCO) extensible markup language 
+  (http://www.isotc211.org/2005/gco)
+- Geographic MetaData (GMD) extensible markup language
+  (http://www.isotc211.org/2005/gmd)
+- Geographic Metadata XML (GMX) Schema (http://www.isotc211.org/2005/gmx)
+- Geographic Spatial Schema (GSS) extensible markup language
+  (http://www.isotc211.org/2005/gss)
+- Geographic Spatial Referencing (GSR) extensible markup language
+  (http://www.isotc211.org/2005/gsr)
+- Geographic Temporal Schema (GTS) extensible markup language
+  (http://www.isotc211.org/2005/gts)
+
+The most current schemas are available at:
+http://standards.iso.org/ittf/PubliclyAvailableStandards/ISO_19139_Schemas/
+
+XML resources related to those namespaces are also provided at this location.
+
+-------------------------------------------------------------------------------
+
+See X\ReadMe.txt for details of lineage and modification of the package X
diff --git a/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gco/ReadMe.txt b/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gco/ReadMe.txt
new file mode 100644
index 0000000..db0b4ed
--- /dev/null
+++ b/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gco/ReadMe.txt
@@ -0,0 +1,47 @@
+ISO(c) GCO schema ReadMe.txt
+------------------------------------------------------------------------------
+
+Geographic COmmon (GCO) extensible markup language
+
+GCO is a component of the XML Schema Implementation of Geographic
+Information Metadata documented in ISO/TS 19139:2007.
+
+GCO includes all the definitions of http://www.isotc211.org/2005/gco
+namespace. The root document of this namespace is the file gco.xsd.
+
+The most current schemas are available at:
+http://standards.iso.org/ittf/PubliclyAvailableStandards/ISO_19139_Schemas/
+
+-------------------------------------------------------------------------------
+
+2012-07-13 Nicolas Lesage on behalf of the ISO/TC 211 XML Maintenance Group
+	* Update of readme.txt file and schema annotations
+	* Use of absolute schema locations of imported namespaces
+	* Simplification of the schema location of included XML Schemas
+	* Adoption of W3C Implementation of XLink:
+		- schemaLocation changed to: http://www.w3.org/1999/xlink.xsd
+		- xlink:simpleLink renamed xlink:simpleAttrs
+	* Addition of the version attribute to the schema element. The value of
+	  this attribute is expected to be the date of the last release of the
+	  XML schemas (e.g. 2012-07-13 for this release)
+	* Include root XML Schema document in all schema documents
+
+	Validation: Schemas have been validated with XML Spy 2010 Rel. 2 (MSXML 6.0)
+
+2009-03-16 Marcellin Prudham & Nicolas Lesage
+	* Change of GML namespace: http://www.opengis.net/gml (GML 3.2) => 
+	                           http://www.opengis.net/gml/3.2 (GML 3.2.1=ISO 19136)
+							   
+	Note: ISO/TS 19139:2007 (published 2007-04-17) normatively reference
+	ISO 19136 which was	published 2007-08-23. The major change applied to
+	ISO 19136 is the change of the namespace URI. Previous release of GCO
+	are not compliant with ISO/TS 19139:2007
+	
+	Validation: Schemas have been validated with XSV 2.10, Xerces J 2.7.1 and 
+	XML Spy 2009 (2009-03-02, IGN / France - Nicolas Lesage / Marcellin Prudham)
+							   
+2006-05-04 Marie-Pierre Escher & Nicolas Lesage
+	* First official release of GCO
+	* GCO XML Schema files were generated from ISO/TC 211 UML class diagrams
+  	  in accordance with ISO/TS 19139:2007. The XML Schema generator is a
+	  Rational Rose Plug-in developed by IGN France (nicolas.lesage at ign.fr).
diff --git a/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gco/basicTypes.xsd b/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gco/basicTypes.xsd
similarity index 95%
copy from pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gco/basicTypes.xsd
copy to pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gco/basicTypes.xsd
index 803f899..5cb345e 100644
--- a/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gco/basicTypes.xsd
+++ b/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gco/basicTypes.xsd
@@ -1,13 +1,15 @@
 <?xml version="1.0" encoding="utf-8"?>
-<xs:schema targetNamespace="http://www.isotc211.org/2005/gco" elementFormDefault="qualified" version="0.1" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:gml="http://www.opengis.net/gml" xmlns:gco="http://www.isotc211.org/2005/gco">
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:gml="http://www.opengis.net/gml/3.2" xmlns:gco="http://www.isotc211.org/2005/gco" targetNamespace="http://www.isotc211.org/2005/gco" elementFormDefault="qualified" version="2012-07-13">
 	<!-- ================================= Annotation ================================ -->
 	<xs:annotation>
-		<xs:documentation>This file was generated from ISO TC/211 UML class diagrams == 01-26-2005 12:00:05 ====== </xs:documentation>
+		<xs:documentation>Geographic COmmon (GCO) extensible markup language is a component of the XML Schema Implementation of Geographic
+Information Metadata documented in ISO/TS 19139:2007. GCO includes all the definitions of http://www.isotc211.org/2005/gco namespace. The root document of this namespace is the file gco.xsd. This basicTypes.xsd schema implements concepts from the "basic types" package of ISO/TS 19103.</xs:documentation>
 	</xs:annotation>
 	<!-- ================================== Imports ================================== -->
-	<xs:import namespace="http://www.opengis.net/gml" schemaLocation="../gml/gml.xsd"/>
-	<xs:import namespace="http://www.w3.org/1999/xlink" schemaLocation="../../../../../../../../../../pycsw/schemas/w3c/1999/xlink.xsd"/>
-	<xs:include schemaLocation="../gco/gcoBase.xsd"/>
+	<xs:import namespace="http://www.opengis.net/gml/3.2" schemaLocation="../../../../../../../../../core/schemas/ogc/gml/3.2.1/gml.xsd"/>
+	<xs:import namespace="http://www.w3.org/1999/xlink" schemaLocation="../../../../../../../../../core/schemas/w3c/1999/xlink.xsd"/>
+	<xs:include schemaLocation="gco.xsd"/>
+	<xs:include schemaLocation="gcoBase.xsd"/>
 	<!-- ########################################################################### -->
 	<!-- ########################################################################### -->
 	<!-- ================================== Classes ================================= -->
diff --git a/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gco/gco.xsd b/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gco/gco.xsd
new file mode 100644
index 0000000..6090d49
--- /dev/null
+++ b/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gco/gco.xsd
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:gco="http://www.isotc211.org/2005/gco" targetNamespace="http://www.isotc211.org/2005/gco" elementFormDefault="qualified" version="2012-07-13">
+	<!-- ================================= Annotation ================================ -->
+	<xs:annotation>
+		<xs:documentation>Geographic COmmon (GCO) extensible markup language is a component of the XML Schema Implementation of Geographic Information Metadata documented in ISO/TS 19139:2007. GCO includes all the definitions of http://www.isotc211.org/2005/gco namespace. The root document of this namespace is the file gco.xsd.</xs:documentation>
+	</xs:annotation>
+	<!-- ================================== Imports ================================== -->
+	<xs:include schemaLocation="basicTypes.xsd"/>
+	<!-- ########################################################################### -->
+	<!-- ########################################################################### -->
+	<!-- ================================== Classes ================================= -->
+</xs:schema>
diff --git a/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gco/gcoBase.xsd b/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gco/gcoBase.xsd
similarity index 77%
copy from pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gco/gcoBase.xsd
copy to pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gco/gcoBase.xsd
index 4f6f796..4c16390 100644
--- a/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gco/gcoBase.xsd
+++ b/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gco/gcoBase.xsd
@@ -1,14 +1,16 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<xs:schema targetNamespace="http://www.isotc211.org/2005/gco" elementFormDefault="qualified" attributeFormDefault="unqualified" xmlns:gco="http://www.isotc211.org/2005/gco" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:gml="http://www.opengis.net/gml">
+<xs:schema xmlns:gco="http://www.isotc211.org/2005/gco" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:gml="http://www.opengis.net/gml/3.2" targetNamespace="http://www.isotc211.org/2005/gco" elementFormDefault="qualified" attributeFormDefault="unqualified" version="2012-07-13">
 	<!-- ================================= Annotation ================================ -->
 	<xs:annotation>
-		<xs:documentation>This schema provides:
+		<xs:documentation>Geographic COmmon (GCO) extensible markup language is a component of the XML Schema Implementation of Geographic
+Information Metadata documented in ISO/TS 19139:2007. GCO includes all the definitions of http://www.isotc211.org/2005/gco namespace. The root document of this namespace is the file gco.xsd. This gcoBase.xsd schema provides:
 		1.  tools to handle specific objects like "code lists" and "record";
 		2. Some XML types representing that do not follow the general encoding rules.</xs:documentation>
 	</xs:annotation>
 	<!-- ================================== Imports ================================== -->
-	<xs:import namespace="http://www.w3.org/1999/xlink" schemaLocation="../../../../../../../../../../pycsw/schemas/w3c/1999/xlink.xsd"/>
-	<xs:import namespace="http://www.opengis.net/gml" schemaLocation="../gml/gml.xsd"/>
+	<xs:import namespace="http://www.w3.org/1999/xlink" schemaLocation="../../../../../../../../../core/schemas/w3c/1999/xlink.xsd"/>
+	<xs:import namespace="http://www.opengis.net/gml/3.2" schemaLocation="../../../../../../../../../core/schemas/ogc/gml/3.2.1/gml.xsd"/>
+	<xs:include schemaLocation="gco.xsd"/>
 	<!-- ########################################################################### -->
 	<!-- ########################################################################### -->
 	<!-- =========================================================================== -->
diff --git a/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gmd/ReadMe.txt b/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gmd/ReadMe.txt
new file mode 100644
index 0000000..2c4c7c6
--- /dev/null
+++ b/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gmd/ReadMe.txt
@@ -0,0 +1,45 @@
+ISO(c) GMD schema ReadMe.txt
+------------------------------------------------------------------------------
+
+Geographic MetaData (GMD) extensible markup language
+
+GMD is a component of the XML Schema Implementation of Geographic
+Information Metadata documented in ISO/TS 19139:2007.
+
+GMD includes all the definitions of http://www.isotc211.org/2005/gmd
+namespace. The root document of this namespace is the file gmd.xsd.
+
+The most current schemas are available at:
+http://standards.iso.org/ittf/PubliclyAvailableStandards/ISO_19139_Schemas/
+
+-------------------------------------------------------------------------------
+
+2012-07-13 Nicolas Lesage on behalf of the ISO/TC 211 XML Maintenance Group
+	* Update of readme.txt file and schema annotations
+	* Use of absolute schema locations of imported namespaces
+	* Simplification of the schema location of included XML Schemas
+	* Addition of the version attribute to the schema element. The value of
+	  this attribute is expected to be the date of the last release of the
+	  XML schemas (e.g. 2012-07-13 for this release)
+	* Include root XML Schema document in all schema documents
+
+	Validation: Schemas have been validated with XML Spy 2010 Rel. 2 (MSXML 6.0)
+
+2009-03-16 Marcellin Prudham & Nicolas Lesage
+	* Change of GML namespace: http://www.opengis.net/gml (GML 3.2) => 
+	                           http://www.opengis.net/gml/3.2 (GML 3.2.1=ISO 19136)
+							   
+	Note: ISO/TS 19139:2007 (published 2007-04-17) normatively reference
+	ISO 19136 which was	published 2007-08-23. The major change applied to
+	ISO 19136 is the change of the namespace URI. Previous release of GMD
+	are not compliant with ISO/TS 19139:2007
+	
+	Validation: Schemas have been validated with XSV 2.10, Xerces J 2.7.1 and 
+	XML Spy 2009 (2009-03-02, IGN / France - Nicolas Lesage / Marcellin Prudham)
+							   
+2006-05-04 Marie-Pierre Escher & Nicolas Lesage 
+	* First official release of GMD
+	* GMD XML Schema files were generated from ISO/TC 211 UML class diagrams
+  	  in accordance with ISO/TS 19139:2007. The XML Schema generator is a
+	  Rational Rose Plug-in developed by IGN France (http://www.ign.fr).
+
diff --git a/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gmd/applicationSchema.xsd b/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gmd/applicationSchema.xsd
new file mode 100644
index 0000000..0a7ccbb
--- /dev/null
+++ b/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gmd/applicationSchema.xsd
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="utf-8"?>
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:gco="http://www.isotc211.org/2005/gco" xmlns:gmd="http://www.isotc211.org/2005/gmd" targetNamespace="http://www.isotc211.org/2005/gmd" elementFormDefault="qualified" version="2012-07-13">
+	<!-- ================================= Annotation ================================ -->
+	<xs:annotation>
+		<xs:documentation>Geographic MetaData (GMD) extensible markup language is a component of the XML Schema Implementation of Geographic Information Metadata documented in ISO/TS 19139:2007. GMD includes all the definitions of http://www.isotc211.org/2005/gmd namespace. The root document of this namespace is the file gmd.xsd. This applicationSchema.xsd schema implements the UML conceptual schema defined in A.2.12 of ISO 19115:2003. It contains the implementation of the class MD_Application [...]
+	</xs:annotation>
+	<!-- ================================== Imports ================================== -->
+	<xs:import namespace="http://www.isotc211.org/2005/gco" schemaLocation="../gco/gco.xsd"/>
+	<xs:include schemaLocation="gmd.xsd"/>
+	<xs:include schemaLocation="citation.xsd"/>
+	<!-- ########################################################################### -->
+	<!-- ########################################################################### -->
+	<!-- ================================== Classes ================================= -->
+	<xs:complexType name="MD_ApplicationSchemaInformation_Type">
+		<xs:annotation>
+			<xs:documentation>Information about the application schema used to build the dataset</xs:documentation>
+		</xs:annotation>
+		<xs:complexContent>
+			<xs:extension base="gco:AbstractObject_Type">
+				<xs:sequence>
+					<xs:element name="name" type="gmd:CI_Citation_PropertyType"/>
+					<xs:element name="schemaLanguage" type="gco:CharacterString_PropertyType"/>
+					<xs:element name="constraintLanguage" type="gco:CharacterString_PropertyType"/>
+					<xs:element name="schemaAscii" type="gco:CharacterString_PropertyType" minOccurs="0"/>
+					<xs:element name="graphicsFile" type="gco:Binary_PropertyType" minOccurs="0"/>
+					<xs:element name="softwareDevelopmentFile" type="gco:Binary_PropertyType" minOccurs="0"/>
+					<xs:element name="softwareDevelopmentFileFormat" type="gco:CharacterString_PropertyType" minOccurs="0"/>
+				</xs:sequence>
+			</xs:extension>
+		</xs:complexContent>
+	</xs:complexType>
+	<!-- ........................................................................ -->
+	<xs:element name="MD_ApplicationSchemaInformation" type="gmd:MD_ApplicationSchemaInformation_Type"/>
+	<!-- ........................................................................ -->
+	<xs:complexType name="MD_ApplicationSchemaInformation_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gmd:MD_ApplicationSchemaInformation"/>
+		</xs:sequence>
+		<xs:attributeGroup ref="gco:ObjectReference"/>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+</xs:schema>
diff --git a/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gmd/citation.xsd b/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gmd/citation.xsd
new file mode 100644
index 0000000..4f5d7dd
--- /dev/null
+++ b/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gmd/citation.xsd
@@ -0,0 +1,276 @@
+<?xml version="1.0" encoding="utf-8"?>
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:gco="http://www.isotc211.org/2005/gco" xmlns:gmd="http://www.isotc211.org/2005/gmd" targetNamespace="http://www.isotc211.org/2005/gmd" elementFormDefault="qualified" version="2012-07-13">
+	<!-- ================================= Annotation ================================ -->
+	<xs:annotation>
+		<xs:documentation>Geographic MetaData (GMD) extensible markup language is a component of the XML Schema Implementation of Geographic Information Metadata documented in ISO/TS 19139:2007. GMD includes all the definitions of http://www.isotc211.org/2005/gmd namespace. The root document of this namespace is the file gmd.xsd. This citation.xsd schema implements the UML conceptual schema defined in A.3.2 of ISO 19115:2003. It contains the implementation of the following classes: CI_Responsi [...]
+	</xs:annotation>
+	<!-- ================================== Imports ================================== -->
+	<xs:import namespace="http://www.isotc211.org/2005/gco" schemaLocation="../gco/gco.xsd"/>
+	<xs:include schemaLocation="gmd.xsd"/>
+	<xs:include schemaLocation="referenceSystem.xsd"/>
+	<!-- ########################################################################### -->
+	<!-- ########################################################################### -->
+	<!-- ================================== Classes ================================= -->
+	<xs:complexType name="CI_ResponsibleParty_Type">
+		<xs:annotation>
+			<xs:documentation>Identification of, and means of communication with, person(s) and organisations associated with the dataset</xs:documentation>
+		</xs:annotation>
+		<xs:complexContent>
+			<xs:extension base="gco:AbstractObject_Type">
+				<xs:sequence>
+					<xs:element name="individualName" type="gco:CharacterString_PropertyType" minOccurs="0"/>
+					<xs:element name="organisationName" type="gco:CharacterString_PropertyType" minOccurs="0"/>
+					<xs:element name="positionName" type="gco:CharacterString_PropertyType" minOccurs="0"/>
+					<xs:element name="contactInfo" type="gmd:CI_Contact_PropertyType" minOccurs="0"/>
+					<xs:element name="role" type="gmd:CI_RoleCode_PropertyType"/>
+				</xs:sequence>
+			</xs:extension>
+		</xs:complexContent>
+	</xs:complexType>
+	<!-- ........................................................................ -->
+	<xs:element name="CI_ResponsibleParty" type="gmd:CI_ResponsibleParty_Type"/>
+	<!-- ........................................................................ -->
+	<xs:complexType name="CI_ResponsibleParty_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gmd:CI_ResponsibleParty"/>
+		</xs:sequence>
+		<xs:attributeGroup ref="gco:ObjectReference"/>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+	<xs:complexType name="CI_Citation_Type">
+		<xs:annotation>
+			<xs:documentation>Standardized resource reference</xs:documentation>
+		</xs:annotation>
+		<xs:complexContent>
+			<xs:extension base="gco:AbstractObject_Type">
+				<xs:sequence>
+					<xs:element name="title" type="gco:CharacterString_PropertyType"/>
+					<xs:element name="alternateTitle" type="gco:CharacterString_PropertyType" minOccurs="0" maxOccurs="unbounded"/>
+					<xs:element name="date" type="gmd:CI_Date_PropertyType" maxOccurs="unbounded"/>
+					<xs:element name="edition" type="gco:CharacterString_PropertyType" minOccurs="0"/>
+					<xs:element name="editionDate" type="gco:Date_PropertyType" minOccurs="0"/>
+					<xs:element name="identifier" type="gmd:MD_Identifier_PropertyType" minOccurs="0" maxOccurs="unbounded"/>
+					<xs:element name="citedResponsibleParty" type="gmd:CI_ResponsibleParty_PropertyType" minOccurs="0" maxOccurs="unbounded"/>
+					<xs:element name="presentationForm" type="gmd:CI_PresentationFormCode_PropertyType" minOccurs="0" maxOccurs="unbounded"/>
+					<xs:element name="series" type="gmd:CI_Series_PropertyType" minOccurs="0"/>
+					<xs:element name="otherCitationDetails" type="gco:CharacterString_PropertyType" minOccurs="0"/>
+					<xs:element name="collectiveTitle" type="gco:CharacterString_PropertyType" minOccurs="0"/>
+					<xs:element name="ISBN" type="gco:CharacterString_PropertyType" minOccurs="0"/>
+					<xs:element name="ISSN" type="gco:CharacterString_PropertyType" minOccurs="0"/>
+				</xs:sequence>
+			</xs:extension>
+		</xs:complexContent>
+	</xs:complexType>
+	<!-- ........................................................................ -->
+	<xs:element name="CI_Citation" type="gmd:CI_Citation_Type"/>
+	<!-- ........................................................................ -->
+	<xs:complexType name="CI_Citation_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gmd:CI_Citation"/>
+		</xs:sequence>
+		<xs:attributeGroup ref="gco:ObjectReference"/>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+	<xs:complexType name="CI_Address_Type">
+		<xs:annotation>
+			<xs:documentation>Location of the responsible individual or organisation</xs:documentation>
+		</xs:annotation>
+		<xs:complexContent>
+			<xs:extension base="gco:AbstractObject_Type">
+				<xs:sequence>
+					<xs:element name="deliveryPoint" type="gco:CharacterString_PropertyType" minOccurs="0" maxOccurs="unbounded"/>
+					<xs:element name="city" type="gco:CharacterString_PropertyType" minOccurs="0"/>
+					<xs:element name="administrativeArea" type="gco:CharacterString_PropertyType" minOccurs="0"/>
+					<xs:element name="postalCode" type="gco:CharacterString_PropertyType" minOccurs="0"/>
+					<xs:element name="country" type="gco:CharacterString_PropertyType" minOccurs="0"/>
+					<xs:element name="electronicMailAddress" type="gco:CharacterString_PropertyType" minOccurs="0" maxOccurs="unbounded"/>
+				</xs:sequence>
+			</xs:extension>
+		</xs:complexContent>
+	</xs:complexType>
+	<!-- ........................................................................ -->
+	<xs:element name="CI_Address" type="gmd:CI_Address_Type"/>
+	<!-- ........................................................................ -->
+	<xs:complexType name="CI_Address_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gmd:CI_Address"/>
+		</xs:sequence>
+		<xs:attributeGroup ref="gco:ObjectReference"/>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+	<xs:complexType name="CI_OnlineResource_Type">
+		<xs:annotation>
+			<xs:documentation>Information about online sources from which the dataset, specification, or community profile name and extended metadata elements can be obtained.</xs:documentation>
+		</xs:annotation>
+		<xs:complexContent>
+			<xs:extension base="gco:AbstractObject_Type">
+				<xs:sequence>
+					<xs:element name="linkage" type="gmd:URL_PropertyType"/>
+					<xs:element name="protocol" type="gco:CharacterString_PropertyType" minOccurs="0"/>
+					<xs:element name="applicationProfile" type="gco:CharacterString_PropertyType" minOccurs="0"/>
+					<xs:element name="name" type="gco:CharacterString_PropertyType" minOccurs="0"/>
+					<xs:element name="description" type="gco:CharacterString_PropertyType" minOccurs="0"/>
+					<xs:element name="function" type="gmd:CI_OnLineFunctionCode_PropertyType" minOccurs="0"/>
+				</xs:sequence>
+			</xs:extension>
+		</xs:complexContent>
+	</xs:complexType>
+	<!-- ........................................................................ -->
+	<xs:element name="CI_OnlineResource" type="gmd:CI_OnlineResource_Type"/>
+	<!-- ........................................................................ -->
+	<xs:complexType name="CI_OnlineResource_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gmd:CI_OnlineResource"/>
+		</xs:sequence>
+		<xs:attributeGroup ref="gco:ObjectReference"/>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+	<xs:complexType name="CI_Contact_Type">
+		<xs:annotation>
+			<xs:documentation>Information required enabling contact with the  responsible person and/or organisation</xs:documentation>
+		</xs:annotation>
+		<xs:complexContent>
+			<xs:extension base="gco:AbstractObject_Type">
+				<xs:sequence>
+					<xs:element name="phone" type="gmd:CI_Telephone_PropertyType" minOccurs="0"/>
+					<xs:element name="address" type="gmd:CI_Address_PropertyType" minOccurs="0"/>
+					<xs:element name="onlineResource" type="gmd:CI_OnlineResource_PropertyType" minOccurs="0"/>
+					<xs:element name="hoursOfService" type="gco:CharacterString_PropertyType" minOccurs="0"/>
+					<xs:element name="contactInstructions" type="gco:CharacterString_PropertyType" minOccurs="0"/>
+				</xs:sequence>
+			</xs:extension>
+		</xs:complexContent>
+	</xs:complexType>
+	<!-- ........................................................................ -->
+	<xs:element name="CI_Contact" type="gmd:CI_Contact_Type"/>
+	<!-- ........................................................................ -->
+	<xs:complexType name="CI_Contact_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gmd:CI_Contact"/>
+		</xs:sequence>
+		<xs:attributeGroup ref="gco:ObjectReference"/>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+	<xs:complexType name="CI_Telephone_Type">
+		<xs:annotation>
+			<xs:documentation>Telephone numbers for contacting the responsible individual or organisation</xs:documentation>
+		</xs:annotation>
+		<xs:complexContent>
+			<xs:extension base="gco:AbstractObject_Type">
+				<xs:sequence>
+					<xs:element name="voice" type="gco:CharacterString_PropertyType" minOccurs="0" maxOccurs="unbounded"/>
+					<xs:element name="facsimile" type="gco:CharacterString_PropertyType" minOccurs="0" maxOccurs="unbounded"/>
+				</xs:sequence>
+			</xs:extension>
+		</xs:complexContent>
+	</xs:complexType>
+	<!-- ........................................................................ -->
+	<xs:element name="CI_Telephone" type="gmd:CI_Telephone_Type"/>
+	<!-- ........................................................................ -->
+	<xs:complexType name="CI_Telephone_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gmd:CI_Telephone"/>
+		</xs:sequence>
+		<xs:attributeGroup ref="gco:ObjectReference"/>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+	<xs:complexType name="CI_Date_Type">
+		<xs:complexContent>
+			<xs:extension base="gco:AbstractObject_Type">
+				<xs:sequence>
+					<xs:element name="date" type="gco:Date_PropertyType"/>
+					<xs:element name="dateType" type="gmd:CI_DateTypeCode_PropertyType"/>
+				</xs:sequence>
+			</xs:extension>
+		</xs:complexContent>
+	</xs:complexType>
+	<!-- ........................................................................ -->
+	<xs:element name="CI_Date" type="gmd:CI_Date_Type"/>
+	<!-- ........................................................................ -->
+	<xs:complexType name="CI_Date_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gmd:CI_Date"/>
+		</xs:sequence>
+		<xs:attributeGroup ref="gco:ObjectReference"/>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+	<xs:complexType name="CI_Series_Type">
+		<xs:complexContent>
+			<xs:extension base="gco:AbstractObject_Type">
+				<xs:sequence>
+					<xs:element name="name" type="gco:CharacterString_PropertyType" minOccurs="0"/>
+					<xs:element name="issueIdentification" type="gco:CharacterString_PropertyType" minOccurs="0"/>
+					<xs:element name="page" type="gco:CharacterString_PropertyType" minOccurs="0"/>
+				</xs:sequence>
+			</xs:extension>
+		</xs:complexContent>
+	</xs:complexType>
+	<!-- ........................................................................ -->
+	<xs:element name="CI_Series" type="gmd:CI_Series_Type"/>
+	<!-- ........................................................................ -->
+	<xs:complexType name="CI_Series_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gmd:CI_Series"/>
+		</xs:sequence>
+		<xs:attributeGroup ref="gco:ObjectReference"/>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+	<!-- ........................................................................ -->
+	<xs:element name="URL" type="xs:anyURI"/>
+	<!-- ........................................................................ -->
+	<xs:complexType name="URL_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gmd:URL"/>
+		</xs:sequence>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+	<!-- ........................................................................ -->
+	<xs:element name="CI_RoleCode" type="gco:CodeListValue_Type" substitutionGroup="gco:CharacterString"/>
+	<!-- ........................................................................ -->
+	<xs:complexType name="CI_RoleCode_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gmd:CI_RoleCode"/>
+		</xs:sequence>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+	<!-- ........................................................................ -->
+	<xs:element name="CI_PresentationFormCode" type="gco:CodeListValue_Type" substitutionGroup="gco:CharacterString"/>
+	<!-- ........................................................................ -->
+	<xs:complexType name="CI_PresentationFormCode_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gmd:CI_PresentationFormCode"/>
+		</xs:sequence>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+	<!-- ........................................................................ -->
+	<xs:element name="CI_OnLineFunctionCode" type="gco:CodeListValue_Type" substitutionGroup="gco:CharacterString"/>
+	<!-- ........................................................................ -->
+	<xs:complexType name="CI_OnLineFunctionCode_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gmd:CI_OnLineFunctionCode"/>
+		</xs:sequence>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+	<!-- ........................................................................ -->
+	<xs:element name="CI_DateTypeCode" type="gco:CodeListValue_Type" substitutionGroup="gco:CharacterString"/>
+	<!-- ........................................................................ -->
+	<xs:complexType name="CI_DateTypeCode_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gmd:CI_DateTypeCode"/>
+		</xs:sequence>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+</xs:schema>
diff --git a/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gmd/constraints.xsd b/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gmd/constraints.xsd
new file mode 100644
index 0000000..b683389
--- /dev/null
+++ b/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gmd/constraints.xsd
@@ -0,0 +1,107 @@
+<?xml version="1.0" encoding="utf-8"?>
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:gco="http://www.isotc211.org/2005/gco" xmlns:gmd="http://www.isotc211.org/2005/gmd" targetNamespace="http://www.isotc211.org/2005/gmd" elementFormDefault="qualified" version="2012-07-13">
+	<!-- ================================= Annotation ================================ -->
+	<xs:annotation>
+		<xs:documentation>Geographic MetaData (GMD) extensible markup language is a component of the XML Schema Implementation of Geographic Information Metadata documented in ISO/TS 19139:2007. GMD includes all the definitions of http://www.isotc211.org/2005/gmd namespace. The root document of this namespace is the file gmd.xsd. This constraints.xsd schema implements the UML conceptual schema defined in A.2.3 of ISO 19115:2003. It contains the implementation of the following classes: MD_Const [...]
+	</xs:annotation>
+	<!-- ================================== Imports ================================== -->
+	<xs:import namespace="http://www.isotc211.org/2005/gco" schemaLocation="../gco/gco.xsd"/>
+	<xs:include schemaLocation="gmd.xsd"/>
+	<!-- ########################################################################### -->
+	<!-- ########################################################################### -->
+	<!-- ================================== Classes ================================= -->
+	<xs:complexType name="MD_Constraints_Type">
+		<xs:annotation>
+			<xs:documentation>Restrictions on the access and use of a dataset or metadata</xs:documentation>
+		</xs:annotation>
+		<xs:complexContent>
+			<xs:extension base="gco:AbstractObject_Type">
+				<xs:sequence>
+					<xs:element name="useLimitation" type="gco:CharacterString_PropertyType" minOccurs="0" maxOccurs="unbounded"/>
+				</xs:sequence>
+			</xs:extension>
+		</xs:complexContent>
+	</xs:complexType>
+	<!-- ........................................................................ -->
+	<xs:element name="MD_Constraints" type="gmd:MD_Constraints_Type"/>
+	<!-- ........................................................................ -->
+	<xs:complexType name="MD_Constraints_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gmd:MD_Constraints"/>
+		</xs:sequence>
+		<xs:attributeGroup ref="gco:ObjectReference"/>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+	<xs:complexType name="MD_LegalConstraints_Type">
+		<xs:annotation>
+			<xs:documentation>Restrictions and legal prerequisites for accessing and using the dataset.</xs:documentation>
+		</xs:annotation>
+		<xs:complexContent>
+			<xs:extension base="gmd:MD_Constraints_Type">
+				<xs:sequence>
+					<xs:element name="accessConstraints" type="gmd:MD_RestrictionCode_PropertyType" minOccurs="0" maxOccurs="unbounded"/>
+					<xs:element name="useConstraints" type="gmd:MD_RestrictionCode_PropertyType" minOccurs="0" maxOccurs="unbounded"/>
+					<xs:element name="otherConstraints" type="gco:CharacterString_PropertyType" minOccurs="0" maxOccurs="unbounded"/>
+				</xs:sequence>
+			</xs:extension>
+		</xs:complexContent>
+	</xs:complexType>
+	<!-- ........................................................................ -->
+	<xs:element name="MD_LegalConstraints" type="gmd:MD_LegalConstraints_Type" substitutionGroup="gmd:MD_Constraints"/>
+	<!-- ........................................................................ -->
+	<xs:complexType name="MD_LegalConstraints_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gmd:MD_LegalConstraints"/>
+		</xs:sequence>
+		<xs:attributeGroup ref="gco:ObjectReference"/>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+	<xs:complexType name="MD_SecurityConstraints_Type">
+		<xs:annotation>
+			<xs:documentation>Handling restrictions imposed on the dataset because of national security, privacy, or other concerns</xs:documentation>
+		</xs:annotation>
+		<xs:complexContent>
+			<xs:extension base="gmd:MD_Constraints_Type">
+				<xs:sequence>
+					<xs:element name="classification" type="gmd:MD_ClassificationCode_PropertyType"/>
+					<xs:element name="userNote" type="gco:CharacterString_PropertyType" minOccurs="0"/>
+					<xs:element name="classificationSystem" type="gco:CharacterString_PropertyType" minOccurs="0"/>
+					<xs:element name="handlingDescription" type="gco:CharacterString_PropertyType" minOccurs="0"/>
+				</xs:sequence>
+			</xs:extension>
+		</xs:complexContent>
+	</xs:complexType>
+	<!-- ........................................................................ -->
+	<xs:element name="MD_SecurityConstraints" type="gmd:MD_SecurityConstraints_Type" substitutionGroup="gmd:MD_Constraints"/>
+	<!-- ........................................................................ -->
+	<xs:complexType name="MD_SecurityConstraints_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gmd:MD_SecurityConstraints"/>
+		</xs:sequence>
+		<xs:attributeGroup ref="gco:ObjectReference"/>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+	<!-- ........................................................................ -->
+	<xs:element name="MD_ClassificationCode" type="gco:CodeListValue_Type" substitutionGroup="gco:CharacterString"/>
+	<!-- ........................................................................ -->
+	<xs:complexType name="MD_ClassificationCode_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gmd:MD_ClassificationCode"/>
+		</xs:sequence>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+	<!-- ........................................................................ -->
+	<xs:element name="MD_RestrictionCode" type="gco:CodeListValue_Type" substitutionGroup="gco:CharacterString"/>
+	<!-- ........................................................................ -->
+	<xs:complexType name="MD_RestrictionCode_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gmd:MD_RestrictionCode"/>
+		</xs:sequence>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+</xs:schema>
diff --git a/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gmd/content.xsd b/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gmd/content.xsd
new file mode 100644
index 0000000..bf3c946
--- /dev/null
+++ b/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gmd/content.xsd
@@ -0,0 +1,190 @@
+<?xml version="1.0" encoding="utf-8"?>
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:gco="http://www.isotc211.org/2005/gco" xmlns:gmd="http://www.isotc211.org/2005/gmd" targetNamespace="http://www.isotc211.org/2005/gmd" elementFormDefault="qualified" version="2012-07-13">
+	<!-- ================================= Annotation ================================ -->
+	<xs:annotation>
+		<xs:documentation>Geographic MetaData (GMD) extensible markup language is a component of the XML Schema Implementation of Geographic Information Metadata documented in ISO/TS 19139:2007. GMD includes all the definitions of http://www.isotc211.org/2005/gmd namespace. The root document of this namespace is the file gmd.xsd. This content.xsd schema implements the UML conceptual schema defined in ISO 19115:2003, A.2.8. It contains the implementation of the following classes: MD_FeatureCata [...]
+MD_ImageDescription, MD_ContentInformation, MD_RangeDimension, MD_Band, MD_CoverageContentTypeCode, MD_ImagingConditionCode.</xs:documentation>
+	</xs:annotation>
+	<!-- ================================== Imports ================================== -->
+	<xs:import namespace="http://www.isotc211.org/2005/gco" schemaLocation="../gco/gco.xsd"/>
+	<xs:include schemaLocation="gmd.xsd"/>
+	<xs:include schemaLocation="citation.xsd"/>
+	<!-- ########################################################################### -->
+	<!-- ########################################################################### -->
+	<!-- ================================== Classes ================================= -->
+	<xs:complexType name="MD_FeatureCatalogueDescription_Type">
+		<xs:annotation>
+			<xs:documentation>Information identifing the feature catalogue</xs:documentation>
+		</xs:annotation>
+		<xs:complexContent>
+			<xs:extension base="gmd:AbstractMD_ContentInformation_Type">
+				<xs:sequence>
+					<xs:element name="complianceCode" type="gco:Boolean_PropertyType" minOccurs="0"/>
+					<xs:element name="language" type="gco:CharacterString_PropertyType" minOccurs="0" maxOccurs="unbounded"/>
+					<xs:element name="includedWithDataset" type="gco:Boolean_PropertyType"/>
+					<xs:element name="featureTypes" type="gco:GenericName_PropertyType" minOccurs="0" maxOccurs="unbounded"/>
+					<xs:element name="featureCatalogueCitation" type="gmd:CI_Citation_PropertyType" maxOccurs="unbounded"/>
+				</xs:sequence>
+			</xs:extension>
+		</xs:complexContent>
+	</xs:complexType>
+	<!-- ........................................................................ -->
+	<xs:element name="MD_FeatureCatalogueDescription" type="gmd:MD_FeatureCatalogueDescription_Type" substitutionGroup="gmd:AbstractMD_ContentInformation"/>
+	<!-- ........................................................................ -->
+	<xs:complexType name="MD_FeatureCatalogueDescription_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gmd:MD_FeatureCatalogueDescription"/>
+		</xs:sequence>
+		<xs:attributeGroup ref="gco:ObjectReference"/>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+	<xs:complexType name="MD_CoverageDescription_Type">
+		<xs:annotation>
+			<xs:documentation>Information about the domain of the raster cell</xs:documentation>
+		</xs:annotation>
+		<xs:complexContent>
+			<xs:extension base="gmd:AbstractMD_ContentInformation_Type">
+				<xs:sequence>
+					<xs:element name="attributeDescription" type="gco:RecordType_PropertyType"/>
+					<xs:element name="contentType" type="gmd:MD_CoverageContentTypeCode_PropertyType"/>
+					<xs:element name="dimension" type="gmd:MD_RangeDimension_PropertyType" minOccurs="0" maxOccurs="unbounded"/>
+				</xs:sequence>
+			</xs:extension>
+		</xs:complexContent>
+	</xs:complexType>
+	<!-- ........................................................................ -->
+	<xs:element name="MD_CoverageDescription" type="gmd:MD_CoverageDescription_Type" substitutionGroup="gmd:AbstractMD_ContentInformation"/>
+	<!-- ........................................................................ -->
+	<xs:complexType name="MD_CoverageDescription_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gmd:MD_CoverageDescription"/>
+		</xs:sequence>
+		<xs:attributeGroup ref="gco:ObjectReference"/>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+	<xs:complexType name="MD_ImageDescription_Type">
+		<xs:annotation>
+			<xs:documentation>Information about an image's suitability for use</xs:documentation>
+		</xs:annotation>
+		<xs:complexContent>
+			<xs:extension base="gmd:MD_CoverageDescription_Type">
+				<xs:sequence>
+					<xs:element name="illuminationElevationAngle" type="gco:Real_PropertyType" minOccurs="0"/>
+					<xs:element name="illuminationAzimuthAngle" type="gco:Real_PropertyType" minOccurs="0"/>
+					<xs:element name="imagingCondition" type="gmd:MD_ImagingConditionCode_PropertyType" minOccurs="0"/>
+					<xs:element name="imageQualityCode" type="gmd:MD_Identifier_PropertyType" minOccurs="0"/>
+					<xs:element name="cloudCoverPercentage" type="gco:Real_PropertyType" minOccurs="0"/>
+					<xs:element name="processingLevelCode" type="gmd:MD_Identifier_PropertyType" minOccurs="0"/>
+					<xs:element name="compressionGenerationQuantity" type="gco:Integer_PropertyType" minOccurs="0"/>
+					<xs:element name="triangulationIndicator" type="gco:Boolean_PropertyType" minOccurs="0"/>
+					<xs:element name="radiometricCalibrationDataAvailability" type="gco:Boolean_PropertyType" minOccurs="0"/>
+					<xs:element name="cameraCalibrationInformationAvailability" type="gco:Boolean_PropertyType" minOccurs="0"/>
+					<xs:element name="filmDistortionInformationAvailability" type="gco:Boolean_PropertyType" minOccurs="0"/>
+					<xs:element name="lensDistortionInformationAvailability" type="gco:Boolean_PropertyType" minOccurs="0"/>
+				</xs:sequence>
+			</xs:extension>
+		</xs:complexContent>
+	</xs:complexType>
+	<!-- ........................................................................ -->
+	<xs:element name="MD_ImageDescription" type="gmd:MD_ImageDescription_Type" substitutionGroup="gmd:MD_CoverageDescription"/>
+	<!-- ........................................................................ -->
+	<xs:complexType name="MD_ImageDescription_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gmd:MD_ImageDescription"/>
+		</xs:sequence>
+		<xs:attributeGroup ref="gco:ObjectReference"/>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+	<xs:complexType name="AbstractMD_ContentInformation_Type" abstract="true">
+		<xs:complexContent>
+			<xs:extension base="gco:AbstractObject_Type">
+				<xs:sequence/>
+			</xs:extension>
+		</xs:complexContent>
+	</xs:complexType>
+	<!-- ........................................................................ -->
+	<xs:element name="AbstractMD_ContentInformation" type="gmd:AbstractMD_ContentInformation_Type" abstract="true"/>
+	<!-- ........................................................................ -->
+	<xs:complexType name="MD_ContentInformation_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gmd:AbstractMD_ContentInformation"/>
+		</xs:sequence>
+		<xs:attributeGroup ref="gco:ObjectReference"/>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+	<xs:complexType name="MD_RangeDimension_Type">
+		<xs:annotation>
+			<xs:documentation>Set of adjacent wavelengths in the electro-magnetic spectrum with a common characteristic, such as the visible band</xs:documentation>
+		</xs:annotation>
+		<xs:complexContent>
+			<xs:extension base="gco:AbstractObject_Type">
+				<xs:sequence>
+					<xs:element name="sequenceIdentifier" type="gco:MemberName_PropertyType" minOccurs="0"/>
+					<xs:element name="descriptor" type="gco:CharacterString_PropertyType" minOccurs="0"/>
+				</xs:sequence>
+			</xs:extension>
+		</xs:complexContent>
+	</xs:complexType>
+	<!-- ........................................................................ -->
+	<xs:element name="MD_RangeDimension" type="gmd:MD_RangeDimension_Type"/>
+	<!-- ........................................................................ -->
+	<xs:complexType name="MD_RangeDimension_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gmd:MD_RangeDimension"/>
+		</xs:sequence>
+		<xs:attributeGroup ref="gco:ObjectReference"/>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+	<xs:complexType name="MD_Band_Type">
+		<xs:complexContent>
+			<xs:extension base="gmd:MD_RangeDimension_Type">
+				<xs:sequence>
+					<xs:element name="maxValue" type="gco:Real_PropertyType" minOccurs="0"/>
+					<xs:element name="minValue" type="gco:Real_PropertyType" minOccurs="0"/>
+					<xs:element name="units" type="gco:UomLength_PropertyType" minOccurs="0"/>
+					<xs:element name="peakResponse" type="gco:Real_PropertyType" minOccurs="0"/>
+					<xs:element name="bitsPerValue" type="gco:Integer_PropertyType" minOccurs="0"/>
+					<xs:element name="toneGradation" type="gco:Integer_PropertyType" minOccurs="0"/>
+					<xs:element name="scaleFactor" type="gco:Real_PropertyType" minOccurs="0"/>
+					<xs:element name="offset" type="gco:Real_PropertyType" minOccurs="0"/>
+				</xs:sequence>
+			</xs:extension>
+		</xs:complexContent>
+	</xs:complexType>
+	<!-- ........................................................................ -->
+	<xs:element name="MD_Band" type="gmd:MD_Band_Type" substitutionGroup="gmd:MD_RangeDimension"/>
+	<!-- ........................................................................ -->
+	<xs:complexType name="MD_Band_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gmd:MD_Band"/>
+		</xs:sequence>
+		<xs:attributeGroup ref="gco:ObjectReference"/>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+	<!-- ........................................................................ -->
+	<xs:element name="MD_CoverageContentTypeCode" type="gco:CodeListValue_Type" substitutionGroup="gco:CharacterString"/>
+	<!-- ........................................................................ -->
+	<xs:complexType name="MD_CoverageContentTypeCode_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gmd:MD_CoverageContentTypeCode"/>
+		</xs:sequence>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+	<!-- ........................................................................ -->
+	<xs:element name="MD_ImagingConditionCode" type="gco:CodeListValue_Type" substitutionGroup="gco:CharacterString"/>
+	<!-- ........................................................................ -->
+	<xs:complexType name="MD_ImagingConditionCode_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gmd:MD_ImagingConditionCode"/>
+		</xs:sequence>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+</xs:schema>
diff --git a/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gmd/dataQuality.xsd b/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gmd/dataQuality.xsd
new file mode 100644
index 0000000..3cd6d16
--- /dev/null
+++ b/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gmd/dataQuality.xsd
@@ -0,0 +1,556 @@
+<?xml version="1.0" encoding="utf-8"?>
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:gco="http://www.isotc211.org/2005/gco" xmlns:gmd="http://www.isotc211.org/2005/gmd" targetNamespace="http://www.isotc211.org/2005/gmd" elementFormDefault="qualified" version="2012-07-13">
+	<!-- ================================= Annotation ================================ -->
+	<xs:annotation>
+		<xs:documentation>Geographic MetaData (GMD) extensible markup language is a component of the XML Schema Implementation of Geographic Information Metadata documented in ISO/TS 19139:2007. GMD includes all the definitions of http://www.isotc211.org/2005/gmd namespace. The root document of this namespace is the file gmd.xsd. This dataQuality.xsd schema implements the UML conceptual schema defined in A.2.4 of ISO 19115:2003. It contains the implementation of the following classes: LI_Proce [...]
+DQ_ConformanceResult, DQ_QuantitativeResult, DQ_Result, DQ_TemporalValidity, DQ_AccuracyOfATimeMeasurement, DQ_QuantitativeAttributeAccuracy, DQ_NonQuantitativeAttributeAccuracy, DQ_ThematicClassificationCorrectness, DQ_RelativeInternalPositionalAccuracy, DQ_GriddedDataPositionalAccuracy, DQ_AbsoluteExternalPositionalAccuracy, DQ_TopologicalConsistency, DQ_FormatConsistency, DQ_DomainConsistency, DQ_ConceptualConsistency, DQ_CompletenessOmission, DQ_CompletenessCommission, DQ_TemporalAcc [...]
+	</xs:annotation>
+	<!-- ================================== Imports ================================== -->
+	<xs:import namespace="http://www.isotc211.org/2005/gco" schemaLocation="../gco/gco.xsd"/>
+	<xs:include schemaLocation="gmd.xsd"/>
+	<xs:include schemaLocation="identification.xsd"/>
+	<!-- ########################################################################### -->
+	<!-- ########################################################################### -->
+	<!-- ================================== Classes ================================= -->
+	<xs:complexType name="LI_ProcessStep_Type">
+		<xs:complexContent>
+			<xs:extension base="gco:AbstractObject_Type">
+				<xs:sequence>
+					<xs:element name="description" type="gco:CharacterString_PropertyType"/>
+					<xs:element name="rationale" type="gco:CharacterString_PropertyType" minOccurs="0"/>
+					<xs:element name="dateTime" type="gco:DateTime_PropertyType" minOccurs="0"/>
+					<xs:element name="processor" type="gmd:CI_ResponsibleParty_PropertyType" minOccurs="0" maxOccurs="unbounded"/>
+					<xs:element name="source" type="gmd:LI_Source_PropertyType" minOccurs="0" maxOccurs="unbounded"/>
+				</xs:sequence>
+			</xs:extension>
+		</xs:complexContent>
+	</xs:complexType>
+	<!-- ........................................................................ -->
+	<xs:element name="LI_ProcessStep" type="gmd:LI_ProcessStep_Type"/>
+	<!-- ........................................................................ -->
+	<xs:complexType name="LI_ProcessStep_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gmd:LI_ProcessStep"/>
+		</xs:sequence>
+		<xs:attributeGroup ref="gco:ObjectReference"/>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+	<xs:complexType name="LI_Source_Type">
+		<xs:complexContent>
+			<xs:extension base="gco:AbstractObject_Type">
+				<xs:sequence>
+					<xs:element name="description" type="gco:CharacterString_PropertyType" minOccurs="0"/>
+					<xs:element name="scaleDenominator" type="gmd:MD_RepresentativeFraction_PropertyType" minOccurs="0"/>
+					<xs:element name="sourceReferenceSystem" type="gmd:MD_ReferenceSystem_PropertyType" minOccurs="0"/>
+					<xs:element name="sourceCitation" type="gmd:CI_Citation_PropertyType" minOccurs="0"/>
+					<xs:element name="sourceExtent" type="gmd:EX_Extent_PropertyType" minOccurs="0" maxOccurs="unbounded"/>
+					<xs:element name="sourceStep" type="gmd:LI_ProcessStep_PropertyType" minOccurs="0" maxOccurs="unbounded"/>
+				</xs:sequence>
+			</xs:extension>
+		</xs:complexContent>
+	</xs:complexType>
+	<!-- ........................................................................ -->
+	<xs:element name="LI_Source" type="gmd:LI_Source_Type"/>
+	<!-- ........................................................................ -->
+	<xs:complexType name="LI_Source_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gmd:LI_Source"/>
+		</xs:sequence>
+		<xs:attributeGroup ref="gco:ObjectReference"/>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+	<xs:complexType name="LI_Lineage_Type">
+		<xs:complexContent>
+			<xs:extension base="gco:AbstractObject_Type">
+				<xs:sequence>
+					<xs:element name="statement" type="gco:CharacterString_PropertyType" minOccurs="0"/>
+					<xs:element name="processStep" type="gmd:LI_ProcessStep_PropertyType" minOccurs="0" maxOccurs="unbounded"/>
+					<xs:element name="source" type="gmd:LI_Source_PropertyType" minOccurs="0" maxOccurs="unbounded"/>
+				</xs:sequence>
+			</xs:extension>
+		</xs:complexContent>
+	</xs:complexType>
+	<!-- ........................................................................ -->
+	<xs:element name="LI_Lineage" type="gmd:LI_Lineage_Type"/>
+	<!-- ........................................................................ -->
+	<xs:complexType name="LI_Lineage_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gmd:LI_Lineage"/>
+		</xs:sequence>
+		<xs:attributeGroup ref="gco:ObjectReference"/>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+	<xs:complexType name="DQ_ConformanceResult_Type">
+		<xs:annotation>
+			<xs:documentation>quantitative_result from Quality Procedures -  - renamed to remove implied use limitiation.</xs:documentation>
+		</xs:annotation>
+		<xs:complexContent>
+			<xs:extension base="gmd:AbstractDQ_Result_Type">
+				<xs:sequence>
+					<xs:element name="specification" type="gmd:CI_Citation_PropertyType"/>
+					<xs:element name="explanation" type="gco:CharacterString_PropertyType"/>
+					<xs:element name="pass" type="gco:Boolean_PropertyType"/>
+				</xs:sequence>
+			</xs:extension>
+		</xs:complexContent>
+	</xs:complexType>
+	<!-- ........................................................................ -->
+	<xs:element name="DQ_ConformanceResult" type="gmd:DQ_ConformanceResult_Type" substitutionGroup="gmd:AbstractDQ_Result"/>
+	<!-- ........................................................................ -->
+	<xs:complexType name="DQ_ConformanceResult_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gmd:DQ_ConformanceResult"/>
+		</xs:sequence>
+		<xs:attributeGroup ref="gco:ObjectReference"/>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+	<xs:complexType name="DQ_QuantitativeResult_Type">
+		<xs:annotation>
+			<xs:documentation>Quantitative_conformance_measure from Quality Procedures.  -  - Renamed to remove implied use limitation -  - OCL - -- result is type specified by valueDomain - result.tupleType = valueDomain</xs:documentation>
+		</xs:annotation>
+		<xs:complexContent>
+			<xs:extension base="gmd:AbstractDQ_Result_Type">
+				<xs:sequence>
+					<xs:element name="valueType" type="gco:RecordType_PropertyType" minOccurs="0"/>
+					<xs:element name="valueUnit" type="gco:UnitOfMeasure_PropertyType"/>
+					<xs:element name="errorStatistic" type="gco:CharacterString_PropertyType" minOccurs="0"/>
+					<xs:element name="value" type="gco:Record_PropertyType" maxOccurs="unbounded"/>
+				</xs:sequence>
+			</xs:extension>
+		</xs:complexContent>
+	</xs:complexType>
+	<!-- ........................................................................ -->
+	<xs:element name="DQ_QuantitativeResult" type="gmd:DQ_QuantitativeResult_Type" substitutionGroup="gmd:AbstractDQ_Result"/>
+	<!-- ........................................................................ -->
+	<xs:complexType name="DQ_QuantitativeResult_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gmd:DQ_QuantitativeResult"/>
+		</xs:sequence>
+		<xs:attributeGroup ref="gco:ObjectReference"/>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+	<xs:complexType name="AbstractDQ_Result_Type" abstract="true">
+		<xs:complexContent>
+			<xs:extension base="gco:AbstractObject_Type">
+				<xs:sequence/>
+			</xs:extension>
+		</xs:complexContent>
+	</xs:complexType>
+	<!-- ........................................................................ -->
+	<xs:element name="AbstractDQ_Result" type="gmd:AbstractDQ_Result_Type" abstract="true"/>
+	<!-- ........................................................................ -->
+	<xs:complexType name="DQ_Result_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gmd:AbstractDQ_Result"/>
+		</xs:sequence>
+		<xs:attributeGroup ref="gco:ObjectReference"/>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+	<xs:complexType name="DQ_TemporalValidity_Type">
+		<xs:complexContent>
+			<xs:extension base="gmd:AbstractDQ_TemporalAccuracy_Type"/>
+		</xs:complexContent>
+	</xs:complexType>
+	<!-- ........................................................................ -->
+	<xs:element name="DQ_TemporalValidity" type="gmd:DQ_TemporalValidity_Type" substitutionGroup="gmd:AbstractDQ_TemporalAccuracy"/>
+	<!-- ........................................................................ -->
+	<xs:complexType name="DQ_TemporalValidity_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gmd:DQ_TemporalValidity"/>
+		</xs:sequence>
+		<xs:attributeGroup ref="gco:ObjectReference"/>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+	<xs:complexType name="DQ_TemporalConsistency_Type">
+		<xs:complexContent>
+			<xs:extension base="gmd:AbstractDQ_TemporalAccuracy_Type"/>
+		</xs:complexContent>
+	</xs:complexType>
+	<!-- ........................................................................ -->
+	<xs:element name="DQ_TemporalConsistency" type="gmd:DQ_TemporalConsistency_Type" substitutionGroup="gmd:AbstractDQ_TemporalAccuracy"/>
+	<!-- ........................................................................ -->
+	<xs:complexType name="DQ_TemporalConsistency_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gmd:DQ_TemporalConsistency"/>
+		</xs:sequence>
+		<xs:attributeGroup ref="gco:ObjectReference"/>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+	<xs:complexType name="DQ_AccuracyOfATimeMeasurement_Type">
+		<xs:complexContent>
+			<xs:extension base="gmd:AbstractDQ_TemporalAccuracy_Type"/>
+		</xs:complexContent>
+	</xs:complexType>
+	<!-- ........................................................................ -->
+	<xs:element name="DQ_AccuracyOfATimeMeasurement" type="gmd:DQ_AccuracyOfATimeMeasurement_Type" substitutionGroup="gmd:AbstractDQ_TemporalAccuracy"/>
+	<!-- ........................................................................ -->
+	<xs:complexType name="DQ_AccuracyOfATimeMeasurement_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gmd:DQ_AccuracyOfATimeMeasurement"/>
+		</xs:sequence>
+		<xs:attributeGroup ref="gco:ObjectReference"/>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+	<xs:complexType name="DQ_QuantitativeAttributeAccuracy_Type">
+		<xs:complexContent>
+			<xs:extension base="gmd:AbstractDQ_ThematicAccuracy_Type"/>
+		</xs:complexContent>
+	</xs:complexType>
+	<!-- ........................................................................ -->
+	<xs:element name="DQ_QuantitativeAttributeAccuracy" type="gmd:DQ_QuantitativeAttributeAccuracy_Type" substitutionGroup="gmd:AbstractDQ_ThematicAccuracy"/>
+	<!-- ........................................................................ -->
+	<xs:complexType name="DQ_QuantitativeAttributeAccuracy_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gmd:DQ_QuantitativeAttributeAccuracy"/>
+		</xs:sequence>
+		<xs:attributeGroup ref="gco:ObjectReference"/>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+	<xs:complexType name="DQ_NonQuantitativeAttributeAccuracy_Type">
+		<xs:complexContent>
+			<xs:extension base="gmd:AbstractDQ_ThematicAccuracy_Type"/>
+		</xs:complexContent>
+	</xs:complexType>
+	<!-- ........................................................................ -->
+	<xs:element name="DQ_NonQuantitativeAttributeAccuracy" type="gmd:DQ_NonQuantitativeAttributeAccuracy_Type" substitutionGroup="gmd:AbstractDQ_ThematicAccuracy"/>
+	<!-- ........................................................................ -->
+	<xs:complexType name="DQ_NonQuantitativeAttributeAccuracy_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gmd:DQ_NonQuantitativeAttributeAccuracy"/>
+		</xs:sequence>
+		<xs:attributeGroup ref="gco:ObjectReference"/>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+	<xs:complexType name="DQ_ThematicClassificationCorrectness_Type">
+		<xs:complexContent>
+			<xs:extension base="gmd:AbstractDQ_ThematicAccuracy_Type"/>
+		</xs:complexContent>
+	</xs:complexType>
+	<!-- ........................................................................ -->
+	<xs:element name="DQ_ThematicClassificationCorrectness" type="gmd:DQ_ThematicClassificationCorrectness_Type" substitutionGroup="gmd:AbstractDQ_ThematicAccuracy"/>
+	<!-- ........................................................................ -->
+	<xs:complexType name="DQ_ThematicClassificationCorrectness_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gmd:DQ_ThematicClassificationCorrectness"/>
+		</xs:sequence>
+		<xs:attributeGroup ref="gco:ObjectReference"/>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+	<xs:complexType name="DQ_RelativeInternalPositionalAccuracy_Type">
+		<xs:complexContent>
+			<xs:extension base="gmd:AbstractDQ_PositionalAccuracy_Type"/>
+		</xs:complexContent>
+	</xs:complexType>
+	<!-- ........................................................................ -->
+	<xs:element name="DQ_RelativeInternalPositionalAccuracy" type="gmd:DQ_RelativeInternalPositionalAccuracy_Type" substitutionGroup="gmd:AbstractDQ_PositionalAccuracy"/>
+	<!-- ........................................................................ -->
+	<xs:complexType name="DQ_RelativeInternalPositionalAccuracy_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gmd:DQ_RelativeInternalPositionalAccuracy"/>
+		</xs:sequence>
+		<xs:attributeGroup ref="gco:ObjectReference"/>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+	<xs:complexType name="DQ_GriddedDataPositionalAccuracy_Type">
+		<xs:complexContent>
+			<xs:extension base="gmd:AbstractDQ_PositionalAccuracy_Type"/>
+		</xs:complexContent>
+	</xs:complexType>
+	<!-- ........................................................................ -->
+	<xs:element name="DQ_GriddedDataPositionalAccuracy" type="gmd:DQ_GriddedDataPositionalAccuracy_Type" substitutionGroup="gmd:AbstractDQ_PositionalAccuracy"/>
+	<!-- ........................................................................ -->
+	<xs:complexType name="DQ_GriddedDataPositionalAccuracy_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gmd:DQ_GriddedDataPositionalAccuracy"/>
+		</xs:sequence>
+		<xs:attributeGroup ref="gco:ObjectReference"/>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+	<xs:complexType name="DQ_AbsoluteExternalPositionalAccuracy_Type">
+		<xs:complexContent>
+			<xs:extension base="gmd:AbstractDQ_PositionalAccuracy_Type"/>
+		</xs:complexContent>
+	</xs:complexType>
+	<!-- ........................................................................ -->
+	<xs:element name="DQ_AbsoluteExternalPositionalAccuracy" type="gmd:DQ_AbsoluteExternalPositionalAccuracy_Type" substitutionGroup="gmd:AbstractDQ_PositionalAccuracy"/>
+	<!-- ........................................................................ -->
+	<xs:complexType name="DQ_AbsoluteExternalPositionalAccuracy_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gmd:DQ_AbsoluteExternalPositionalAccuracy"/>
+		</xs:sequence>
+		<xs:attributeGroup ref="gco:ObjectReference"/>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+	<xs:complexType name="DQ_TopologicalConsistency_Type">
+		<xs:complexContent>
+			<xs:extension base="gmd:AbstractDQ_LogicalConsistency_Type"/>
+		</xs:complexContent>
+	</xs:complexType>
+	<!-- ........................................................................ -->
+	<xs:element name="DQ_TopologicalConsistency" type="gmd:DQ_TopologicalConsistency_Type" substitutionGroup="gmd:AbstractDQ_LogicalConsistency"/>
+	<!-- ........................................................................ -->
+	<xs:complexType name="DQ_TopologicalConsistency_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gmd:DQ_TopologicalConsistency"/>
+		</xs:sequence>
+		<xs:attributeGroup ref="gco:ObjectReference"/>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+	<xs:complexType name="DQ_FormatConsistency_Type">
+		<xs:complexContent>
+			<xs:extension base="gmd:AbstractDQ_LogicalConsistency_Type"/>
+		</xs:complexContent>
+	</xs:complexType>
+	<!-- ........................................................................ -->
+	<xs:element name="DQ_FormatConsistency" type="gmd:DQ_FormatConsistency_Type" substitutionGroup="gmd:AbstractDQ_LogicalConsistency"/>
+	<!-- ........................................................................ -->
+	<xs:complexType name="DQ_FormatConsistency_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gmd:DQ_FormatConsistency"/>
+		</xs:sequence>
+		<xs:attributeGroup ref="gco:ObjectReference"/>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+	<xs:complexType name="DQ_DomainConsistency_Type">
+		<xs:complexContent>
+			<xs:extension base="gmd:AbstractDQ_LogicalConsistency_Type"/>
+		</xs:complexContent>
+	</xs:complexType>
+	<!-- ........................................................................ -->
+	<xs:element name="DQ_DomainConsistency" type="gmd:DQ_DomainConsistency_Type" substitutionGroup="gmd:AbstractDQ_LogicalConsistency"/>
+	<!-- ........................................................................ -->
+	<xs:complexType name="DQ_DomainConsistency_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gmd:DQ_DomainConsistency"/>
+		</xs:sequence>
+		<xs:attributeGroup ref="gco:ObjectReference"/>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+	<xs:complexType name="DQ_ConceptualConsistency_Type">
+		<xs:complexContent>
+			<xs:extension base="gmd:AbstractDQ_LogicalConsistency_Type"/>
+		</xs:complexContent>
+	</xs:complexType>
+	<!-- ........................................................................ -->
+	<xs:element name="DQ_ConceptualConsistency" type="gmd:DQ_ConceptualConsistency_Type" substitutionGroup="gmd:AbstractDQ_LogicalConsistency"/>
+	<!-- ........................................................................ -->
+	<xs:complexType name="DQ_ConceptualConsistency_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gmd:DQ_ConceptualConsistency"/>
+		</xs:sequence>
+		<xs:attributeGroup ref="gco:ObjectReference"/>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+	<xs:complexType name="DQ_CompletenessOmission_Type">
+		<xs:complexContent>
+			<xs:extension base="gmd:AbstractDQ_Completeness_Type"/>
+		</xs:complexContent>
+	</xs:complexType>
+	<!-- ........................................................................ -->
+	<xs:element name="DQ_CompletenessOmission" type="gmd:DQ_CompletenessOmission_Type" substitutionGroup="gmd:AbstractDQ_Completeness"/>
+	<!-- ........................................................................ -->
+	<xs:complexType name="DQ_CompletenessOmission_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gmd:DQ_CompletenessOmission"/>
+		</xs:sequence>
+		<xs:attributeGroup ref="gco:ObjectReference"/>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+	<xs:complexType name="DQ_CompletenessCommission_Type">
+		<xs:complexContent>
+			<xs:extension base="gmd:AbstractDQ_Completeness_Type"/>
+		</xs:complexContent>
+	</xs:complexType>
+	<!-- ........................................................................ -->
+	<xs:element name="DQ_CompletenessCommission" type="gmd:DQ_CompletenessCommission_Type" substitutionGroup="gmd:AbstractDQ_Completeness"/>
+	<!-- ........................................................................ -->
+	<xs:complexType name="DQ_CompletenessCommission_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gmd:DQ_CompletenessCommission"/>
+		</xs:sequence>
+		<xs:attributeGroup ref="gco:ObjectReference"/>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+	<xs:complexType name="AbstractDQ_TemporalAccuracy_Type" abstract="true">
+		<xs:complexContent>
+			<xs:extension base="gmd:AbstractDQ_Element_Type"/>
+		</xs:complexContent>
+	</xs:complexType>
+	<!-- ........................................................................ -->
+	<xs:element name="AbstractDQ_TemporalAccuracy" type="gmd:AbstractDQ_TemporalAccuracy_Type" abstract="true" substitutionGroup="gmd:AbstractDQ_Element"/>
+	<!-- ........................................................................ -->
+	<xs:complexType name="DQ_TemporalAccuracy_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gmd:AbstractDQ_TemporalAccuracy"/>
+		</xs:sequence>
+		<xs:attributeGroup ref="gco:ObjectReference"/>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+	<xs:complexType name="AbstractDQ_ThematicAccuracy_Type" abstract="true">
+		<xs:complexContent>
+			<xs:extension base="gmd:AbstractDQ_Element_Type"/>
+		</xs:complexContent>
+	</xs:complexType>
+	<!-- ........................................................................ -->
+	<xs:element name="AbstractDQ_ThematicAccuracy" type="gmd:AbstractDQ_ThematicAccuracy_Type" abstract="true" substitutionGroup="gmd:AbstractDQ_Element"/>
+	<!-- ........................................................................ -->
+	<xs:complexType name="DQ_ThematicAccuracy_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gmd:AbstractDQ_ThematicAccuracy"/>
+		</xs:sequence>
+		<xs:attributeGroup ref="gco:ObjectReference"/>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+	<xs:complexType name="AbstractDQ_PositionalAccuracy_Type" abstract="true">
+		<xs:complexContent>
+			<xs:extension base="gmd:AbstractDQ_Element_Type"/>
+		</xs:complexContent>
+	</xs:complexType>
+	<!-- ........................................................................ -->
+	<xs:element name="AbstractDQ_PositionalAccuracy" type="gmd:AbstractDQ_PositionalAccuracy_Type" abstract="true" substitutionGroup="gmd:AbstractDQ_Element"/>
+	<!-- ........................................................................ -->
+	<xs:complexType name="DQ_PositionalAccuracy_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gmd:AbstractDQ_PositionalAccuracy"/>
+		</xs:sequence>
+		<xs:attributeGroup ref="gco:ObjectReference"/>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+	<xs:complexType name="AbstractDQ_LogicalConsistency_Type" abstract="true">
+		<xs:complexContent>
+			<xs:extension base="gmd:AbstractDQ_Element_Type"/>
+		</xs:complexContent>
+	</xs:complexType>
+	<!-- ........................................................................ -->
+	<xs:element name="AbstractDQ_LogicalConsistency" type="gmd:AbstractDQ_LogicalConsistency_Type" abstract="true" substitutionGroup="gmd:AbstractDQ_Element"/>
+	<!-- ........................................................................ -->
+	<xs:complexType name="DQ_LogicalConsistency_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gmd:AbstractDQ_LogicalConsistency"/>
+		</xs:sequence>
+		<xs:attributeGroup ref="gco:ObjectReference"/>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+	<xs:complexType name="AbstractDQ_Completeness_Type" abstract="true">
+		<xs:complexContent>
+			<xs:extension base="gmd:AbstractDQ_Element_Type"/>
+		</xs:complexContent>
+	</xs:complexType>
+	<!-- ........................................................................ -->
+	<xs:element name="AbstractDQ_Completeness" type="gmd:AbstractDQ_Completeness_Type" abstract="true" substitutionGroup="gmd:AbstractDQ_Element"/>
+	<!-- ........................................................................ -->
+	<xs:complexType name="DQ_Completeness_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gmd:AbstractDQ_Completeness"/>
+		</xs:sequence>
+		<xs:attributeGroup ref="gco:ObjectReference"/>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+	<xs:complexType name="AbstractDQ_Element_Type" abstract="true">
+		<xs:complexContent>
+			<xs:extension base="gco:AbstractObject_Type">
+				<xs:sequence>
+					<xs:element name="nameOfMeasure" type="gco:CharacterString_PropertyType" minOccurs="0" maxOccurs="unbounded"/>
+					<xs:element name="measureIdentification" type="gmd:MD_Identifier_PropertyType" minOccurs="0"/>
+					<xs:element name="measureDescription" type="gco:CharacterString_PropertyType" minOccurs="0"/>
+					<xs:element name="evaluationMethodType" type="gmd:DQ_EvaluationMethodTypeCode_PropertyType" minOccurs="0"/>
+					<xs:element name="evaluationMethodDescription" type="gco:CharacterString_PropertyType" minOccurs="0"/>
+					<xs:element name="evaluationProcedure" type="gmd:CI_Citation_PropertyType" minOccurs="0"/>
+					<xs:element name="dateTime" type="gco:DateTime_PropertyType" minOccurs="0" maxOccurs="unbounded"/>
+					<xs:element name="result" type="gmd:DQ_Result_PropertyType" maxOccurs="2"/>
+				</xs:sequence>
+			</xs:extension>
+		</xs:complexContent>
+	</xs:complexType>
+	<!-- ........................................................................ -->
+	<xs:element name="AbstractDQ_Element" type="gmd:AbstractDQ_Element_Type" abstract="true"/>
+	<!-- ........................................................................ -->
+	<xs:complexType name="DQ_Element_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gmd:AbstractDQ_Element"/>
+		</xs:sequence>
+		<xs:attributeGroup ref="gco:ObjectReference"/>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+	<xs:complexType name="DQ_DataQuality_Type">
+		<xs:complexContent>
+			<xs:extension base="gco:AbstractObject_Type">
+				<xs:sequence>
+					<xs:element name="scope" type="gmd:DQ_Scope_PropertyType"/>
+					<xs:element name="report" type="gmd:DQ_Element_PropertyType" minOccurs="0" maxOccurs="unbounded"/>
+					<xs:element name="lineage" type="gmd:LI_Lineage_PropertyType" minOccurs="0"/>
+				</xs:sequence>
+			</xs:extension>
+		</xs:complexContent>
+	</xs:complexType>
+	<!-- ........................................................................ -->
+	<xs:element name="DQ_DataQuality" type="gmd:DQ_DataQuality_Type"/>
+	<!-- ........................................................................ -->
+	<xs:complexType name="DQ_DataQuality_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gmd:DQ_DataQuality"/>
+		</xs:sequence>
+		<xs:attributeGroup ref="gco:ObjectReference"/>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+	<xs:complexType name="DQ_Scope_Type">
+		<xs:complexContent>
+			<xs:extension base="gco:AbstractObject_Type">
+				<xs:sequence>
+					<xs:element name="level" type="gmd:MD_ScopeCode_PropertyType"/>
+					<xs:element name="extent" type="gmd:EX_Extent_PropertyType" minOccurs="0"/>
+					<xs:element name="levelDescription" type="gmd:MD_ScopeDescription_PropertyType" minOccurs="0" maxOccurs="unbounded"/>
+				</xs:sequence>
+			</xs:extension>
+		</xs:complexContent>
+	</xs:complexType>
+	<!-- ........................................................................ -->
+	<xs:element name="DQ_Scope" type="gmd:DQ_Scope_Type"/>
+	<!-- ........................................................................ -->
+	<xs:complexType name="DQ_Scope_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gmd:DQ_Scope"/>
+		</xs:sequence>
+		<xs:attributeGroup ref="gco:ObjectReference"/>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+	<!-- ........................................................................ -->
+	<xs:element name="DQ_EvaluationMethodTypeCode" type="gco:CodeListValue_Type" substitutionGroup="gco:CharacterString"/>
+	<!-- ........................................................................ -->
+	<xs:complexType name="DQ_EvaluationMethodTypeCode_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gmd:DQ_EvaluationMethodTypeCode"/>
+		</xs:sequence>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+</xs:schema>
diff --git a/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gmd/distribution.xsd b/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gmd/distribution.xsd
new file mode 100644
index 0000000..380ceca
--- /dev/null
+++ b/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gmd/distribution.xsd
@@ -0,0 +1,203 @@
+<?xml version="1.0" encoding="utf-8"?>
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:gco="http://www.isotc211.org/2005/gco" xmlns:gmd="http://www.isotc211.org/2005/gmd" targetNamespace="http://www.isotc211.org/2005/gmd" elementFormDefault="qualified" version="2012-07-13">
+	<!-- ================================= Annotation ================================ -->
+	<xs:annotation>
+		<xs:documentation>Geographic MetaData (GMD) extensible markup language is a component of the XML Schema Implementation of Geographic Information Metadata documented in ISO/TS 19139:2007. GMD includes all the definitions of http://www.isotc211.org/2005/gmd namespace. The root document of this namespace is the file gmd.xsd. This distribution.xsd schema implements the UML conceptual schema defined in A.2.10 of ISO 19115:2003. It contains the implementation of the following classes: MD_Med [...]
+	</xs:annotation>
+	<!-- ================================== Imports ================================== -->
+	<xs:import namespace="http://www.isotc211.org/2005/gco" schemaLocation="../gco/gco.xsd"/>
+	<xs:include schemaLocation="gmd.xsd"/>
+	<xs:include schemaLocation="citation.xsd"/>
+	<!-- ########################################################################### -->
+	<!-- ########################################################################### -->
+	<!-- ================================== Classes ================================= -->
+	<xs:complexType name="MD_Medium_Type">
+		<xs:annotation>
+			<xs:documentation>Information about the media on which the data can be distributed</xs:documentation>
+		</xs:annotation>
+		<xs:complexContent>
+			<xs:extension base="gco:AbstractObject_Type">
+				<xs:sequence>
+					<xs:element name="name" type="gmd:MD_MediumNameCode_PropertyType" minOccurs="0"/>
+					<xs:element name="density" type="gco:Real_PropertyType" minOccurs="0" maxOccurs="unbounded"/>
+					<xs:element name="densityUnits" type="gco:CharacterString_PropertyType" minOccurs="0"/>
+					<xs:element name="volumes" type="gco:Integer_PropertyType" minOccurs="0"/>
+					<xs:element name="mediumFormat" type="gmd:MD_MediumFormatCode_PropertyType" minOccurs="0" maxOccurs="unbounded"/>
+					<xs:element name="mediumNote" type="gco:CharacterString_PropertyType" minOccurs="0"/>
+				</xs:sequence>
+			</xs:extension>
+		</xs:complexContent>
+	</xs:complexType>
+	<!-- ........................................................................ -->
+	<xs:element name="MD_Medium" type="gmd:MD_Medium_Type"/>
+	<!-- ........................................................................ -->
+	<xs:complexType name="MD_Medium_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gmd:MD_Medium"/>
+		</xs:sequence>
+		<xs:attributeGroup ref="gco:ObjectReference"/>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+	<xs:complexType name="MD_DigitalTransferOptions_Type">
+		<xs:annotation>
+			<xs:documentation>Technical means and media by which a dataset is obtained from the distributor</xs:documentation>
+		</xs:annotation>
+		<xs:complexContent>
+			<xs:extension base="gco:AbstractObject_Type">
+				<xs:sequence>
+					<xs:element name="unitsOfDistribution" type="gco:CharacterString_PropertyType" minOccurs="0"/>
+					<xs:element name="transferSize" type="gco:Real_PropertyType" minOccurs="0"/>
+					<xs:element name="onLine" type="gmd:CI_OnlineResource_PropertyType" minOccurs="0" maxOccurs="unbounded"/>
+					<xs:element name="offLine" type="gmd:MD_Medium_PropertyType" minOccurs="0"/>
+				</xs:sequence>
+			</xs:extension>
+		</xs:complexContent>
+	</xs:complexType>
+	<!-- ........................................................................ -->
+	<xs:element name="MD_DigitalTransferOptions" type="gmd:MD_DigitalTransferOptions_Type"/>
+	<!-- ........................................................................ -->
+	<xs:complexType name="MD_DigitalTransferOptions_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gmd:MD_DigitalTransferOptions"/>
+		</xs:sequence>
+		<xs:attributeGroup ref="gco:ObjectReference"/>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+	<xs:complexType name="MD_StandardOrderProcess_Type">
+		<xs:annotation>
+			<xs:documentation>Common ways in which the dataset may be obtained or received, and related instructions and fee information</xs:documentation>
+		</xs:annotation>
+		<xs:complexContent>
+			<xs:extension base="gco:AbstractObject_Type">
+				<xs:sequence>
+					<xs:element name="fees" type="gco:CharacterString_PropertyType" minOccurs="0"/>
+					<xs:element name="plannedAvailableDateTime" type="gco:DateTime_PropertyType" minOccurs="0"/>
+					<xs:element name="orderingInstructions" type="gco:CharacterString_PropertyType" minOccurs="0"/>
+					<xs:element name="turnaround" type="gco:CharacterString_PropertyType" minOccurs="0"/>
+				</xs:sequence>
+			</xs:extension>
+		</xs:complexContent>
+	</xs:complexType>
+	<!-- ........................................................................ -->
+	<xs:element name="MD_StandardOrderProcess" type="gmd:MD_StandardOrderProcess_Type"/>
+	<!-- ........................................................................ -->
+	<xs:complexType name="MD_StandardOrderProcess_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gmd:MD_StandardOrderProcess"/>
+		</xs:sequence>
+		<xs:attributeGroup ref="gco:ObjectReference"/>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+	<xs:complexType name="MD_Distributor_Type">
+		<xs:annotation>
+			<xs:documentation>Information about the distributor</xs:documentation>
+		</xs:annotation>
+		<xs:complexContent>
+			<xs:extension base="gco:AbstractObject_Type">
+				<xs:sequence>
+					<xs:element name="distributorContact" type="gmd:CI_ResponsibleParty_PropertyType"/>
+					<xs:element name="distributionOrderProcess" type="gmd:MD_StandardOrderProcess_PropertyType" minOccurs="0" maxOccurs="unbounded"/>
+					<xs:element name="distributorFormat" type="gmd:MD_Format_PropertyType" minOccurs="0" maxOccurs="unbounded"/>
+					<xs:element name="distributorTransferOptions" type="gmd:MD_DigitalTransferOptions_PropertyType" minOccurs="0" maxOccurs="unbounded"/>
+				</xs:sequence>
+			</xs:extension>
+		</xs:complexContent>
+	</xs:complexType>
+	<!-- ........................................................................ -->
+	<xs:element name="MD_Distributor" type="gmd:MD_Distributor_Type"/>
+	<!-- ........................................................................ -->
+	<xs:complexType name="MD_Distributor_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gmd:MD_Distributor"/>
+		</xs:sequence>
+		<xs:attributeGroup ref="gco:ObjectReference"/>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+	<xs:complexType name="MD_Distribution_Type">
+		<xs:annotation>
+			<xs:documentation>Information about the distributor of and options for obtaining the dataset</xs:documentation>
+		</xs:annotation>
+		<xs:complexContent>
+			<xs:extension base="gco:AbstractObject_Type">
+				<xs:sequence>
+					<xs:element name="distributionFormat" type="gmd:MD_Format_PropertyType" minOccurs="0" maxOccurs="unbounded"/>
+					<xs:element name="distributor" type="gmd:MD_Distributor_PropertyType" minOccurs="0" maxOccurs="unbounded"/>
+					<xs:element name="transferOptions" type="gmd:MD_DigitalTransferOptions_PropertyType" minOccurs="0" maxOccurs="unbounded"/>
+				</xs:sequence>
+			</xs:extension>
+		</xs:complexContent>
+	</xs:complexType>
+	<!-- ........................................................................ -->
+	<xs:element name="MD_Distribution" type="gmd:MD_Distribution_Type"/>
+	<!-- ........................................................................ -->
+	<xs:complexType name="MD_Distribution_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gmd:MD_Distribution"/>
+		</xs:sequence>
+		<xs:attributeGroup ref="gco:ObjectReference"/>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+	<xs:complexType name="MD_Format_Type">
+		<xs:annotation>
+			<xs:documentation>Description of the form of the data to be distributed</xs:documentation>
+		</xs:annotation>
+		<xs:complexContent>
+			<xs:extension base="gco:AbstractObject_Type">
+				<xs:sequence>
+					<xs:element name="name" type="gco:CharacterString_PropertyType"/>
+					<xs:element name="version" type="gco:CharacterString_PropertyType"/>
+					<xs:element name="amendmentNumber" type="gco:CharacterString_PropertyType" minOccurs="0"/>
+					<xs:element name="specification" type="gco:CharacterString_PropertyType" minOccurs="0"/>
+					<xs:element name="fileDecompressionTechnique" type="gco:CharacterString_PropertyType" minOccurs="0"/>
+					<xs:element name="formatDistributor" type="gmd:MD_Distributor_PropertyType" minOccurs="0" maxOccurs="unbounded"/>
+				</xs:sequence>
+			</xs:extension>
+		</xs:complexContent>
+	</xs:complexType>
+	<!-- ........................................................................ -->
+	<xs:element name="MD_Format" type="gmd:MD_Format_Type"/>
+	<!-- ........................................................................ -->
+	<xs:complexType name="MD_Format_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gmd:MD_Format"/>
+		</xs:sequence>
+		<xs:attributeGroup ref="gco:ObjectReference"/>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+	<!-- ........................................................................ -->
+	<xs:element name="MD_DistributionUnits" type="gco:CodeListValue_Type" substitutionGroup="gco:CharacterString"/>
+	<!-- ........................................................................ -->
+	<xs:complexType name="MD_DistributionUnits_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gmd:MD_DistributionUnits"/>
+		</xs:sequence>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+	<!-- ........................................................................ -->
+	<xs:element name="MD_MediumFormatCode" type="gco:CodeListValue_Type" substitutionGroup="gco:CharacterString"/>
+	<!-- ........................................................................ -->
+	<xs:complexType name="MD_MediumFormatCode_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gmd:MD_MediumFormatCode"/>
+		</xs:sequence>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+	<!-- ........................................................................ -->
+	<xs:element name="MD_MediumNameCode" type="gco:CodeListValue_Type" substitutionGroup="gco:CharacterString"/>
+	<!-- ........................................................................ -->
+	<xs:complexType name="MD_MediumNameCode_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gmd:MD_MediumNameCode"/>
+		</xs:sequence>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+</xs:schema>
diff --git a/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gmd/extent.xsd b/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gmd/extent.xsd
new file mode 100644
index 0000000..363da13
--- /dev/null
+++ b/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gmd/extent.xsd
@@ -0,0 +1,206 @@
+<?xml version="1.0" encoding="utf-8"?>
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:gsr="http://www.isotc211.org/2005/gsr" xmlns:gco="http://www.isotc211.org/2005/gco" xmlns:gts="http://www.isotc211.org/2005/gts" xmlns:gss="http://www.isotc211.org/2005/gss" xmlns:gmd="http://www.isotc211.org/2005/gmd" targetNamespace="http://www.isotc211.org/2005/gmd" elementFormDefault="qualified" version="2012-07-13">
+	<!-- ================================= Annotation ================================ -->
+	<xs:annotation>
+		<xs:documentation>Geographic MetaData (GMD) extensible markup language is a component of the XML Schema Implementation of Geographic Information Metadata documented in ISO/TS 19139:2007. GMD includes all the definitions of http://www.isotc211.org/2005/gmd namespace. The root document of this namespace is the file gmd.xsd. This extent.xsd schema implements the UML conceptual schema defined in A.3.1 of ISO 19115:2003 and the associated corrigendum. It contains the implementation of the f [...]
+	</xs:annotation>
+	<!-- ================================== Imports ================================== -->
+	<xs:import namespace="http://www.isotc211.org/2005/gss" schemaLocation="../gss/gss.xsd"/>
+	<xs:import namespace="http://www.isotc211.org/2005/gts" schemaLocation="../gts/gts.xsd"/>
+	<xs:import namespace="http://www.isotc211.org/2005/gco" schemaLocation="../gco/gco.xsd"/>
+	<xs:import namespace="http://www.isotc211.org/2005/gsr" schemaLocation="../gsr/gsr.xsd"/>
+	<xs:include schemaLocation="gmd.xsd"/>
+	<xs:include schemaLocation="referenceSystem.xsd"/>
+	<!-- ########################################################################### -->
+	<!-- ########################################################################### -->
+	<!-- ================================== Classes ================================= -->
+	<xs:complexType name="EX_TemporalExtent_Type">
+		<xs:annotation>
+			<xs:documentation>Time period covered by the content of the dataset</xs:documentation>
+		</xs:annotation>
+		<xs:complexContent>
+			<xs:extension base="gco:AbstractObject_Type">
+				<xs:sequence>
+					<xs:element name="extent" type="gts:TM_Primitive_PropertyType"/>
+				</xs:sequence>
+			</xs:extension>
+		</xs:complexContent>
+	</xs:complexType>
+	<!-- ........................................................................ -->
+	<xs:element name="EX_TemporalExtent" type="gmd:EX_TemporalExtent_Type"/>
+	<!-- ........................................................................ -->
+	<xs:complexType name="EX_TemporalExtent_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gmd:EX_TemporalExtent"/>
+		</xs:sequence>
+		<xs:attributeGroup ref="gco:ObjectReference"/>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+	<xs:complexType name="EX_VerticalExtent_Type">
+		<xs:annotation>
+			<xs:documentation>Vertical domain of dataset</xs:documentation>
+		</xs:annotation>
+		<xs:complexContent>
+			<xs:extension base="gco:AbstractObject_Type">
+				<xs:sequence>
+					<xs:element name="minimumValue" type="gco:Real_PropertyType"/>
+					<xs:element name="maximumValue" type="gco:Real_PropertyType"/>
+					<xs:element name="verticalCRS" type="gsr:SC_CRS_PropertyType"/>
+				</xs:sequence>
+			</xs:extension>
+		</xs:complexContent>
+	</xs:complexType>
+	<!-- ........................................................................ -->
+	<xs:element name="EX_VerticalExtent" type="gmd:EX_VerticalExtent_Type"/>
+	<!-- ........................................................................ -->
+	<xs:complexType name="EX_VerticalExtent_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gmd:EX_VerticalExtent"/>
+		</xs:sequence>
+		<xs:attributeGroup ref="gco:ObjectReference"/>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+	<xs:complexType name="EX_BoundingPolygon_Type">
+		<xs:annotation>
+			<xs:documentation>Boundary enclosing the dataset expressed as the closed set of (x,y) coordinates of the polygon (last point replicates first point)</xs:documentation>
+		</xs:annotation>
+		<xs:complexContent>
+			<xs:extension base="gmd:AbstractEX_GeographicExtent_Type">
+				<xs:sequence>
+					<xs:element name="polygon" type="gss:GM_Object_PropertyType" maxOccurs="unbounded"/>
+				</xs:sequence>
+			</xs:extension>
+		</xs:complexContent>
+	</xs:complexType>
+	<!-- ........................................................................ -->
+	<xs:element name="EX_BoundingPolygon" type="gmd:EX_BoundingPolygon_Type" substitutionGroup="gmd:AbstractEX_GeographicExtent"/>
+	<!-- ........................................................................ -->
+	<xs:complexType name="EX_BoundingPolygon_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gmd:EX_BoundingPolygon"/>
+		</xs:sequence>
+		<xs:attributeGroup ref="gco:ObjectReference"/>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+	<xs:complexType name="EX_Extent_Type">
+		<xs:annotation>
+			<xs:documentation>Information about spatial, vertical, and temporal extent</xs:documentation>
+		</xs:annotation>
+		<xs:complexContent>
+			<xs:extension base="gco:AbstractObject_Type">
+				<xs:sequence>
+					<xs:element name="description" type="gco:CharacterString_PropertyType" minOccurs="0"/>
+					<xs:element name="geographicElement" type="gmd:EX_GeographicExtent_PropertyType" minOccurs="0" maxOccurs="unbounded"/>
+					<xs:element name="temporalElement" type="gmd:EX_TemporalExtent_PropertyType" minOccurs="0" maxOccurs="unbounded"/>
+					<xs:element name="verticalElement" type="gmd:EX_VerticalExtent_PropertyType" minOccurs="0" maxOccurs="unbounded"/>
+				</xs:sequence>
+			</xs:extension>
+		</xs:complexContent>
+	</xs:complexType>
+	<!-- ........................................................................ -->
+	<xs:element name="EX_Extent" type="gmd:EX_Extent_Type"/>
+	<!-- ........................................................................ -->
+	<xs:complexType name="EX_Extent_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gmd:EX_Extent"/>
+		</xs:sequence>
+		<xs:attributeGroup ref="gco:ObjectReference"/>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+	<xs:complexType name="AbstractEX_GeographicExtent_Type" abstract="true">
+		<xs:annotation>
+			<xs:documentation>Geographic area of the dataset</xs:documentation>
+		</xs:annotation>
+		<xs:complexContent>
+			<xs:extension base="gco:AbstractObject_Type">
+				<xs:sequence>
+					<xs:element name="extentTypeCode" type="gco:Boolean_PropertyType" minOccurs="0"/>
+				</xs:sequence>
+			</xs:extension>
+		</xs:complexContent>
+	</xs:complexType>
+	<!-- ........................................................................ -->
+	<xs:element name="AbstractEX_GeographicExtent" type="gmd:AbstractEX_GeographicExtent_Type" abstract="true"/>
+	<!-- ........................................................................ -->
+	<xs:complexType name="EX_GeographicExtent_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gmd:AbstractEX_GeographicExtent"/>
+		</xs:sequence>
+		<xs:attributeGroup ref="gco:ObjectReference"/>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+	<xs:complexType name="EX_GeographicBoundingBox_Type">
+		<xs:annotation>
+			<xs:documentation>Geographic area of the entire dataset referenced to WGS 84</xs:documentation>
+		</xs:annotation>
+		<xs:complexContent>
+			<xs:extension base="gmd:AbstractEX_GeographicExtent_Type">
+				<xs:sequence>
+					<xs:element name="westBoundLongitude" type="gco:Decimal_PropertyType"/>
+					<xs:element name="eastBoundLongitude" type="gco:Decimal_PropertyType"/>
+					<xs:element name="southBoundLatitude" type="gco:Decimal_PropertyType"/>
+					<xs:element name="northBoundLatitude" type="gco:Decimal_PropertyType"/>
+				</xs:sequence>
+			</xs:extension>
+		</xs:complexContent>
+	</xs:complexType>
+	<!-- ........................................................................ -->
+	<xs:element name="EX_GeographicBoundingBox" type="gmd:EX_GeographicBoundingBox_Type" substitutionGroup="gmd:AbstractEX_GeographicExtent"/>
+	<!-- ........................................................................ -->
+	<xs:complexType name="EX_GeographicBoundingBox_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gmd:EX_GeographicBoundingBox"/>
+		</xs:sequence>
+		<xs:attributeGroup ref="gco:ObjectReference"/>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+	<xs:complexType name="EX_SpatialTemporalExtent_Type">
+		<xs:annotation>
+			<xs:documentation>Extent with respect to date and time</xs:documentation>
+		</xs:annotation>
+		<xs:complexContent>
+			<xs:extension base="gmd:EX_TemporalExtent_Type">
+				<xs:sequence>
+					<xs:element name="spatialExtent" type="gmd:EX_GeographicExtent_PropertyType" maxOccurs="unbounded"/>
+				</xs:sequence>
+			</xs:extension>
+		</xs:complexContent>
+	</xs:complexType>
+	<!-- ........................................................................ -->
+	<xs:element name="EX_SpatialTemporalExtent" type="gmd:EX_SpatialTemporalExtent_Type" substitutionGroup="gmd:EX_TemporalExtent"/>
+	<!-- ........................................................................ -->
+	<xs:complexType name="EX_SpatialTemporalExtent_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gmd:EX_SpatialTemporalExtent"/>
+		</xs:sequence>
+		<xs:attributeGroup ref="gco:ObjectReference"/>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+	<xs:complexType name="EX_GeographicDescription_Type">
+		<xs:complexContent>
+			<xs:extension base="gmd:AbstractEX_GeographicExtent_Type">
+				<xs:sequence>
+					<xs:element name="geographicIdentifier" type="gmd:MD_Identifier_PropertyType"/>
+				</xs:sequence>
+			</xs:extension>
+		</xs:complexContent>
+	</xs:complexType>
+	<!-- ........................................................................ -->
+	<xs:element name="EX_GeographicDescription" type="gmd:EX_GeographicDescription_Type" substitutionGroup="gmd:AbstractEX_GeographicExtent"/>
+	<!-- ........................................................................ -->
+	<xs:complexType name="EX_GeographicDescription_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gmd:EX_GeographicDescription"/>
+		</xs:sequence>
+		<xs:attributeGroup ref="gco:ObjectReference"/>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+</xs:schema>
diff --git a/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gmd/freeText.xsd b/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gmd/freeText.xsd
new file mode 100644
index 0000000..f552770
--- /dev/null
+++ b/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gmd/freeText.xsd
@@ -0,0 +1,123 @@
+<?xml version="1.0" encoding="utf-8"?>
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:gco="http://www.isotc211.org/2005/gco" xmlns:gmd="http://www.isotc211.org/2005/gmd" targetNamespace="http://www.isotc211.org/2005/gmd" elementFormDefault="qualified" version="2012-07-13">
+	<!-- ================================= Annotation ================================ -->
+	<xs:annotation>
+		<xs:documentation>Geographic MetaData (GMD) extensible markup language is a component of the XML Schema Implementation of Geographic Information Metadata documented in ISO/TS 19139:2007. GMD includes all the definitions of http://www.isotc211.org/2005/gmd namespace. The root document of this namespace is the file gmd.xsd. This freeText.xsd schema implements cultural and linguistic adaptability extensions defined in 7.3 of ISO/TS 19139:2007. This extension essentially formalizes the fre [...]
+	</xs:annotation>
+	<!-- ================================== Imports ================================== -->
+	<xs:import namespace="http://www.isotc211.org/2005/gco" schemaLocation="../gco/gco.xsd"/>
+	<xs:include schemaLocation="gmd.xsd"/>
+	<xs:include schemaLocation="identification.xsd"/>
+	<!-- ########################################################################### -->
+	<!-- ########################################################################### -->
+	<!-- ================================== Classes ================================= -->
+	<xs:complexType name="PT_FreeText_Type">
+		<xs:complexContent>
+			<xs:extension base="gco:AbstractObject_Type">
+				<xs:sequence>
+					<xs:element name="textGroup" type="gmd:LocalisedCharacterString_PropertyType" maxOccurs="unbounded"/>
+				</xs:sequence>
+			</xs:extension>
+		</xs:complexContent>
+	</xs:complexType>
+	<!-- ........................................................................ -->
+	<xs:element name="PT_FreeText" type="gmd:PT_FreeText_Type"/>
+	<!-- ........................................................................ -->
+	<xs:complexType name="PT_FreeText_PropertyType">
+		<xs:complexContent>
+			<xs:extension base="gco:CharacterString_PropertyType">
+				<xs:sequence minOccurs="0">
+					<xs:element ref="gmd:PT_FreeText"/>
+				</xs:sequence>
+			</xs:extension>
+		</xs:complexContent>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+	<xs:complexType name="PT_Locale_Type">
+		<xs:complexContent>
+			<xs:extension base="gco:AbstractObject_Type">
+				<xs:sequence>
+					<xs:element name="languageCode" type="gmd:LanguageCode_PropertyType"/>
+					<xs:element name="country" type="gmd:Country_PropertyType" minOccurs="0"/>
+					<xs:element name="characterEncoding" type="gmd:MD_CharacterSetCode_PropertyType"/>
+				</xs:sequence>
+			</xs:extension>
+		</xs:complexContent>
+	</xs:complexType>
+	<!-- ........................................................................ -->
+	<xs:element name="PT_Locale" type="gmd:PT_Locale_Type"/>
+	<!-- ........................................................................ -->
+	<xs:complexType name="PT_Locale_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gmd:PT_Locale"/>
+		</xs:sequence>
+		<xs:attributeGroup ref="gco:ObjectReference"/>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+	<xs:complexType name="LocalisedCharacterString_Type">
+		<xs:simpleContent>
+			<xs:extension base="xs:string">
+				<xs:attribute name="id" type="xs:ID"/>
+				<xs:attribute name="locale" type="xs:anyURI"/>
+			</xs:extension>
+		</xs:simpleContent>
+	</xs:complexType>
+	<!-- ........................................................................ -->
+	<xs:element name="LocalisedCharacterString" type="gmd:LocalisedCharacterString_Type" substitutionGroup="gco:CharacterString"/>
+	<!-- ........................................................................ -->
+	<xs:complexType name="LocalisedCharacterString_PropertyType">
+		<xs:complexContent>
+			<xs:extension base="gco:ObjectReference_PropertyType">
+				<xs:sequence minOccurs="0">
+					<xs:element ref="gmd:LocalisedCharacterString"/>
+				</xs:sequence>
+			</xs:extension>
+		</xs:complexContent>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+	<xs:complexType name="PT_LocaleContainer_Type">
+		<xs:sequence>
+			<xs:element name="description" type="gco:CharacterString_PropertyType"/>
+			<xs:element name="locale" type="gmd:PT_Locale_PropertyType"/>
+			<xs:element name="date" type="gmd:CI_Date_PropertyType" maxOccurs="unbounded"/>
+			<xs:element name="responsibleParty" type="gmd:CI_ResponsibleParty_PropertyType" maxOccurs="unbounded"/>
+			<xs:element name="localisedString" type="gmd:LocalisedCharacterString_PropertyType" maxOccurs="unbounded"/>
+		</xs:sequence>
+	</xs:complexType>
+	<!-- ........................................................................ -->
+	<xs:element name="PT_LocaleContainer" type="gmd:PT_LocaleContainer_Type"/>
+	<!-- ........................................................................ -->
+	<xs:complexType name="PT_LocaleContainer_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gmd:PT_LocaleContainer"/>
+		</xs:sequence>
+		<xs:attributeGroup ref="gco:ObjectReference"/>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+	<!-- =========================================================================== -->
+	<!-- =========================================================================== -->
+	<!-- =========================================================================== -->
+	<!-- ........................................................................ -->
+	<xs:element name="LanguageCode" type="gco:CodeListValue_Type" substitutionGroup="gco:CharacterString"/>
+	<!-- ........................................................................ -->
+	<xs:complexType name="LanguageCode_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gmd:LanguageCode"/>
+		</xs:sequence>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+	<!-- ........................................................................ -->
+	<xs:element name="Country" type="gco:CodeListValue_Type" substitutionGroup="gco:CharacterString"/>
+	<!-- ........................................................................ -->
+	<xs:complexType name="Country_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gmd:Country"/>
+		</xs:sequence>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+	<!--====EOF====-->
+</xs:schema>
diff --git a/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gmd/gmd.xsd b/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gmd/gmd.xsd
new file mode 100644
index 0000000..8037c8a
--- /dev/null
+++ b/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gmd/gmd.xsd
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+<xs:schema targetNamespace="http://www.isotc211.org/2005/gmd" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:gmd="http://www.isotc211.org/2005/gmd" version="2012-07-13">
+	<!-- ================================= Annotation ================================ -->
+	<xs:annotation>
+		<xs:documentation>Geographic MetaData (GMD) extensible markup language is a component of the XML Schema Implementation of Geographic Information Metadata documented in ISO/TS 19139:2007. GMD includes all the definitions of http://www.isotc211.org/2005/gmd namespace. The root document of this namespace is the file gmd.xsd.</xs:documentation>
+	</xs:annotation>
+	<!-- ================================== Imports ================================== -->
+	<xs:include schemaLocation="metadataApplication.xsd"/>
+	<!-- ########################################################################### -->
+	<!-- ########################################################################### -->
+	<!-- ================================== Classes ================================= -->
+</xs:schema>
diff --git a/tests/expected/suites_apiso_post_DescribeRecord.xml b/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gmd/identification.xsd
similarity index 58%
copy from tests/expected/suites_apiso_post_DescribeRecord.xml
copy to pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gmd/identification.xsd
index 74f2d33..1e23f57 100644
--- a/tests/expected/suites_apiso_post_DescribeRecord.xml
+++ b/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gmd/identification.xsd
@@ -1,17 +1,15 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- PYCSW_VERSION -->
-<csw:DescribeRecordResponse xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:inspire_common="http://inspire.ec.europa.eu/schemas/common/1.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dct="http://purl.org/dc/terms/" xmlns:ows="http://www.opengis.net/ows" xmlns:apiso="http://www.opengis.net/cat/csw/apiso/1.0" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xlink="http://www.w3.org/1999/xli [...]
-  <csw:SchemaComponent parentSchema="gmd.xsd" schemaLanguage="XMLSCHEMA" targetNamespace="http://www.isotc211.org/2005/gmd">
-    <xs:schema targetNamespace="http://www.isotc211.org/2005/gmd" elementFormDefault="qualified" version="0.1">
+<?xml version="1.0" encoding="utf-8"?>
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:gco="http://www.isotc211.org/2005/gco" xmlns:gmd="http://www.isotc211.org/2005/gmd" targetNamespace="http://www.isotc211.org/2005/gmd" elementFormDefault="qualified" version="2012-07-13">
 	<!-- ================================= Annotation ================================ -->
 	<xs:annotation>
-		<xs:documentation>This file was generated from ISO TC/211 UML class diagrams == 01-26-2005 12:40:05 ====== </xs:documentation>
+		<xs:documentation>Geographic MetaData (GMD) extensible markup language is a component of the XML Schema Implementation of Geographic Information Metadata documented in ISO/TS 19139:2007. GMD includes all the definitions of http://www.isotc211.org/2005/gmd namespace. The root document of this namespace is the file gmd.xsd. This identification.xsd schema implements the UML conceptual schema defined in A.2.2 of ISO 19115:2003. It contains the implementation of the following classes: MD_Id [...]
 	</xs:annotation>
 	<!-- ================================== Imports ================================== -->
 	<xs:import namespace="http://www.isotc211.org/2005/gco" schemaLocation="../gco/gco.xsd"/>
-	<xs:include schemaLocation="../gmd/constraints.xsd"/>
-	<xs:include schemaLocation="../gmd/distribution.xsd"/>
-	<xs:include schemaLocation="../gmd/maintenance.xsd"/>
+	<xs:include schemaLocation="gmd.xsd"/>
+	<xs:include schemaLocation="constraints.xsd"/>
+	<xs:include schemaLocation="distribution.xsd"/>
+	<xs:include schemaLocation="maintenance.xsd"/>
 	<!-- ########################################################################### -->
 	<!-- ########################################################################### -->
 	<!-- ================================== Classes ================================= -->
@@ -349,203 +347,3 @@
 	</xs:complexType>
 	<!-- =========================================================================== -->
 </xs:schema>
-  </csw:SchemaComponent>
-  <csw:SchemaComponent parentSchema="gmd.xsd" schemaLanguage="XMLSCHEMA" targetNamespace="http://www.isotc211.org/2005/gmd">
-    <xs:schema targetNamespace="http://www.isotc211.org/2005/srv" elementFormDefault="qualified" version="0.1">
-	<!-- ================================= Annotation ================================ -->
-	<xs:annotation>
-		<xs:documentation>This file was generated from ISO TC/211 UML class diagrams == 10-13-2006 11:14:04 ====== </xs:documentation>
-	</xs:annotation>
-	<!-- ================================== Imports ================================== -->
-	<xs:import namespace="http://www.isotc211.org/2005/gmd" schemaLocation="../gmd/identification.xsd"/>
-	<xs:import namespace="http://www.isotc211.org/2005/gco" schemaLocation="../gco/gco.xsd"/>
-	<xs:include schemaLocation="../srv/serviceModel.xsd"/>
-	<!-- ########################################################################### -->
-	<!-- ########################################################################### -->
-	<!-- ================================== Classes ================================= -->
-	<xs:complexType name="SV_Parameter_Type">
-		<xs:complexContent>
-			<xs:extension base="gco:AbstractObject_Type">
-				<xs:sequence>
-					<xs:element name="name" type="gco:MemberName_Type"/>
-					<xs:element name="direction" type="srv:SV_ParameterDirection_PropertyType" minOccurs="0"/>
-					<xs:element name="description" type="gco:CharacterString_PropertyType" minOccurs="0"/>
-					<xs:element name="optionality" type="gco:CharacterString_PropertyType"/>
-					<xs:element name="repeatability" type="gco:Boolean_PropertyType"/>
-					<xs:element name="valueType" type="gco:TypeName_PropertyType"/>
-				</xs:sequence>
-			</xs:extension>
-		</xs:complexContent>
-	</xs:complexType>
-	<!-- ........................................................................ -->
-	<xs:element name="SV_Parameter" type="srv:SV_Parameter_Type"/>
-	<!-- ........................................................................ -->
-	<xs:complexType name="SV_Parameter_PropertyType">
-		<xs:sequence>
-			<xs:element ref="srv:SV_Parameter" minOccurs="0"/>
-		</xs:sequence>
-		<xs:attributeGroup ref="gco:ObjectReference"/>
-		<xs:attribute ref="gco:nilReason"/>
-	</xs:complexType>
-	<!-- =========================================================================== -->
-	<xs:complexType name="SV_OperationMetadata_Type">
-		<xs:complexContent>
-			<xs:extension base="gco:AbstractObject_Type">
-				<xs:sequence>
-					<xs:element name="operationName" type="gco:CharacterString_PropertyType"/>
-					<xs:element name="DCP" type="srv:DCPList_PropertyType" maxOccurs="unbounded"/>
-					<xs:element name="operationDescription" type="gco:CharacterString_PropertyType" minOccurs="0"/>
-					<xs:element name="invocationName" type="gco:CharacterString_PropertyType" minOccurs="0"/>
-					<xs:element name="parameters" type="srv:SV_Parameter_PropertyType" minOccurs="0" maxOccurs="unbounded"/>
-					<xs:element name="connectPoint" type="gmd:CI_OnlineResource_PropertyType" maxOccurs="unbounded"/>
-					<xs:element name="dependsOn" type="srv:SV_OperationMetadata_PropertyType" minOccurs="0" maxOccurs="unbounded"/>
-				</xs:sequence>
-			</xs:extension>
-		</xs:complexContent>
-	</xs:complexType>
-	<!-- ........................................................................ -->
-	<xs:element name="SV_OperationMetadata" type="srv:SV_OperationMetadata_Type"/>
-	<!-- ........................................................................ -->
-	<xs:complexType name="SV_OperationMetadata_PropertyType">
-		<xs:sequence>
-			<xs:element ref="srv:SV_OperationMetadata" minOccurs="0"/>
-		</xs:sequence>
-		<xs:attributeGroup ref="gco:ObjectReference"/>
-		<xs:attribute ref="gco:nilReason"/>
-	</xs:complexType>
-	<!-- =========================================================================== -->
-	<xs:complexType name="SV_ServiceIdentification_Type">
-		<xs:complexContent>
-			<xs:extension base="gmd:AbstractMD_Identification_Type">
-				<xs:sequence>
-					<xs:element name="serviceType" type="gco:GenericName_PropertyType"/>
-					<xs:element name="serviceTypeVersion" type="gco:CharacterString_PropertyType" minOccurs="0" maxOccurs="unbounded"/>
-					<xs:element name="accessProperties" type="gmd:MD_StandardOrderProcess_PropertyType" minOccurs="0"/>
-					<xs:element name="restrictions" type="gmd:MD_Constraints_PropertyType" minOccurs="0"/>
-					<xs:element name="keywords" type="gmd:MD_Keywords_PropertyType" minOccurs="0" maxOccurs="unbounded"/>
-					<xs:element name="extent" type="gmd:EX_Extent_PropertyType" minOccurs="0" maxOccurs="unbounded"/>
-					<xs:element name="coupledResource" type="srv:SV_CoupledResource_PropertyType" minOccurs="0" maxOccurs="unbounded"/>
-					<xs:element name="couplingType" type="srv:SV_CouplingType_PropertyType"/>
-					<xs:element name="containsOperations" type="srv:SV_OperationMetadata_PropertyType" maxOccurs="unbounded"/>
-					<xs:element name="operatesOn" type="gmd:MD_DataIdentification_PropertyType" minOccurs="0" maxOccurs="unbounded"/>
-				</xs:sequence>
-			</xs:extension>
-		</xs:complexContent>
-	</xs:complexType>
-	<!-- ........................................................................ -->
-	<xs:element name="SV_ServiceIdentification" type="srv:SV_ServiceIdentification_Type" substitutionGroup="gmd:AbstractMD_Identification"/>
-	<!-- ........................................................................ -->
-	<xs:complexType name="SV_ServiceIdentification_PropertyType">
-		<xs:sequence>
-			<xs:element ref="srv:SV_ServiceIdentification" minOccurs="0"/>
-		</xs:sequence>
-		<xs:attributeGroup ref="gco:ObjectReference"/>
-		<xs:attribute ref="gco:nilReason"/>
-	</xs:complexType>
-	<!-- =========================================================================== -->
-	<xs:complexType name="SV_OperationChain_Type">
-		<xs:complexContent>
-			<xs:extension base="gco:AbstractObject_Type">
-				<xs:sequence>
-					<xs:element name="name" type="gco:CharacterString_PropertyType"/>
-					<xs:element name="description" type="gco:CharacterString_PropertyType" minOccurs="0"/>
-					<xs:element name="operation" type="srv:SV_Operation_PropertyType" maxOccurs="unbounded"/>
-				</xs:sequence>
-			</xs:extension>
-		</xs:complexContent>
-	</xs:complexType>
-	<!-- ........................................................................ -->
-	<xs:element name="SV_OperationChain" type="srv:SV_OperationChain_Type"/>
-	<!-- ........................................................................ -->
-	<xs:complexType name="SV_OperationChain_PropertyType">
-		<xs:sequence>
-			<xs:element ref="srv:SV_OperationChain" minOccurs="0"/>
-		</xs:sequence>
-		<xs:attributeGroup ref="gco:ObjectReference"/>
-		<xs:attribute ref="gco:nilReason"/>
-	</xs:complexType>
-	<!-- =========================================================================== -->
-	<xs:complexType name="SV_OperationChainMetadata_Type">
-		<xs:complexContent>
-			<xs:extension base="gco:AbstractObject_Type">
-				<xs:sequence>
-					<xs:element name="name" type="gco:CharacterString_PropertyType"/>
-					<xs:element name="description" type="gco:CharacterString_PropertyType" minOccurs="0"/>
-					<xs:element name="operation" type="srv:SV_OperationMetadata_PropertyType" maxOccurs="unbounded"/>
-				</xs:sequence>
-			</xs:extension>
-		</xs:complexContent>
-	</xs:complexType>
-	<!-- ........................................................................ -->
-	<xs:element name="SV_OperationChainMetadata" type="srv:SV_OperationChainMetadata_Type"/>
-	<!-- ........................................................................ -->
-	<xs:complexType name="SV_OperationChainMetadata_PropertyType">
-		<xs:sequence>
-			<xs:element ref="srv:SV_OperationChainMetadata" minOccurs="0"/>
-		</xs:sequence>
-		<xs:attributeGroup ref="gco:ObjectReference"/>
-		<xs:attribute ref="gco:nilReason"/>
-	</xs:complexType>
-	<!-- =========================================================================== -->
-	<xs:complexType name="SV_CoupledResource_Type">
-		<xs:complexContent>
-			<xs:extension base="gco:AbstractObject_Type">
-				<xs:sequence>
-					<xs:element name="operationName" type="gco:CharacterString_PropertyType"/>
-					<xs:element name="identifier" type="gco:CharacterString_PropertyType"/>
-					<xs:element ref="gco:ScopedName" minOccurs="0" maxOccurs="1"/>
-				</xs:sequence>
-			</xs:extension>
-		</xs:complexContent>
-	</xs:complexType>
-	<!-- ........................................................................ -->
-	<xs:element name="SV_CoupledResource" type="srv:SV_CoupledResource_Type"/>
-	<!-- ........................................................................ -->
-	<xs:complexType name="SV_CoupledResource_PropertyType">
-		<xs:sequence>
-			<xs:element ref="srv:SV_CoupledResource" minOccurs="0"/>
-		</xs:sequence>
-		<xs:attributeGroup ref="gco:ObjectReference"/>
-		<xs:attribute ref="gco:nilReason"/>
-	</xs:complexType>
-	<!-- =========================================================================== -->
-	<xs:simpleType name="SV_ParameterDirection_Type">
-		<xs:restriction base="xs:string">
-			<xs:enumeration value="in"/>
-			<xs:enumeration value="out"/>
-			<xs:enumeration value="in/out"/>
-		</xs:restriction>
-	</xs:simpleType>
-	<!-- ........................................................................ -->
-	<xs:element name="SV_ParameterDirection" type="srv:SV_ParameterDirection_Type" substitutionGroup="gco:CharacterString"/>
-	<!-- ........................................................................ -->
-	<xs:complexType name="SV_ParameterDirection_PropertyType">
-		<xs:sequence>
-			<xs:element ref="srv:SV_ParameterDirection" minOccurs="0"/>
-		</xs:sequence>
-		<xs:attribute ref="gco:nilReason"/>
-	</xs:complexType>
-	<!-- =========================================================================== -->
-	<!-- ........................................................................ -->
-	<xs:element name="DCPList" type="gco:CodeListValue_Type" substitutionGroup="gco:CharacterString"/>
-	<!-- ........................................................................ -->
-	<xs:complexType name="DCPList_PropertyType">
-		<xs:sequence>
-			<xs:element ref="srv:DCPList" minOccurs="0"/>
-		</xs:sequence>
-		<xs:attribute ref="gco:nilReason"/>
-	</xs:complexType>
-	<!-- =========================================================================== -->
-	<!-- ........................................................................ -->
-	<xs:element name="SV_CouplingType" type="gco:CodeListValue_Type" substitutionGroup="gco:CharacterString"/>
-	<!-- ........................................................................ -->
-	<xs:complexType name="SV_CouplingType_PropertyType">
-		<xs:sequence>
-			<xs:element ref="srv:SV_CouplingType" minOccurs="0"/>
-		</xs:sequence>
-		<xs:attribute ref="gco:nilReason"/>
-	</xs:complexType>
-	<!-- =========================================================================== -->
-</xs:schema>
-  </csw:SchemaComponent>
-</csw:DescribeRecordResponse>
diff --git a/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gmd/maintenance.xsd b/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gmd/maintenance.xsd
new file mode 100644
index 0000000..9e72369
--- /dev/null
+++ b/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gmd/maintenance.xsd
@@ -0,0 +1,87 @@
+<?xml version="1.0" encoding="utf-8"?>
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:gco="http://www.isotc211.org/2005/gco" xmlns:gts="http://www.isotc211.org/2005/gts" xmlns:gmd="http://www.isotc211.org/2005/gmd" targetNamespace="http://www.isotc211.org/2005/gmd" elementFormDefault="qualified" version="2012-07-13">
+	<!-- ================================= Annotation ================================ -->
+	<xs:annotation>
+		<xs:documentation>Geographic MetaData (GMD) extensible markup language is a component of the XML Schema Implementation of Geographic Information Metadata documented in ISO/TS 19139:2007. GMD includes all the definitions of http://www.isotc211.org/2005/gmd namespace. The root document of this namespace is the file gmd.xsd. This maintenance.xsd schema implements the UML conceptual schema defined in A.2.5 of ISO 19115:2003. It contains the implementation of the following classes: MD_Maint [...]
+	</xs:annotation>
+	<!-- ================================== Imports ================================== -->
+	<xs:import namespace="http://www.isotc211.org/2005/gts" schemaLocation="../gts/gts.xsd"/>
+	<xs:import namespace="http://www.isotc211.org/2005/gco" schemaLocation="../gco/gco.xsd"/>
+	<xs:include schemaLocation="gmd.xsd"/>
+	<xs:include schemaLocation="citation.xsd"/>
+	<!-- ########################################################################### -->
+	<!-- ########################################################################### -->
+	<!-- ================================== Classes ================================= -->
+	<xs:complexType name="MD_MaintenanceInformation_Type">
+		<xs:annotation>
+			<xs:documentation>Information about the scope and frequency of updating</xs:documentation>
+		</xs:annotation>
+		<xs:complexContent>
+			<xs:extension base="gco:AbstractObject_Type">
+				<xs:sequence>
+					<xs:element name="maintenanceAndUpdateFrequency" type="gmd:MD_MaintenanceFrequencyCode_PropertyType"/>
+					<xs:element name="dateOfNextUpdate" type="gco:Date_PropertyType" minOccurs="0"/>
+					<xs:element name="userDefinedMaintenanceFrequency" type="gts:TM_PeriodDuration_PropertyType" minOccurs="0"/>
+					<xs:element name="updateScope" type="gmd:MD_ScopeCode_PropertyType" minOccurs="0" maxOccurs="unbounded"/>
+					<xs:element name="updateScopeDescription" type="gmd:MD_ScopeDescription_PropertyType" minOccurs="0" maxOccurs="unbounded"/>
+					<xs:element name="maintenanceNote" type="gco:CharacterString_PropertyType" minOccurs="0" maxOccurs="unbounded"/>
+					<xs:element name="contact" type="gmd:CI_ResponsibleParty_PropertyType" minOccurs="0" maxOccurs="unbounded"/>
+				</xs:sequence>
+			</xs:extension>
+		</xs:complexContent>
+	</xs:complexType>
+	<!-- ........................................................................ -->
+	<xs:element name="MD_MaintenanceInformation" type="gmd:MD_MaintenanceInformation_Type"/>
+	<!-- ........................................................................ -->
+	<xs:complexType name="MD_MaintenanceInformation_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gmd:MD_MaintenanceInformation"/>
+		</xs:sequence>
+		<xs:attributeGroup ref="gco:ObjectReference"/>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+	<xs:complexType name="MD_ScopeDescription_Type">
+		<xs:annotation>
+			<xs:documentation>Description of the class of information covered by the information</xs:documentation>
+		</xs:annotation>
+		<xs:choice>
+			<xs:element name="attributes" type="gco:ObjectReference_PropertyType" maxOccurs="unbounded"/>
+			<xs:element name="features" type="gco:ObjectReference_PropertyType" maxOccurs="unbounded"/>
+			<xs:element name="featureInstances" type="gco:ObjectReference_PropertyType" maxOccurs="unbounded"/>
+			<xs:element name="attributeInstances" type="gco:ObjectReference_PropertyType" maxOccurs="unbounded"/>
+			<xs:element name="dataset" type="gco:CharacterString_PropertyType"/>
+			<xs:element name="other" type="gco:CharacterString_PropertyType"/>
+		</xs:choice>
+	</xs:complexType>
+	<!-- ........................................................................ -->
+	<xs:element name="MD_ScopeDescription" type="gmd:MD_ScopeDescription_Type"/>
+	<!-- ........................................................................ -->
+	<xs:complexType name="MD_ScopeDescription_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gmd:MD_ScopeDescription"/>
+		</xs:sequence>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+	<!-- ........................................................................ -->
+	<xs:element name="MD_MaintenanceFrequencyCode" type="gco:CodeListValue_Type" substitutionGroup="gco:CharacterString"/>
+	<!-- ........................................................................ -->
+	<xs:complexType name="MD_MaintenanceFrequencyCode_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gmd:MD_MaintenanceFrequencyCode"/>
+		</xs:sequence>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+	<!-- ........................................................................ -->
+	<xs:element name="MD_ScopeCode" type="gco:CodeListValue_Type" substitutionGroup="gco:CharacterString"/>
+	<!-- ........................................................................ -->
+	<xs:complexType name="MD_ScopeCode_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gmd:MD_ScopeCode"/>
+		</xs:sequence>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+</xs:schema>
diff --git a/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gmd/metadataApplication.xsd b/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gmd/metadataApplication.xsd
new file mode 100644
index 0000000..1442919
--- /dev/null
+++ b/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gmd/metadataApplication.xsd
@@ -0,0 +1,176 @@
+<?xml version="1.0" encoding="utf-8"?>
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:gco="http://www.isotc211.org/2005/gco" xmlns:gmd="http://www.isotc211.org/2005/gmd" targetNamespace="http://www.isotc211.org/2005/gmd" elementFormDefault="qualified" version="2012-07-13">
+	<!-- ================================= Annotation ================================ -->
+	<xs:annotation>
+		<xs:documentation>Geographic MetaData (GMD) extensible markup language is a component of the XML Schema Implementation of Geographic Information Metadata documented in ISO/TS 19139:2007. GMD includes all the definitions of http://www.isotc211.org/2005/gmd namespace. The root document of this namespace is the file gmd.xsd. This metadataApplication.xsd schema implements the UML conceptual schema defined in A.2.12 of ISO 19115:2003. It contains the implementation of the class: MD_Applicat [...]
+	</xs:annotation>
+	<!-- ================================== Imports ================================== -->
+	<xs:import namespace="http://www.isotc211.org/2005/gco" schemaLocation="../gco/gco.xsd"/>
+	<xs:include schemaLocation="gmd.xsd"/>
+	<xs:include schemaLocation="metadataEntity.xsd"/>
+	<!-- ########################################################################### -->
+	<!-- ########################################################################### -->
+	<!-- ================================== Classes ================================= -->
+	<xs:complexType name="AbstractDS_Aggregate_Type" abstract="true">
+		<xs:annotation>
+			<xs:documentation>Identifiable collection of datasets</xs:documentation>
+		</xs:annotation>
+		<xs:complexContent>
+			<xs:extension base="gco:AbstractObject_Type">
+				<xs:sequence>
+					<xs:element name="composedOf" type="gmd:DS_DataSet_PropertyType" maxOccurs="unbounded"/>
+					<xs:element name="seriesMetadata" type="gmd:MD_Metadata_PropertyType" maxOccurs="unbounded"/>
+					<xs:element name="subset" type="gmd:DS_Aggregate_PropertyType" minOccurs="0" maxOccurs="unbounded"/>
+					<xs:element name="superset" type="gmd:DS_Aggregate_PropertyType" minOccurs="0" maxOccurs="unbounded"/>
+				</xs:sequence>
+			</xs:extension>
+		</xs:complexContent>
+	</xs:complexType>
+	<!-- ........................................................................ -->
+	<xs:element name="AbstractDS_Aggregate" type="gmd:AbstractDS_Aggregate_Type" abstract="true"/>
+	<!-- ........................................................................ -->
+	<xs:complexType name="DS_Aggregate_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gmd:AbstractDS_Aggregate"/>
+		</xs:sequence>
+		<xs:attributeGroup ref="gco:ObjectReference"/>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+	<xs:complexType name="DS_DataSet_Type">
+		<xs:annotation>
+			<xs:documentation>Identifiable collection of data</xs:documentation>
+		</xs:annotation>
+		<xs:complexContent>
+			<xs:extension base="gco:AbstractObject_Type">
+				<xs:sequence>
+					<xs:element name="has" type="gmd:MD_Metadata_PropertyType" maxOccurs="unbounded"/>
+					<xs:element name="partOf" type="gmd:DS_Aggregate_PropertyType" minOccurs="0" maxOccurs="unbounded"/>
+				</xs:sequence>
+			</xs:extension>
+		</xs:complexContent>
+	</xs:complexType>
+	<!-- ........................................................................ -->
+	<xs:element name="DS_DataSet" type="gmd:DS_DataSet_Type"/>
+	<!-- ........................................................................ -->
+	<xs:complexType name="DS_DataSet_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gmd:DS_DataSet"/>
+		</xs:sequence>
+		<xs:attributeGroup ref="gco:ObjectReference"/>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+	<xs:complexType name="DS_OtherAggregate_Type">
+		<xs:complexContent>
+			<xs:extension base="gmd:AbstractDS_Aggregate_Type"/>
+		</xs:complexContent>
+	</xs:complexType>
+	<!-- ........................................................................ -->
+	<xs:element name="DS_OtherAggregate" type="gmd:DS_OtherAggregate_Type" substitutionGroup="gmd:AbstractDS_Aggregate"/>
+	<!-- ........................................................................ -->
+	<xs:complexType name="DS_OtherAggregate_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gmd:DS_OtherAggregate"/>
+		</xs:sequence>
+		<xs:attributeGroup ref="gco:ObjectReference"/>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+	<xs:complexType name="DS_Series_Type">
+		<xs:complexContent>
+			<xs:extension base="gmd:AbstractDS_Aggregate_Type"/>
+		</xs:complexContent>
+	</xs:complexType>
+	<!-- ........................................................................ -->
+	<xs:element name="DS_Series" type="gmd:DS_Series_Type" substitutionGroup="gmd:AbstractDS_Aggregate"/>
+	<!-- ........................................................................ -->
+	<xs:complexType name="DS_Series_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gmd:DS_Series"/>
+		</xs:sequence>
+		<xs:attributeGroup ref="gco:ObjectReference"/>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+	<xs:complexType name="DS_Initiative_Type">
+		<xs:complexContent>
+			<xs:extension base="gmd:AbstractDS_Aggregate_Type"/>
+		</xs:complexContent>
+	</xs:complexType>
+	<!-- ........................................................................ -->
+	<xs:element name="DS_Initiative" type="gmd:DS_Initiative_Type" substitutionGroup="gmd:AbstractDS_Aggregate"/>
+	<!-- ........................................................................ -->
+	<xs:complexType name="DS_Initiative_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gmd:DS_Initiative"/>
+		</xs:sequence>
+		<xs:attributeGroup ref="gco:ObjectReference"/>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+	<xs:complexType name="DS_Platform_Type">
+		<xs:complexContent>
+			<xs:extension base="gmd:DS_Series_Type"/>
+		</xs:complexContent>
+	</xs:complexType>
+	<!-- ........................................................................ -->
+	<xs:element name="DS_Platform" type="gmd:DS_Platform_Type" substitutionGroup="gmd:DS_Series"/>
+	<!-- ........................................................................ -->
+	<xs:complexType name="DS_Platform_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gmd:DS_Platform"/>
+		</xs:sequence>
+		<xs:attributeGroup ref="gco:ObjectReference"/>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+	<xs:complexType name="DS_Sensor_Type">
+		<xs:complexContent>
+			<xs:extension base="gmd:DS_Series_Type"/>
+		</xs:complexContent>
+	</xs:complexType>
+	<!-- ........................................................................ -->
+	<xs:element name="DS_Sensor" type="gmd:DS_Sensor_Type" substitutionGroup="gmd:DS_Series"/>
+	<!-- ........................................................................ -->
+	<xs:complexType name="DS_Sensor_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gmd:DS_Sensor"/>
+		</xs:sequence>
+		<xs:attributeGroup ref="gco:ObjectReference"/>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+	<xs:complexType name="DS_ProductionSeries_Type">
+		<xs:complexContent>
+			<xs:extension base="gmd:DS_Series_Type"/>
+		</xs:complexContent>
+	</xs:complexType>
+	<!-- ........................................................................ -->
+	<xs:element name="DS_ProductionSeries" type="gmd:DS_ProductionSeries_Type" substitutionGroup="gmd:DS_Series"/>
+	<!-- ........................................................................ -->
+	<xs:complexType name="DS_ProductionSeries_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gmd:DS_ProductionSeries"/>
+		</xs:sequence>
+		<xs:attributeGroup ref="gco:ObjectReference"/>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+	<xs:complexType name="DS_StereoMate_Type">
+		<xs:complexContent>
+			<xs:extension base="gmd:DS_OtherAggregate_Type"/>
+		</xs:complexContent>
+	</xs:complexType>
+	<!-- ........................................................................ -->
+	<xs:element name="DS_StereoMate" type="gmd:DS_StereoMate_Type" substitutionGroup="gmd:DS_OtherAggregate"/>
+	<!-- ........................................................................ -->
+	<xs:complexType name="DS_StereoMate_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gmd:DS_StereoMate"/>
+		</xs:sequence>
+		<xs:attributeGroup ref="gco:ObjectReference"/>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+</xs:schema>
diff --git a/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gmd/metadataEntity.xsd b/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gmd/metadataEntity.xsd
new file mode 100644
index 0000000..d0ae0bf
--- /dev/null
+++ b/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gmd/metadataEntity.xsd
@@ -0,0 +1,71 @@
+<?xml version="1.0" encoding="utf-8"?>
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:gco="http://www.isotc211.org/2005/gco" xmlns:gmd="http://www.isotc211.org/2005/gmd" targetNamespace="http://www.isotc211.org/2005/gmd" elementFormDefault="qualified" version="2012-07-13">
+	<!-- ================================= Annotation ================================ -->
+	<xs:annotation>
+		<xs:documentation>Geographic MetaData (GMD) extensible markup language is a component of the XML Schema Implementation of Geographic Information Metadata documented in ISO/TS 19139:2007. GMD includes all the definitions of http://www.isotc211.org/2005/gmd namespace. The root document of this namespace is the file gmd.xsd. This metadataEntity.xsd schema implements the UML conceptual schema defined in A.2.1 of ISO 19115:2003. It contains the implementation of the class MD_Metadata.</xs:d [...]
+	</xs:annotation>
+	<!-- ================================== Imports ================================== -->
+	<xs:import namespace="http://www.isotc211.org/2005/gco" schemaLocation="../gco/gco.xsd"/>
+	<xs:include schemaLocation="gmd.xsd"/>
+	<xs:include schemaLocation="spatialRepresentation.xsd"/>
+	<xs:include schemaLocation="metadataExtension.xsd"/>
+	<xs:include schemaLocation="content.xsd"/>
+	<xs:include schemaLocation="metadataApplication.xsd"/>
+	<xs:include schemaLocation="applicationSchema.xsd"/>
+	<xs:include schemaLocation="portrayalCatalogue.xsd"/>
+	<xs:include schemaLocation="dataQuality.xsd"/>
+	<xs:include schemaLocation="freeText.xsd"/>
+	<!-- ########################################################################### -->
+	<!-- ########################################################################### -->
+	<!-- ================================== Classes ================================= -->
+	<xs:complexType name="MD_Metadata_Type">
+		<xs:annotation>
+			<xs:documentation>Information about the metadata</xs:documentation>
+		</xs:annotation>
+		<xs:complexContent>
+			<xs:extension base="gco:AbstractObject_Type">
+				<xs:sequence>
+					<xs:element name="fileIdentifier" type="gco:CharacterString_PropertyType" minOccurs="0"/>
+					<xs:element name="language" type="gco:CharacterString_PropertyType" minOccurs="0"/>
+					<xs:element name="characterSet" type="gmd:MD_CharacterSetCode_PropertyType" minOccurs="0"/>
+					<xs:element name="parentIdentifier" type="gco:CharacterString_PropertyType" minOccurs="0"/>
+					<xs:element name="hierarchyLevel" type="gmd:MD_ScopeCode_PropertyType" minOccurs="0" maxOccurs="unbounded"/>
+					<xs:element name="hierarchyLevelName" type="gco:CharacterString_PropertyType" minOccurs="0" maxOccurs="unbounded"/>
+					<xs:element name="contact" type="gmd:CI_ResponsibleParty_PropertyType" maxOccurs="unbounded"/>
+					<xs:element name="dateStamp" type="gco:Date_PropertyType"/>
+					<xs:element name="metadataStandardName" type="gco:CharacterString_PropertyType" minOccurs="0"/>
+					<xs:element name="metadataStandardVersion" type="gco:CharacterString_PropertyType" minOccurs="0"/>
+					<xs:element name="dataSetURI" type="gco:CharacterString_PropertyType" minOccurs="0"/>
+					<xs:element name="locale" type="gmd:PT_Locale_PropertyType" minOccurs="0" maxOccurs="unbounded"/>
+					<xs:element name="spatialRepresentationInfo" type="gmd:MD_SpatialRepresentation_PropertyType" minOccurs="0" maxOccurs="unbounded"/>
+					<xs:element name="referenceSystemInfo" type="gmd:MD_ReferenceSystem_PropertyType" minOccurs="0" maxOccurs="unbounded"/>
+					<xs:element name="metadataExtensionInfo" type="gmd:MD_MetadataExtensionInformation_PropertyType" minOccurs="0" maxOccurs="unbounded"/>
+					<xs:element name="identificationInfo" type="gmd:MD_Identification_PropertyType" maxOccurs="unbounded"/>
+					<xs:element name="contentInfo" type="gmd:MD_ContentInformation_PropertyType" minOccurs="0" maxOccurs="unbounded"/>
+					<xs:element name="distributionInfo" type="gmd:MD_Distribution_PropertyType" minOccurs="0"/>
+					<xs:element name="dataQualityInfo" type="gmd:DQ_DataQuality_PropertyType" minOccurs="0" maxOccurs="unbounded"/>
+					<xs:element name="portrayalCatalogueInfo" type="gmd:MD_PortrayalCatalogueReference_PropertyType" minOccurs="0" maxOccurs="unbounded"/>
+					<xs:element name="metadataConstraints" type="gmd:MD_Constraints_PropertyType" minOccurs="0" maxOccurs="unbounded"/>
+					<xs:element name="applicationSchemaInfo" type="gmd:MD_ApplicationSchemaInformation_PropertyType" minOccurs="0" maxOccurs="unbounded"/>
+					<xs:element name="metadataMaintenance" type="gmd:MD_MaintenanceInformation_PropertyType" minOccurs="0"/>
+					<xs:element name="series" type="gmd:DS_Aggregate_PropertyType" minOccurs="0" maxOccurs="unbounded"/>
+					<xs:element name="describes" type="gmd:DS_DataSet_PropertyType" minOccurs="0" maxOccurs="unbounded"/>
+					<xs:element name="propertyType" type="gco:ObjectReference_PropertyType" minOccurs="0" maxOccurs="unbounded"/>
+					<xs:element name="featureType" type="gco:ObjectReference_PropertyType" minOccurs="0" maxOccurs="unbounded"/>
+					<xs:element name="featureAttribute" type="gco:ObjectReference_PropertyType" minOccurs="0" maxOccurs="unbounded"/>
+				</xs:sequence>
+			</xs:extension>
+		</xs:complexContent>
+	</xs:complexType>
+	<!-- ........................................................................ -->
+	<xs:element name="MD_Metadata" type="gmd:MD_Metadata_Type"/>
+	<!-- ........................................................................ -->
+	<xs:complexType name="MD_Metadata_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gmd:MD_Metadata"/>
+		</xs:sequence>
+		<xs:attributeGroup ref="gco:ObjectReference"/>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+</xs:schema>
diff --git a/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gmd/metadataExtension.xsd b/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gmd/metadataExtension.xsd
new file mode 100644
index 0000000..665740a
--- /dev/null
+++ b/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gmd/metadataExtension.xsd
@@ -0,0 +1,100 @@
+<?xml version="1.0" encoding="utf-8"?>
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:gco="http://www.isotc211.org/2005/gco" xmlns:gmd="http://www.isotc211.org/2005/gmd" targetNamespace="http://www.isotc211.org/2005/gmd" elementFormDefault="qualified" version="2012-07-13">
+	<!-- ================================= Annotation ================================ -->
+	<xs:annotation>
+		<xs:documentation>Geographic MetaData (GMD) extensible markup language is a component of the XML Schema Implementation of Geographic Information Metadata documented in ISO/TS 19139:2007. GMD includes all the definitions of http://www.isotc211.org/2005/gmd namespace. The root document of this namespace is the file gmd.xsd. This metadataExtension.xsd schema implements the UML conceptual schema defined in A.2.11 of ISO 19115:2003. It contains the implementation of the following classes: M [...]
+	</xs:annotation>
+	<!-- ================================== Imports ================================== -->
+	<xs:import namespace="http://www.isotc211.org/2005/gco" schemaLocation="../gco/gco.xsd"/>
+	<xs:include schemaLocation="gmd.xsd"/>
+	<xs:include schemaLocation="citation.xsd"/>
+	<!-- ########################################################################### -->
+	<!-- ########################################################################### -->
+	<!-- ================================== Classes ================================= -->
+	<xs:complexType name="MD_ExtendedElementInformation_Type">
+		<xs:annotation>
+			<xs:documentation>New metadata element, not found in ISO 19115, which is required to describe geographic data</xs:documentation>
+		</xs:annotation>
+		<xs:complexContent>
+			<xs:extension base="gco:AbstractObject_Type">
+				<xs:sequence>
+					<xs:element name="name" type="gco:CharacterString_PropertyType"/>
+					<xs:element name="shortName" type="gco:CharacterString_PropertyType" minOccurs="0"/>
+					<xs:element name="domainCode" type="gco:Integer_PropertyType" minOccurs="0"/>
+					<xs:element name="definition" type="gco:CharacterString_PropertyType"/>
+					<xs:element name="obligation" type="gmd:MD_ObligationCode_PropertyType" minOccurs="0"/>
+					<xs:element name="condition" type="gco:CharacterString_PropertyType" minOccurs="0"/>
+					<xs:element name="dataType" type="gmd:MD_DatatypeCode_PropertyType"/>
+					<xs:element name="maximumOccurrence" type="gco:CharacterString_PropertyType" minOccurs="0"/>
+					<xs:element name="domainValue" type="gco:CharacterString_PropertyType" minOccurs="0"/>
+					<xs:element name="parentEntity" type="gco:CharacterString_PropertyType" maxOccurs="unbounded"/>
+					<xs:element name="rule" type="gco:CharacterString_PropertyType"/>
+					<xs:element name="rationale" type="gco:CharacterString_PropertyType" minOccurs="0" maxOccurs="unbounded"/>
+					<xs:element name="source" type="gmd:CI_ResponsibleParty_PropertyType" maxOccurs="unbounded"/>
+				</xs:sequence>
+			</xs:extension>
+		</xs:complexContent>
+	</xs:complexType>
+	<!-- ........................................................................ -->
+	<xs:element name="MD_ExtendedElementInformation" type="gmd:MD_ExtendedElementInformation_Type"/>
+	<!-- ........................................................................ -->
+	<xs:complexType name="MD_ExtendedElementInformation_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gmd:MD_ExtendedElementInformation"/>
+		</xs:sequence>
+		<xs:attributeGroup ref="gco:ObjectReference"/>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+	<xs:complexType name="MD_MetadataExtensionInformation_Type">
+		<xs:annotation>
+			<xs:documentation>Information describing metadata extensions.</xs:documentation>
+		</xs:annotation>
+		<xs:complexContent>
+			<xs:extension base="gco:AbstractObject_Type">
+				<xs:sequence>
+					<xs:element name="extensionOnLineResource" type="gmd:CI_OnlineResource_PropertyType" minOccurs="0"/>
+					<xs:element name="extendedElementInformation" type="gmd:MD_ExtendedElementInformation_PropertyType" minOccurs="0" maxOccurs="unbounded"/>
+				</xs:sequence>
+			</xs:extension>
+		</xs:complexContent>
+	</xs:complexType>
+	<!-- ........................................................................ -->
+	<xs:element name="MD_MetadataExtensionInformation" type="gmd:MD_MetadataExtensionInformation_Type"/>
+	<!-- ........................................................................ -->
+	<xs:complexType name="MD_MetadataExtensionInformation_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gmd:MD_MetadataExtensionInformation"/>
+		</xs:sequence>
+		<xs:attributeGroup ref="gco:ObjectReference"/>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+	<xs:simpleType name="MD_ObligationCode_Type">
+		<xs:restriction base="xs:string">
+			<xs:enumeration value="mandatory"/>
+			<xs:enumeration value="optional"/>
+			<xs:enumeration value="conditional"/>
+		</xs:restriction>
+	</xs:simpleType>
+	<!-- ........................................................................ -->
+	<xs:element name="MD_ObligationCode" type="gmd:MD_ObligationCode_Type" substitutionGroup="gco:CharacterString"/>
+	<!-- ........................................................................ -->
+	<xs:complexType name="MD_ObligationCode_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gmd:MD_ObligationCode"/>
+		</xs:sequence>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+	<!-- ........................................................................ -->
+	<xs:element name="MD_DatatypeCode" type="gco:CodeListValue_Type" substitutionGroup="gco:CharacterString"/>
+	<!-- ........................................................................ -->
+	<xs:complexType name="MD_DatatypeCode_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gmd:MD_DatatypeCode"/>
+		</xs:sequence>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+</xs:schema>
diff --git a/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gmd/portrayalCatalogue.xsd b/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gmd/portrayalCatalogue.xsd
new file mode 100644
index 0000000..5cf370d
--- /dev/null
+++ b/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gmd/portrayalCatalogue.xsd
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="utf-8"?>
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:gco="http://www.isotc211.org/2005/gco" xmlns:gmd="http://www.isotc211.org/2005/gmd" targetNamespace="http://www.isotc211.org/2005/gmd" elementFormDefault="qualified" version="2012-07-13">
+	<!-- ================================= Annotation ================================ -->
+	<xs:annotation>
+		<xs:documentation>Geographic MetaData (GMD) extensible markup language is a component of the XML Schema Implementation of Geographic Information Metadata documented in ISO/TS 19139:2007. GMD includes all the definitions of http://www.isotc211.org/2005/gmd namespace. The root document of this namespace is the file gmd.xsd. This portrayalCatalogue.xsd schema implements the UML conceptual schema defined in A.2.9 of ISO 19115:2003. It contains the implementation of the class MD_PortrayalCa [...]
+	</xs:annotation>
+	<!-- ================================== Imports ================================== -->
+	<xs:import namespace="http://www.isotc211.org/2005/gco" schemaLocation="../gco/gco.xsd"/>
+	<xs:include schemaLocation="gmd.xsd"/>
+	<xs:include schemaLocation="citation.xsd"/>
+	<!-- ########################################################################### -->
+	<!-- ########################################################################### -->
+	<!-- ================================== Classes ================================= -->
+	<xs:complexType name="MD_PortrayalCatalogueReference_Type">
+		<xs:annotation>
+			<xs:documentation>Information identifing the portrayal catalogue used</xs:documentation>
+		</xs:annotation>
+		<xs:complexContent>
+			<xs:extension base="gco:AbstractObject_Type">
+				<xs:sequence>
+					<xs:element name="portrayalCatalogueCitation" type="gmd:CI_Citation_PropertyType" maxOccurs="unbounded"/>
+				</xs:sequence>
+			</xs:extension>
+		</xs:complexContent>
+	</xs:complexType>
+	<!-- ........................................................................ -->
+	<xs:element name="MD_PortrayalCatalogueReference" type="gmd:MD_PortrayalCatalogueReference_Type"/>
+	<!-- ........................................................................ -->
+	<xs:complexType name="MD_PortrayalCatalogueReference_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gmd:MD_PortrayalCatalogueReference"/>
+		</xs:sequence>
+		<xs:attributeGroup ref="gco:ObjectReference"/>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+</xs:schema>
diff --git a/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gmd/referenceSystem.xsd b/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gmd/referenceSystem.xsd
new file mode 100644
index 0000000..b6abd58
--- /dev/null
+++ b/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gmd/referenceSystem.xsd
@@ -0,0 +1,101 @@
+<?xml version="1.0" encoding="utf-8"?>
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:gco="http://www.isotc211.org/2005/gco" xmlns:gmd="http://www.isotc211.org/2005/gmd" targetNamespace="http://www.isotc211.org/2005/gmd" elementFormDefault="qualified" version="2012-07-13">
+	<!-- ================================= Annotation ================================ -->
+	<xs:annotation>
+		<xs:documentation>Geographic MetaData (GMD) extensible markup language is a component of the XML Schema Implementation of Geographic Information Metadata documented in ISO/TS 19139:2007. GMD includes all the definitions of http://www.isotc211.org/2005/gmd namespace. The root document of this namespace is the file gmd.xsd. This referenceSystem.xsd schema implements the UML conceptual schema defined in A.2.7 of ISO 19115:2003 and ISO 19115:2003/Cor. 1:2006. It contains the implementation [...]
+	</xs:annotation>
+	<!-- ================================== Imports ================================== -->
+	<xs:import namespace="http://www.isotc211.org/2005/gco" schemaLocation="../gco/gco.xsd"/>
+	<xs:include schemaLocation="gmd.xsd"/>
+	<xs:include schemaLocation="citation.xsd"/>
+	<xs:include schemaLocation="extent.xsd"/>
+	<!-- ########################################################################### -->
+	<!-- ########################################################################### -->
+	<!-- ================================== Classes ================================= -->
+	<xs:complexType name="RS_Identifier_Type">
+		<xs:complexContent>
+			<xs:extension base="gmd:MD_Identifier_Type">
+				<xs:sequence>
+					<xs:element name="codeSpace" type="gco:CharacterString_PropertyType" minOccurs="0"/>
+					<xs:element name="version" type="gco:CharacterString_PropertyType" minOccurs="0"/>
+				</xs:sequence>
+			</xs:extension>
+		</xs:complexContent>
+	</xs:complexType>
+	<!-- ........................................................................ -->
+	<xs:element name="RS_Identifier" type="gmd:RS_Identifier_Type" substitutionGroup="gmd:MD_Identifier"/>
+	<!-- ........................................................................ -->
+	<xs:complexType name="RS_Identifier_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gmd:RS_Identifier"/>
+		</xs:sequence>
+		<xs:attributeGroup ref="gco:ObjectReference"/>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+	<xs:complexType name="MD_ReferenceSystem_Type">
+		<xs:complexContent>
+			<xs:extension base="gco:AbstractObject_Type">
+				<xs:sequence>
+					<xs:element name="referenceSystemIdentifier" type="gmd:RS_Identifier_PropertyType" minOccurs="0"/>
+				</xs:sequence>
+			</xs:extension>
+		</xs:complexContent>
+	</xs:complexType>
+	<!-- ........................................................................ -->
+	<xs:element name="MD_ReferenceSystem" type="gmd:MD_ReferenceSystem_Type"/>
+	<!-- ........................................................................ -->
+	<xs:complexType name="MD_ReferenceSystem_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gmd:MD_ReferenceSystem"/>
+		</xs:sequence>
+		<xs:attributeGroup ref="gco:ObjectReference"/>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+	<xs:complexType name="MD_Identifier_Type">
+		<xs:complexContent>
+			<xs:extension base="gco:AbstractObject_Type">
+				<xs:sequence>
+					<xs:element name="authority" type="gmd:CI_Citation_PropertyType" minOccurs="0"/>
+					<xs:element name="code" type="gco:CharacterString_PropertyType"/>
+				</xs:sequence>
+			</xs:extension>
+		</xs:complexContent>
+	</xs:complexType>
+	<!-- ........................................................................ -->
+	<xs:element name="MD_Identifier" type="gmd:MD_Identifier_Type"/>
+	<!-- ........................................................................ -->
+	<xs:complexType name="MD_Identifier_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gmd:MD_Identifier"/>
+		</xs:sequence>
+		<xs:attributeGroup ref="gco:ObjectReference"/>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+	<xs:complexType name="AbstractRS_ReferenceSystem_Type" abstract="true">
+		<xs:annotation>
+			<xs:documentation>Description of the spatial and temporal reference systems used in the dataset</xs:documentation>
+		</xs:annotation>
+		<xs:complexContent>
+			<xs:extension base="gco:AbstractObject_Type">
+				<xs:sequence>
+					<xs:element name="name" type="gmd:RS_Identifier_PropertyType"/>
+					<xs:element name="domainOfValidity" type="gmd:EX_Extent_PropertyType" minOccurs="0" maxOccurs="unbounded"/>
+				</xs:sequence>
+			</xs:extension>
+		</xs:complexContent>
+	</xs:complexType>
+	<!-- ........................................................................ -->
+	<xs:element name="AbstractRS_ReferenceSystem" type="gmd:AbstractRS_ReferenceSystem_Type" abstract="true"/>
+	<!-- ........................................................................ -->
+	<xs:complexType name="RS_ReferenceSystem_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gmd:AbstractRS_ReferenceSystem"/>
+		</xs:sequence>
+		<xs:attributeGroup ref="gco:ObjectReference"/>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+</xs:schema>
diff --git a/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gmd/spatialRepresentation.xsd b/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gmd/spatialRepresentation.xsd
new file mode 100644
index 0000000..34e0f23
--- /dev/null
+++ b/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gmd/spatialRepresentation.xsd
@@ -0,0 +1,238 @@
+<?xml version="1.0" encoding="utf-8"?>
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:gco="http://www.isotc211.org/2005/gco" xmlns:gss="http://www.isotc211.org/2005/gss" xmlns:gmd="http://www.isotc211.org/2005/gmd" targetNamespace="http://www.isotc211.org/2005/gmd" elementFormDefault="qualified" version="2012-07-13">
+	<!-- ================================= Annotation ================================ -->
+	<xs:annotation>
+		<xs:documentation>Geographic MetaData (GMD) extensible markup language is a component of the XML Schema Implementation of Geographic Information Metadata documented in ISO/TS 19139:2007. GMD includes all the definitions of http://www.isotc211.org/2005/gmd namespace. The root document of this namespace is the file gmd.xsd. This portrayalCatalogue.xsd schema implements the UML conceptual schema defined in A.2.6 of ISO 19115:2003. It contains the implementation of the following classes: M [...]
+	</xs:annotation>
+	<!-- ================================== Imports ================================== -->
+	<xs:import namespace="http://www.isotc211.org/2005/gss" schemaLocation="../gss/gss.xsd"/>
+	<xs:import namespace="http://www.isotc211.org/2005/gco" schemaLocation="../gco/gco.xsd"/>
+	<xs:include schemaLocation="gmd.xsd"/>
+	<xs:include schemaLocation="citation.xsd"/>
+	<!-- ########################################################################### -->
+	<!-- ########################################################################### -->
+	<!-- ================================== Classes ================================= -->
+	<xs:complexType name="MD_GridSpatialRepresentation_Type">
+		<xs:annotation>
+			<xs:documentation>Types and numbers of raster spatial objects in the dataset</xs:documentation>
+		</xs:annotation>
+		<xs:complexContent>
+			<xs:extension base="gmd:AbstractMD_SpatialRepresentation_Type">
+				<xs:sequence>
+					<xs:element name="numberOfDimensions" type="gco:Integer_PropertyType"/>
+					<xs:element name="axisDimensionProperties" type="gmd:MD_Dimension_PropertyType" minOccurs="0" maxOccurs="unbounded"/>
+					<xs:element name="cellGeometry" type="gmd:MD_CellGeometryCode_PropertyType"/>
+					<xs:element name="transformationParameterAvailability" type="gco:Boolean_PropertyType"/>
+				</xs:sequence>
+			</xs:extension>
+		</xs:complexContent>
+	</xs:complexType>
+	<!-- ........................................................................ -->
+	<xs:element name="MD_GridSpatialRepresentation" type="gmd:MD_GridSpatialRepresentation_Type" substitutionGroup="gmd:AbstractMD_SpatialRepresentation"/>
+	<!-- ........................................................................ -->
+	<xs:complexType name="MD_GridSpatialRepresentation_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gmd:MD_GridSpatialRepresentation"/>
+		</xs:sequence>
+		<xs:attributeGroup ref="gco:ObjectReference"/>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+	<xs:complexType name="MD_VectorSpatialRepresentation_Type">
+		<xs:annotation>
+			<xs:documentation>Information about the vector spatial objects in the dataset</xs:documentation>
+		</xs:annotation>
+		<xs:complexContent>
+			<xs:extension base="gmd:AbstractMD_SpatialRepresentation_Type">
+				<xs:sequence>
+					<xs:element name="topologyLevel" type="gmd:MD_TopologyLevelCode_PropertyType" minOccurs="0"/>
+					<xs:element name="geometricObjects" type="gmd:MD_GeometricObjects_PropertyType" minOccurs="0" maxOccurs="unbounded"/>
+				</xs:sequence>
+			</xs:extension>
+		</xs:complexContent>
+	</xs:complexType>
+	<!-- ........................................................................ -->
+	<xs:element name="MD_VectorSpatialRepresentation" type="gmd:MD_VectorSpatialRepresentation_Type" substitutionGroup="gmd:AbstractMD_SpatialRepresentation"/>
+	<!-- ........................................................................ -->
+	<xs:complexType name="MD_VectorSpatialRepresentation_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gmd:MD_VectorSpatialRepresentation"/>
+		</xs:sequence>
+		<xs:attributeGroup ref="gco:ObjectReference"/>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+	<xs:complexType name="AbstractMD_SpatialRepresentation_Type" abstract="true">
+		<xs:annotation>
+			<xs:documentation>Digital mechanism used to represent spatial information</xs:documentation>
+		</xs:annotation>
+		<xs:complexContent>
+			<xs:extension base="gco:AbstractObject_Type">
+				<xs:sequence/>
+			</xs:extension>
+		</xs:complexContent>
+	</xs:complexType>
+	<!-- ........................................................................ -->
+	<xs:element name="AbstractMD_SpatialRepresentation" type="gmd:AbstractMD_SpatialRepresentation_Type" abstract="true"/>
+	<!-- ........................................................................ -->
+	<xs:complexType name="MD_SpatialRepresentation_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gmd:AbstractMD_SpatialRepresentation"/>
+		</xs:sequence>
+		<xs:attributeGroup ref="gco:ObjectReference"/>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+	<xs:complexType name="MD_Georeferenceable_Type">
+		<xs:complexContent>
+			<xs:extension base="gmd:MD_GridSpatialRepresentation_Type">
+				<xs:sequence>
+					<xs:element name="controlPointAvailability" type="gco:Boolean_PropertyType"/>
+					<xs:element name="orientationParameterAvailability" type="gco:Boolean_PropertyType"/>
+					<xs:element name="orientationParameterDescription" type="gco:CharacterString_PropertyType" minOccurs="0"/>
+					<xs:element name="georeferencedParameters" type="gco:Record_PropertyType"/>
+					<xs:element name="parameterCitation" type="gmd:CI_Citation_PropertyType" minOccurs="0" maxOccurs="unbounded"/>
+				</xs:sequence>
+			</xs:extension>
+		</xs:complexContent>
+	</xs:complexType>
+	<!-- ........................................................................ -->
+	<xs:element name="MD_Georeferenceable" type="gmd:MD_Georeferenceable_Type" substitutionGroup="gmd:MD_GridSpatialRepresentation"/>
+	<!-- ........................................................................ -->
+	<xs:complexType name="MD_Georeferenceable_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gmd:MD_Georeferenceable"/>
+		</xs:sequence>
+		<xs:attributeGroup ref="gco:ObjectReference"/>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+	<xs:complexType name="MD_Dimension_Type">
+		<xs:complexContent>
+			<xs:extension base="gco:AbstractObject_Type">
+				<xs:sequence>
+					<xs:element name="dimensionName" type="gmd:MD_DimensionNameTypeCode_PropertyType"/>
+					<xs:element name="dimensionSize" type="gco:Integer_PropertyType"/>
+					<xs:element name="resolution" type="gco:Measure_PropertyType" minOccurs="0"/>
+				</xs:sequence>
+			</xs:extension>
+		</xs:complexContent>
+	</xs:complexType>
+	<!-- ........................................................................ -->
+	<xs:element name="MD_Dimension" type="gmd:MD_Dimension_Type"/>
+	<!-- ........................................................................ -->
+	<xs:complexType name="MD_Dimension_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gmd:MD_Dimension"/>
+		</xs:sequence>
+		<xs:attributeGroup ref="gco:ObjectReference"/>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+	<xs:complexType name="MD_Georectified_Type">
+		<xs:complexContent>
+			<xs:extension base="gmd:MD_GridSpatialRepresentation_Type">
+				<xs:sequence>
+					<xs:element name="checkPointAvailability" type="gco:Boolean_PropertyType"/>
+					<xs:element name="checkPointDescription" type="gco:CharacterString_PropertyType" minOccurs="0"/>
+					<xs:element name="cornerPoints" type="gss:GM_Point_PropertyType" minOccurs="0" maxOccurs="unbounded"/>
+					<xs:element name="centerPoint" type="gss:GM_Point_PropertyType" minOccurs="0"/>
+					<xs:element name="pointInPixel" type="gmd:MD_PixelOrientationCode_PropertyType"/>
+					<xs:element name="transformationDimensionDescription" type="gco:CharacterString_PropertyType" minOccurs="0"/>
+					<xs:element name="transformationDimensionMapping" type="gco:CharacterString_PropertyType" minOccurs="0" maxOccurs="2"/>
+				</xs:sequence>
+			</xs:extension>
+		</xs:complexContent>
+	</xs:complexType>
+	<!-- ........................................................................ -->
+	<xs:element name="MD_Georectified" type="gmd:MD_Georectified_Type" substitutionGroup="gmd:MD_GridSpatialRepresentation"/>
+	<!-- ........................................................................ -->
+	<xs:complexType name="MD_Georectified_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gmd:MD_Georectified"/>
+		</xs:sequence>
+		<xs:attributeGroup ref="gco:ObjectReference"/>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+	<xs:complexType name="MD_GeometricObjects_Type">
+		<xs:complexContent>
+			<xs:extension base="gco:AbstractObject_Type">
+				<xs:sequence>
+					<xs:element name="geometricObjectType" type="gmd:MD_GeometricObjectTypeCode_PropertyType"/>
+					<xs:element name="geometricObjectCount" type="gco:Integer_PropertyType" minOccurs="0"/>
+				</xs:sequence>
+			</xs:extension>
+		</xs:complexContent>
+	</xs:complexType>
+	<!-- ........................................................................ -->
+	<xs:element name="MD_GeometricObjects" type="gmd:MD_GeometricObjects_Type"/>
+	<!-- ........................................................................ -->
+	<xs:complexType name="MD_GeometricObjects_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gmd:MD_GeometricObjects"/>
+		</xs:sequence>
+		<xs:attributeGroup ref="gco:ObjectReference"/>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+	<xs:simpleType name="MD_PixelOrientationCode_Type">
+		<xs:restriction base="xs:string">
+			<xs:enumeration value="center"/>
+			<xs:enumeration value="lowerLeft"/>
+			<xs:enumeration value="lowerRight"/>
+			<xs:enumeration value="upperRight"/>
+			<xs:enumeration value="upperLeft"/>
+		</xs:restriction>
+	</xs:simpleType>
+	<!-- ........................................................................ -->
+	<xs:element name="MD_PixelOrientationCode" type="gmd:MD_PixelOrientationCode_Type" substitutionGroup="gco:CharacterString"/>
+	<!-- ........................................................................ -->
+	<xs:complexType name="MD_PixelOrientationCode_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gmd:MD_PixelOrientationCode"/>
+		</xs:sequence>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+	<!-- ........................................................................ -->
+	<xs:element name="MD_TopologyLevelCode" type="gco:CodeListValue_Type" substitutionGroup="gco:CharacterString"/>
+	<!-- ........................................................................ -->
+	<xs:complexType name="MD_TopologyLevelCode_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gmd:MD_TopologyLevelCode"/>
+		</xs:sequence>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+	<!-- ........................................................................ -->
+	<xs:element name="MD_GeometricObjectTypeCode" type="gco:CodeListValue_Type" substitutionGroup="gco:CharacterString"/>
+	<!-- ........................................................................ -->
+	<xs:complexType name="MD_GeometricObjectTypeCode_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gmd:MD_GeometricObjectTypeCode"/>
+		</xs:sequence>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+	<!-- ........................................................................ -->
+	<xs:element name="MD_CellGeometryCode" type="gco:CodeListValue_Type" substitutionGroup="gco:CharacterString"/>
+	<!-- ........................................................................ -->
+	<xs:complexType name="MD_CellGeometryCode_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gmd:MD_CellGeometryCode"/>
+		</xs:sequence>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+	<!-- ........................................................................ -->
+	<xs:element name="MD_DimensionNameTypeCode" type="gco:CodeListValue_Type" substitutionGroup="gco:CharacterString"/>
+	<!-- ........................................................................ -->
+	<xs:complexType name="MD_DimensionNameTypeCode_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gmd:MD_DimensionNameTypeCode"/>
+		</xs:sequence>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+</xs:schema>
diff --git a/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gmx/ReadMe.txt b/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gmx/ReadMe.txt
new file mode 100644
index 0000000..16a0ede
--- /dev/null
+++ b/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gmx/ReadMe.txt
@@ -0,0 +1,47 @@
+ISO(c) GMX schema ReadMe.txt
+------------------------------------------------------------------------------
+
+Geographic Metadata XML (GMX) Schema
+
+GMX is a component of the XML Schema Implementation of Geographic
+Information Metadata documented in ISO/TS 19139:2007.
+
+GMX includes all the definitions of http://www.isotc211.org/2005/gmx
+namespace. The root document of this namespace is the file gmx.xsd.
+
+The most current schemas are available at:
+http://standards.iso.org/ittf/PubliclyAvailableStandards/ISO_19139_Schemas/
+
+-------------------------------------------------------------------------------
+
+2012-07-13 Nicolas Lesage on behalf of the ISO/TC 211 XML Maintenance Group
+	* Update of readme.txt file and schema annotations
+	* Use of absolute schema locations of imported namespaces
+	* Simplification of the schema location of included XML Schemas
+	* Adoption of W3C Implementation of XLink:
+		- schemaLocation changed to: http://www.w3.org/1999/xlink.xsd
+		- xlink:simpleLink renamed xlink:simpleAttrs
+	* Addition of the version attribute to the schema element. The value of
+	  this attribute is expected to be the date of the last release of the
+	  XML schemas (e.g. 2012-07-13 for this release)
+	* Include root XML Schema document in all schema documents
+
+	Validation: Schemas have been validated with XML Spy 2010 Rel. 2 (MSXML 6.0)
+
+2009-03-16 Marcellin Prudham & Nicolas Lesage
+	* Change of GML namespace: http://www.opengis.net/gml (GML 3.2) => 
+	                           http://www.opengis.net/gml/3.2 (GML 3.2.1=ISO 19136)
+							   
+	Note: ISO/TS 19139:2007 (published 2007-04-17) normatively reference
+	ISO 19136 which was	published 2007-08-23. The major change applied to
+	ISO 19136 is the change of the namespace URI. Previous release of GMX
+	are not compliant with ISO/TS 19139:2007
+	
+	Validation: Schemas have been validated with XSV 2.10, Xerces J 2.7.1 and 
+	XML Spy 2009 (2009-03-02, IGN / France - Nicolas Lesage / Marcellin Prudham)
+							   
+2006-05-04 Marie-Pierre Escher & Nicolas Lesage
+	* First official release of GMX
+	* GMX XML Schema files were generated from ISO/TC 211 UML class diagrams
+  	  in accordance with ISO/TS 19139:2007. The XML Schema generator is a
+	  Rational Rose Plug-in developed by IGN France (nicolas.lesage at ign.fr).
diff --git a/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gmx/catalogues.xsd b/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gmx/catalogues.xsd
new file mode 100644
index 0000000..4f6d6c2
--- /dev/null
+++ b/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gmx/catalogues.xsd
@@ -0,0 +1,113 @@
+<?xml version="1.0" encoding="utf-8"?>
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:gco="http://www.isotc211.org/2005/gco" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gmx="http://www.isotc211.org/2005/gmx" targetNamespace="http://www.isotc211.org/2005/gmx" elementFormDefault="qualified" version="2012-07-13">
+	<!-- ================================= Annotation ================================ -->
+	<xs:annotation>
+		<xs:documentation>Geographic Metadata XML (GMX) Schema is a component of the XML Schema Implementation of Geographic Information Metadata documented in ISO/TS 19139:2007. GMX includes all the definitions of http://www.isotc211.org/2005/gmx namespace. The root document of this namespace is the file gmx.xsd. This catalogues.xsd schema implements the UML conceptual schema defined in 7.4.4.1 of ISO/TS 19139:2007. It contains the implementation of CT_Catalogue, CT_CodelistCatalogue, CT_UomC [...]
+	</xs:annotation>
+	<!-- ================================== Imports ================================== -->
+	<xs:import namespace="http://www.isotc211.org/2005/gmd" schemaLocation="../gmd/gmd.xsd"/>
+	<xs:import namespace="http://www.isotc211.org/2005/gco" schemaLocation="../gco/gco.xsd"/>
+	<xs:include schemaLocation="gmx.xsd"/>
+	<xs:include schemaLocation="uomItem.xsd"/>
+	<xs:include schemaLocation="codelistItem.xsd"/>
+	<xs:include schemaLocation="crsItem.xsd"/>
+	<!-- ########################################################################### -->
+	<!-- ########################################################################### -->
+	<!-- ================================== Classes ================================= -->
+	<xs:complexType name="AbstractCT_Catalogue_Type" abstract="true">
+		<xs:complexContent>
+			<xs:extension base="gco:AbstractObject_Type">
+				<xs:sequence>
+					<xs:element name="name" type="gco:CharacterString_PropertyType"/>
+					<xs:element name="scope" type="gco:CharacterString_PropertyType" maxOccurs="unbounded"/>
+					<xs:element name="fieldOfApplication" type="gco:CharacterString_PropertyType" minOccurs="0" maxOccurs="unbounded"/>
+					<xs:element name="versionNumber" type="gco:CharacterString_PropertyType"/>
+					<xs:element name="versionDate" type="gco:Date_PropertyType"/>
+					<xs:element name="language" type="gco:CharacterString_PropertyType" minOccurs="0"/>
+					<xs:element name="characterSet" type="gmd:MD_CharacterSetCode_PropertyType" minOccurs="0"/>
+					<xs:element name="locale" type="gmd:PT_Locale_PropertyType" minOccurs="0" maxOccurs="unbounded"/>
+					<xs:element name="subCatalogue" type="gmx:CT_Catalogue_PropertyType" minOccurs="0" maxOccurs="unbounded"/>
+				</xs:sequence>
+			</xs:extension>
+		</xs:complexContent>
+	</xs:complexType>
+	<!-- ........................................................................ -->
+	<xs:element name="AbstractCT_Catalogue" type="gmx:AbstractCT_Catalogue_Type" abstract="true"/>
+	<!-- ........................................................................ -->
+	<xs:complexType name="CT_Catalogue_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gmx:AbstractCT_Catalogue"/>
+		</xs:sequence>
+		<xs:attributeGroup ref="gco:ObjectReference"/>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+	<xs:complexType name="CT_CodelistCatalogue_Type">
+		<xs:complexContent>
+			<xs:extension base="gmx:AbstractCT_Catalogue_Type">
+				<xs:sequence>
+					<xs:element name="codelistItem" type="gmx:CT_Codelist_PropertyType" maxOccurs="unbounded"/>
+				</xs:sequence>
+			</xs:extension>
+		</xs:complexContent>
+	</xs:complexType>
+	<!-- ........................................................................ -->
+	<xs:element name="CT_CodelistCatalogue" type="gmx:CT_CodelistCatalogue_Type" substitutionGroup="gmx:AbstractCT_Catalogue"/>
+	<!-- ........................................................................ -->
+	<xs:complexType name="CT_CodelistCatalogue_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gmx:CT_CodelistCatalogue"/>
+		</xs:sequence>
+		<xs:attributeGroup ref="gco:ObjectReference"/>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+	<xs:complexType name="CT_CrsCatalogue_Type">
+		<xs:complexContent>
+			<xs:extension base="gmx:AbstractCT_Catalogue_Type">
+				<xs:sequence>
+					<xs:element name="crs" type="gmx:CT_CRS_PropertyType" maxOccurs="unbounded"/>
+					<xs:element name="coordinateSystem" type="gmx:CT_CoordinateSystem_PropertyType" minOccurs="0" maxOccurs="unbounded"/>
+					<xs:element name="axis" type="gmx:CT_CoordinateSystemAxis_PropertyType" minOccurs="0" maxOccurs="unbounded"/>
+					<xs:element name="datum" type="gmx:CT_Datum_PropertyType" minOccurs="0" maxOccurs="unbounded"/>
+					<xs:element name="ellipsoid" type="gmx:CT_Ellipsoid_PropertyType" minOccurs="0" maxOccurs="unbounded"/>
+					<xs:element name="primeMeridian" type="gmx:CT_PrimeMeridian_PropertyType" minOccurs="0" maxOccurs="unbounded"/>
+					<xs:element name="operation" type="gmx:CT_Operation_PropertyType" minOccurs="0" maxOccurs="unbounded"/>
+					<xs:element name="operationMethod" type="gmx:CT_OperationMethod_PropertyType" minOccurs="0" maxOccurs="unbounded"/>
+					<xs:element name="parameters" type="gmx:CT_OperationParameters_PropertyType" minOccurs="0" maxOccurs="unbounded"/>
+				</xs:sequence>
+			</xs:extension>
+		</xs:complexContent>
+	</xs:complexType>
+	<!-- ........................................................................ -->
+	<xs:element name="CT_CrsCatalogue" type="gmx:CT_CrsCatalogue_Type" substitutionGroup="gmx:AbstractCT_Catalogue"/>
+	<!-- ........................................................................ -->
+	<xs:complexType name="CT_CrsCatalogue_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gmx:CT_CrsCatalogue"/>
+		</xs:sequence>
+		<xs:attributeGroup ref="gco:ObjectReference"/>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+	<xs:complexType name="CT_UomCatalogue_Type">
+		<xs:complexContent>
+			<xs:extension base="gmx:AbstractCT_Catalogue_Type">
+				<xs:sequence>
+					<xs:element name="uomItem" type="gmx:UnitDefinition_PropertyType" maxOccurs="unbounded"/>
+				</xs:sequence>
+			</xs:extension>
+		</xs:complexContent>
+	</xs:complexType>
+	<!-- ........................................................................ -->
+	<xs:element name="CT_UomCatalogue" type="gmx:CT_UomCatalogue_Type" substitutionGroup="gmx:AbstractCT_Catalogue"/>
+	<!-- ........................................................................ -->
+	<xs:complexType name="CT_UomCatalogue_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gmx:CT_UomCatalogue"/>
+		</xs:sequence>
+		<xs:attributeGroup ref="gco:ObjectReference"/>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+</xs:schema>
diff --git a/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gmx/codelistItem.xsd b/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gmx/codelistItem.xsd
new file mode 100644
index 0000000..1ebe9ea
--- /dev/null
+++ b/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gmx/codelistItem.xsd
@@ -0,0 +1,169 @@
+<?xml version="1.0" encoding="utf-8"?>
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml/3.2" xmlns:gco="http://www.isotc211.org/2005/gco" xmlns:gmx="http://www.isotc211.org/2005/gmx" targetNamespace="http://www.isotc211.org/2005/gmx" elementFormDefault="qualified" version="2012-07-13">
+	<!-- ================================= Annotation ================================ -->
+	<xs:annotation>
+		<xs:documentation>Geographic Metadata XML (GMX) Schema is a component of the XML Schema Implementation of Geographic Information Metadata documented in ISO/TS 19139:2007. GMX includes all the definitions of http://www.isotc211.org/2005/gmx namespace. The root document of this namespace is the file gmx.xsd. This codelistItem.xsd schema implements the UML conceptual schema defined in 7.4.4.4 of ISO/TS 19139:2007. It contains the implementation of CT_Codelist and CT_CodelistValue.</xs:doc [...]
+	</xs:annotation>
+	<!-- ================================== Imports ================================== -->
+	<xs:import namespace="http://www.isotc211.org/2005/gco" schemaLocation="../gco/gco.xsd"/>
+	<xs:import namespace="http://www.opengis.net/gml/3.2" schemaLocation="../../../../../../../../../core/schemas/ogc/gml/3.2.1/gml.xsd"/>
+	<xs:import namespace="http://www.isotc211.org/2005/gmd" schemaLocation="../gmd/gmd.xsd"/>
+	<xs:include schemaLocation="gmx.xsd"/>
+	<!-- ########################################################################### -->
+	<!-- ########################################################################### -->
+	<!-- ================================== Classes ================================= -->
+	<!-- ........................................................................ -->
+	<!-- ........................................................................ -->
+	<xs:complexType name="CT_CodelistValue_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gmx:CodeDefinition"/>
+		</xs:sequence>
+		<xs:attributeGroup ref="gco:ObjectReference"/>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+	<!-- ........................................................................ -->
+	<!-- ........................................................................ -->
+	<xs:complexType name="CT_Codelist_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gmx:CodeListDictionary"/>
+		</xs:sequence>
+		<xs:attributeGroup ref="gco:ObjectReference"/>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+	<xs:complexType name="CodeDefinition_Type">
+		<xs:complexContent>
+			<xs:extension base="gml:DefinitionType"/>
+		</xs:complexContent>
+	</xs:complexType>
+	<!-- ........................................................................ -->
+	<xs:element name="CodeDefinition" type="gmx:CodeDefinition_Type" substitutionGroup="gml:Definition"/>
+	<!-- ........................................................................ -->
+	<xs:complexType name="CodeDefinition_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gmx:CodeDefinition"/>
+		</xs:sequence>
+		<xs:attributeGroup ref="gco:ObjectReference"/>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+	<xs:complexType name="CodeListDictionary_Type">
+		<xs:annotation>
+			<xs:documentation>Constraints: - 1) metadataProperty.card = 0 - 2) dictionaryEntry.card = 0</xs:documentation>
+		</xs:annotation>
+		<xs:complexContent>
+			<xs:extension base="gml:DictionaryType">
+				<xs:sequence>
+					<xs:element name="codeEntry" type="gmx:CodeDefinition_PropertyType" maxOccurs="unbounded"/>
+				</xs:sequence>
+			</xs:extension>
+		</xs:complexContent>
+	</xs:complexType>
+	<!-- ........................................................................ -->
+	<xs:element name="CodeListDictionary" type="gmx:CodeListDictionary_Type" substitutionGroup="gml:Dictionary"/>
+	<!-- ........................................................................ -->
+	<xs:complexType name="CodeListDictionary_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gmx:CodeListDictionary"/>
+		</xs:sequence>
+		<xs:attributeGroup ref="gco:ObjectReference"/>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+	<xs:complexType name="ML_CodeDefinition_Type">
+		<xs:complexContent>
+			<xs:extension base="gmx:CodeDefinition_Type">
+				<xs:sequence>
+					<xs:element name="alternativeExpression" type="gmx:CodeAlternativeExpression_PropertyType" maxOccurs="unbounded"/>
+				</xs:sequence>
+			</xs:extension>
+		</xs:complexContent>
+	</xs:complexType>
+	<!-- ........................................................................ -->
+	<xs:element name="ML_CodeDefinition" type="gmx:ML_CodeDefinition_Type" substitutionGroup="gmx:CodeDefinition"/>
+	<!-- ........................................................................ -->
+	<xs:complexType name="ML_CodeDefinition_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gmx:ML_CodeDefinition"/>
+		</xs:sequence>
+		<xs:attributeGroup ref="gco:ObjectReference"/>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+	<xs:complexType name="ML_CodeListDictionary_Type">
+		<xs:annotation>
+			<xs:documentation>Constraint: codeEntry.type = ML_CodeListDefinition</xs:documentation>
+		</xs:annotation>
+		<xs:complexContent>
+			<xs:extension base="gmx:CodeListDictionary_Type">
+				<xs:sequence>
+					<xs:element name="alternativeExpression" type="gmx:ClAlternativeExpression_PropertyType" maxOccurs="unbounded"/>
+				</xs:sequence>
+			</xs:extension>
+		</xs:complexContent>
+	</xs:complexType>
+	<!-- ........................................................................ -->
+	<xs:element name="ML_CodeListDictionary" type="gmx:ML_CodeListDictionary_Type" substitutionGroup="gmx:CodeListDictionary"/>
+	<!-- ........................................................................ -->
+	<xs:complexType name="ML_CodeListDictionary_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gmx:ML_CodeListDictionary"/>
+		</xs:sequence>
+		<xs:attributeGroup ref="gco:ObjectReference"/>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+	<!-- =========================================================================== -->
+	<!--===================== Alternative Expresssion type ===============================-->
+	<xs:complexType name="ClAlternativeExpression_Type">
+		<xs:annotation>
+			<xs:documentation>XML attributes contraints: - 1) Id is mandatory - 2) codeSpace (type xsd:anyURI) is mandatory</xs:documentation>
+		</xs:annotation>
+		<xs:complexContent>
+			<xs:extension base="gml:DefinitionType">
+				<xs:sequence>
+					<xs:element name="locale" type="gmd:PT_Locale_PropertyType"/>
+				</xs:sequence>
+				<xs:attribute name="codeSpace" type="xs:anyURI" use="required"/>
+			</xs:extension>
+		</xs:complexContent>
+	</xs:complexType>
+	<!-- ........................................................................ -->
+	<xs:element name="ClAlternativeExpression" type="gmx:ClAlternativeExpression_Type"/>
+	<!-- ........................................................................ -->
+	<xs:complexType name="ClAlternativeExpression_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gmx:ClAlternativeExpression"/>
+		</xs:sequence>
+		<xs:attributeGroup ref="gco:ObjectReference"/>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+	<!-- =========================================================================== -->
+	<xs:complexType name="CodeAlternativeExpression_Type">
+		<xs:annotation>
+			<xs:documentation>XML attributes contraints: - 1) Id is mandatory - 2) codeSpace (type xsd:anyURI) is mandatory</xs:documentation>
+		</xs:annotation>
+		<xs:complexContent>
+			<xs:extension base="gml:DefinitionType">
+				<xs:sequence>
+					<xs:element name="locale" type="gmd:PT_Locale_PropertyType" minOccurs="0"/>
+				</xs:sequence>
+				<xs:attribute name="codeSpace" type="xs:anyURI" use="required"/>
+			</xs:extension>
+		</xs:complexContent>
+	</xs:complexType>
+	<!-- ........................................................................ -->
+	<xs:element name="CodeAlternativeExpression" type="gmx:CodeAlternativeExpression_Type"/>
+	<!-- ........................................................................ -->
+	<xs:complexType name="CodeAlternativeExpression_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gmx:CodeAlternativeExpression"/>
+		</xs:sequence>
+		<xs:attributeGroup ref="gco:ObjectReference"/>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+	<!--===End Of File===-->
+</xs:schema>
diff --git a/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gmx/crsItem.xsd b/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gmx/crsItem.xsd
new file mode 100644
index 0000000..228feaf
--- /dev/null
+++ b/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gmx/crsItem.xsd
@@ -0,0 +1,1031 @@
+<?xml version="1.0" encoding="utf-8"?>
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gco="http://www.isotc211.org/2005/gco" xmlns:gml="http://www.opengis.net/gml/3.2" xmlns:gmx="http://www.isotc211.org/2005/gmx" targetNamespace="http://www.isotc211.org/2005/gmx" elementFormDefault="qualified" version="2012-07-13">
+	<!-- ================================= Annotation ================================ -->
+	<xs:annotation>
+		<xs:documentation>Geographic Metadata XML (GMX) Schema is a component of the XML Schema Implementation of Geographic Information Metadata documented in ISO/TS 19139:2007. GMX includes all the definitions of http://www.isotc211.org/2005/gmx namespace. The root document of this namespace is the file gmx.xsd. This crsItem.xsd schema implements the UML conceptual schema defined in 7.4.4.3 of ISO/TS 19139:2007. It contains the implementation of CT_CRS, CT_CoordinateSystem, CT_CoordinateSyst [...]
+	</xs:annotation>
+	<!-- ================================== Imports ================================== -->
+	<xs:import namespace="http://www.isotc211.org/2005/gco" schemaLocation="../gco/gco.xsd"/>
+	<xs:import namespace="http://www.opengis.net/gml/3.2" schemaLocation="../../../../../../../../../core/schemas/ogc/gml/3.2.1/gml.xsd"/>
+	<xs:import namespace="http://www.isotc211.org/2005/gmd" schemaLocation="../gmd/gmd.xsd"/>
+	<xs:include schemaLocation="gmx.xsd"/>
+	<!-- ########################################################################### -->
+	<!-- ########################################################################### -->
+	<!-- ================================== Classes ================================= -->
+	<!-- ........................................................................ -->
+	<!-- ........................................................................ -->
+	<xs:complexType name="CT_CRS_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gml:AbstractCRS"/>
+		</xs:sequence>
+		<xs:attributeGroup ref="gco:ObjectReference"/>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+	<!-- ........................................................................ -->
+	<!-- ........................................................................ -->
+	<xs:complexType name="CT_CoordinateSystem_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gml:AbstractCoordinateSystem"/>
+		</xs:sequence>
+		<xs:attributeGroup ref="gco:ObjectReference"/>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+	<!-- ........................................................................ -->
+	<!-- ........................................................................ -->
+	<xs:complexType name="CT_CoordinateSystemAxis_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gml:CoordinateSystemAxis"/>
+		</xs:sequence>
+		<xs:attributeGroup ref="gco:ObjectReference"/>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+	<!-- ........................................................................ -->
+	<!-- ........................................................................ -->
+	<xs:complexType name="CT_Datum_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gml:AbstractDatum"/>
+		</xs:sequence>
+		<xs:attributeGroup ref="gco:ObjectReference"/>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+	<!-- ........................................................................ -->
+	<!-- ........................................................................ -->
+	<xs:complexType name="CT_Ellipsoid_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gml:Ellipsoid"/>
+		</xs:sequence>
+		<xs:attributeGroup ref="gco:ObjectReference"/>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+	<!-- ........................................................................ -->
+	<!-- ........................................................................ -->
+	<xs:complexType name="CT_PrimeMeridian_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gml:PrimeMeridian"/>
+		</xs:sequence>
+		<xs:attributeGroup ref="gco:ObjectReference"/>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+	<!-- ........................................................................ -->
+	<!-- ........................................................................ -->
+	<xs:complexType name="CT_Operation_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gml:AbstractCoordinateOperation"/>
+		</xs:sequence>
+		<xs:attributeGroup ref="gco:ObjectReference"/>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+	<!-- ........................................................................ -->
+	<!-- ........................................................................ -->
+	<xs:complexType name="CT_OperationMethod_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gml:OperationMethod"/>
+		</xs:sequence>
+		<xs:attributeGroup ref="gco:ObjectReference"/>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+	<!-- ........................................................................ -->
+	<!-- ........................................................................ -->
+	<xs:complexType name="CT_OperationParameters_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gml:AbstractGeneralOperationParameter"/>
+		</xs:sequence>
+		<xs:attributeGroup ref="gco:ObjectReference"/>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!--============================= Multilingual types ===============================-->
+	<!--============================== GML extensions ===============================-->
+	<!--================ GML XSchema: coordinateReferenceSystems.xsd ==================-->
+	<xs:complexType name="ML_CompoundCRS_Type">
+		<xs:complexContent>
+			<xs:extension base="gml:CompoundCRSType">
+				<xs:sequence>
+					<xs:element name="alternativeExpression" type="gmx:CrsAlt_PropertyType" maxOccurs="unbounded"/>
+				</xs:sequence>
+			</xs:extension>
+		</xs:complexContent>
+	</xs:complexType>
+	<!-- ........................................................................ -->
+	<xs:element name="ML_CompoundCRS" type="gmx:ML_CompoundCRS_Type" substitutionGroup="gml:CompoundCRS"/>
+	<!-- ........................................................................ -->
+	<xs:complexType name="ML_CompoundCRS_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gmx:ML_CompoundCRS"/>
+		</xs:sequence>
+		<xs:attributeGroup ref="gco:ObjectReference"/>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+	<!--### gml:GeocentricCRS and gml:GeographicCRS were deprecated in 19136 DIS and replaced with gml:GeodeticCRS ###-->
+	<!--<xs:complexType name="ML_GeocentricCRS_Type">
+		<xs:complexContent>
+			<xs:extension base="gml:GeocentricCRSType">
+				<xs:sequence>
+					<xs:element name="alternativeExpression" type="gmx:CrsAlt_PropertyType" maxOccurs="unbounded"/>
+				</xs:sequence>
+			</xs:extension>
+		</xs:complexContent>
+	</xs:complexType>-->
+	<!-- ........................................................................ -->
+	<!--<xs:element name="ML_GeocentricCRS" type="gmx:ML_GeocentricCRS_Type" substitutionGroup="gml:GeocentricCRS"/>-->
+	<!-- ........................................................................ -->
+	<!--<xs:complexType name="ML_GeocentricCRS_PropertyType">
+		<xs:sequence>
+			<xs:element ref="gmx:ML_GeocentricCRS" minOccurs="0"/>
+		</xs:sequence>
+		<xs:attributeGroup ref="gco:ObjectReference"/>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>-->
+	<!-- =========================================================================== -->
+	<!--### gml:GeocentricCRS and gml:GeographicCRS were deprecated in 19136 DIS and replaced with gml:GeodeticCRS ###-->
+	<!--<xs:complexType name="ML_GeographicCRS_Type">
+		<xs:complexContent>
+			<xs:extension base="gml:GeographicCRSType">
+				<xs:sequence>
+					<xs:element name="alternativeExpression" type="gmx:CrsAlt_PropertyType" maxOccurs="unbounded"/>
+				</xs:sequence>
+			</xs:extension>
+		</xs:complexContent>
+	</xs:complexType>-->
+	<!-- ........................................................................ -->
+	<!--<xs:element name="ML_GeographicCRS" type="gmx:ML_GeographicCRS_Type" substitutionGroup="gml:GeographicCRS"/>-->
+	<!-- ........................................................................ -->
+	<!--<xs:complexType name="ML_GeographicCRS_PropertyType">
+		<xs:sequence>
+			<xs:element ref="gmx:ML_GeographicCRS" minOccurs="0"/>
+		</xs:sequence>
+		<xs:attributeGroup ref="gco:ObjectReference"/>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>-->
+	<!-- =========================================================================== -->
+	<xs:complexType name="ML_GeodeticCRS_Type">
+		<xs:complexContent>
+			<xs:extension base="gml:GeodeticCRSType">
+				<xs:sequence>
+					<xs:element name="alternativeExpression" type="gmx:CrsAlt_PropertyType" maxOccurs="unbounded"/>
+				</xs:sequence>
+			</xs:extension>
+		</xs:complexContent>
+	</xs:complexType>
+	<!-- ........................................................................ -->
+	<xs:element name="ML_GeodeticCRS" type="gmx:ML_GeodeticCRS_Type" substitutionGroup="gml:GeodeticCRS"/>
+	<!-- ........................................................................ -->
+	<xs:complexType name="ML_GeodeticCRS_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gmx:ML_GeodeticCRS"/>
+		</xs:sequence>
+		<xs:attributeGroup ref="gco:ObjectReference"/>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+	<xs:complexType name="ML_EngineeringCRS_Type">
+		<xs:complexContent>
+			<xs:extension base="gml:EngineeringCRSType">
+				<xs:sequence>
+					<xs:element name="alternativeExpression" type="gmx:CrsAlt_PropertyType" maxOccurs="unbounded"/>
+				</xs:sequence>
+			</xs:extension>
+		</xs:complexContent>
+	</xs:complexType>
+	<!-- ........................................................................ -->
+	<xs:element name="ML_EngineeringCRS" type="gmx:ML_EngineeringCRS_Type" substitutionGroup="gml:EngineeringCRS"/>
+	<!-- ........................................................................ -->
+	<xs:complexType name="ML_EngineeringCRS_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gmx:ML_EngineeringCRS"/>
+		</xs:sequence>
+		<xs:attributeGroup ref="gco:ObjectReference"/>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+	<xs:complexType name="ML_VerticalCRS_Type">
+		<xs:complexContent>
+			<xs:extension base="gml:VerticalCRSType">
+				<xs:sequence>
+					<xs:element name="alternativeExpression" type="gmx:CrsAlt_PropertyType" maxOccurs="unbounded"/>
+				</xs:sequence>
+			</xs:extension>
+		</xs:complexContent>
+	</xs:complexType>
+	<!-- ........................................................................ -->
+	<xs:element name="ML_VerticalCRS" type="gmx:ML_VerticalCRS_Type" substitutionGroup="gml:VerticalCRS"/>
+	<!-- ........................................................................ -->
+	<xs:complexType name="ML_VerticalCRS_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gmx:ML_VerticalCRS"/>
+		</xs:sequence>
+		<xs:attributeGroup ref="gco:ObjectReference"/>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+	<xs:complexType name="ML_TemporalCRS_Type">
+		<xs:complexContent>
+			<xs:extension base="gml:TemporalCRSType">
+				<xs:sequence>
+					<xs:element name="alternativeExpression" type="gmx:CrsAlt_PropertyType" maxOccurs="unbounded"/>
+				</xs:sequence>
+			</xs:extension>
+		</xs:complexContent>
+	</xs:complexType>
+	<!-- ........................................................................ -->
+	<xs:element name="ML_TemporalCRS" type="gmx:ML_TemporalCRS_Type" substitutionGroup="gml:TemporalCRS"/>
+	<!-- ........................................................................ -->
+	<xs:complexType name="ML_TemporalCRS_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gmx:ML_TemporalCRS"/>
+		</xs:sequence>
+		<xs:attributeGroup ref="gco:ObjectReference"/>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+	<xs:complexType name="ML_ImageCRS_Type">
+		<xs:complexContent>
+			<xs:extension base="gml:ImageCRSType">
+				<xs:sequence>
+					<xs:element name="alternativeExpression" type="gmx:CrsAlt_PropertyType" maxOccurs="unbounded"/>
+				</xs:sequence>
+			</xs:extension>
+		</xs:complexContent>
+	</xs:complexType>
+	<!-- ........................................................................ -->
+	<xs:element name="ML_ImageCRS" type="gmx:ML_ImageCRS_Type" substitutionGroup="gml:ImageCRS"/>
+	<!-- ........................................................................ -->
+	<xs:complexType name="ML_ImageCRS_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gmx:ML_ImageCRS"/>
+		</xs:sequence>
+		<xs:attributeGroup ref="gco:ObjectReference"/>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+	<xs:complexType name="ML_ProjectedCRS_Type">
+		<xs:complexContent>
+			<xs:extension base="gml:ProjectedCRSType">
+				<xs:sequence>
+					<xs:element name="alternativeExpression" type="gmx:CrsAlt_PropertyType" maxOccurs="unbounded"/>
+				</xs:sequence>
+			</xs:extension>
+		</xs:complexContent>
+	</xs:complexType>
+	<!-- ........................................................................ -->
+	<xs:element name="ML_ProjectedCRS" type="gmx:ML_ProjectedCRS_Type" substitutionGroup="gml:ProjectedCRS"/>
+	<!-- ........................................................................ -->
+	<xs:complexType name="ML_ProjectedCRS_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gmx:ML_ProjectedCRS"/>
+		</xs:sequence>
+		<xs:attributeGroup ref="gco:ObjectReference"/>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+	<xs:complexType name="ML_DerivedCRS_Type">
+		<xs:complexContent>
+			<xs:extension base="gml:DerivedCRSType">
+				<xs:sequence>
+					<xs:element name="alternativeExpression" type="gmx:CrsAlt_PropertyType" maxOccurs="unbounded"/>
+				</xs:sequence>
+			</xs:extension>
+		</xs:complexContent>
+	</xs:complexType>
+	<!-- ........................................................................ -->
+	<xs:element name="ML_DerivedCRS" type="gmx:ML_DerivedCRS_Type" substitutionGroup="gml:DerivedCRS"/>
+	<!-- ........................................................................ -->
+	<xs:complexType name="ML_DerivedCRS_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gmx:ML_DerivedCRS"/>
+		</xs:sequence>
+		<xs:attributeGroup ref="gco:ObjectReference"/>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+	<!--====================== GML XSchema: coordinateSystems.xsd =====================-->
+	<xs:complexType name="ML_CoordinateSystemAxis_Type">
+		<xs:complexContent>
+			<xs:extension base="gml:CoordinateSystemAxisType">
+				<xs:sequence>
+					<xs:element name="alternativeExpression" type="gmx:CoordinateSystemAxisAlt_PropertyType" maxOccurs="unbounded"/>
+				</xs:sequence>
+			</xs:extension>
+		</xs:complexContent>
+	</xs:complexType>
+	<!-- ........................................................................ -->
+	<xs:element name="ML_CoordinateSystemAxis" type="gmx:ML_CoordinateSystemAxis_Type" substitutionGroup="gml:CoordinateSystemAxis"/>
+	<!-- ........................................................................ -->
+	<xs:complexType name="ML_CoordinateSystemAxis_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gmx:ML_CoordinateSystemAxis"/>
+		</xs:sequence>
+		<xs:attributeGroup ref="gco:ObjectReference"/>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+	<xs:complexType name="ML_EllipsoidalCS_Type">
+		<xs:complexContent>
+			<xs:extension base="gml:EllipsoidalCSType">
+				<xs:sequence>
+					<xs:element name="alternativeExpression" type="gmx:CoordinateSystemAlt_PropertyType" maxOccurs="unbounded"/>
+				</xs:sequence>
+			</xs:extension>
+		</xs:complexContent>
+	</xs:complexType>
+	<!-- ........................................................................ -->
+	<xs:element name="ML_EllipsoidalCS" type="gmx:ML_EllipsoidalCS_Type" substitutionGroup="gml:EllipsoidalCS"/>
+	<!-- ........................................................................ -->
+	<xs:complexType name="ML_EllipsoidalCS_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gmx:ML_EllipsoidalCS"/>
+		</xs:sequence>
+		<xs:attributeGroup ref="gco:ObjectReference"/>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+	<xs:complexType name="ML_CartesianCS_Type">
+		<xs:complexContent>
+			<xs:extension base="gml:CartesianCSType">
+				<xs:sequence>
+					<xs:element name="alternativeExpression" type="gmx:CoordinateSystemAlt_PropertyType" maxOccurs="unbounded"/>
+				</xs:sequence>
+			</xs:extension>
+		</xs:complexContent>
+	</xs:complexType>
+	<!-- ........................................................................ -->
+	<xs:element name="ML_CartesianCS" type="gmx:ML_CartesianCS_Type" substitutionGroup="gml:CartesianCS"/>
+	<!-- ........................................................................ -->
+	<xs:complexType name="ML_CartesianCS_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gmx:ML_CartesianCS"/>
+		</xs:sequence>
+		<xs:attributeGroup ref="gco:ObjectReference"/>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+	<xs:complexType name="ML_AffineCS_Type">
+		<xs:complexContent>
+			<xs:extension base="gml:AffineCSType">
+				<xs:sequence>
+					<xs:element name="alternativeExpression" type="gmx:CoordinateSystemAlt_PropertyType" maxOccurs="unbounded"/>
+				</xs:sequence>
+			</xs:extension>
+		</xs:complexContent>
+	</xs:complexType>
+	<!-- ........................................................................ -->
+	<xs:element name="ML_AffineCS" type="gmx:ML_AffineCS_Type" substitutionGroup="gml:AffineCS"/>
+	<!-- ........................................................................ -->
+	<xs:complexType name="ML_AffineCS_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gmx:ML_AffineCS"/>
+		</xs:sequence>
+		<xs:attributeGroup ref="gco:ObjectReference"/>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+	<xs:complexType name="ML_UserDefinedCS_Type">
+		<xs:complexContent>
+			<xs:extension base="gml:UserDefinedCSType">
+				<xs:sequence>
+					<xs:element name="alternativeExpression" type="gmx:CoordinateSystemAlt_PropertyType" maxOccurs="unbounded"/>
+				</xs:sequence>
+			</xs:extension>
+		</xs:complexContent>
+	</xs:complexType>
+	<!-- ........................................................................ -->
+	<xs:element name="ML_UserDefinedCS" type="gmx:ML_UserDefinedCS_Type" substitutionGroup="gml:UserDefinedCS"/>
+	<!-- ........................................................................ -->
+	<xs:complexType name="ML_UserDefinedCS_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gmx:ML_UserDefinedCS"/>
+		</xs:sequence>
+		<xs:attributeGroup ref="gco:ObjectReference"/>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+	<xs:complexType name="ML_VerticalCS_Type">
+		<xs:complexContent>
+			<xs:extension base="gml:VerticalCSType">
+				<xs:sequence>
+					<xs:element name="alternativeExpression" type="gmx:CoordinateSystemAlt_PropertyType" maxOccurs="unbounded"/>
+				</xs:sequence>
+			</xs:extension>
+		</xs:complexContent>
+	</xs:complexType>
+	<!-- ........................................................................ -->
+	<xs:element name="ML_VerticalCS" type="gmx:ML_VerticalCS_Type" substitutionGroup="gml:VerticalCS"/>
+	<!-- ........................................................................ -->
+	<xs:complexType name="ML_VerticalCS_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gmx:ML_VerticalCS"/>
+		</xs:sequence>
+		<xs:attributeGroup ref="gco:ObjectReference"/>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+	<xs:complexType name="ML_TimeCS_Type">
+		<xs:complexContent>
+			<xs:extension base="gml:TimeCSType">
+				<xs:sequence>
+					<xs:element name="alternativeExpression" type="gmx:CoordinateSystemAlt_PropertyType" maxOccurs="unbounded"/>
+				</xs:sequence>
+			</xs:extension>
+		</xs:complexContent>
+	</xs:complexType>
+	<!-- ........................................................................ -->
+	<xs:element name="ML_TimeCS" type="gmx:ML_TimeCS_Type" substitutionGroup="gml:TimeCS"/>
+	<!-- ........................................................................ -->
+	<xs:complexType name="ML_TimeCS_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gmx:ML_TimeCS"/>
+		</xs:sequence>
+		<xs:attributeGroup ref="gco:ObjectReference"/>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+	<xs:complexType name="ML_CylindricalCS_Type">
+		<xs:complexContent>
+			<xs:extension base="gml:CylindricalCSType">
+				<xs:sequence>
+					<xs:element name="alternativeExpression" type="gmx:CoordinateSystemAlt_PropertyType" maxOccurs="unbounded"/>
+				</xs:sequence>
+			</xs:extension>
+		</xs:complexContent>
+	</xs:complexType>
+	<!-- ........................................................................ -->
+	<xs:element name="ML_CylindricalCS" type="gmx:ML_CylindricalCS_Type" substitutionGroup="gml:CylindricalCS"/>
+	<!-- ........................................................................ -->
+	<xs:complexType name="ML_CylindricalCS_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gmx:ML_CylindricalCS"/>
+		</xs:sequence>
+		<xs:attributeGroup ref="gco:ObjectReference"/>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+	<xs:complexType name="ML_SphericalCS_Type">
+		<xs:complexContent>
+			<xs:extension base="gml:SphericalCSType">
+				<xs:sequence>
+					<xs:element name="alternativeExpression" type="gmx:CoordinateSystemAlt_PropertyType" maxOccurs="unbounded"/>
+				</xs:sequence>
+			</xs:extension>
+		</xs:complexContent>
+	</xs:complexType>
+	<!-- ........................................................................ -->
+	<xs:element name="ML_SphericalCS" type="gmx:ML_SphericalCS_Type" substitutionGroup="gml:SphericalCS"/>
+	<!-- ........................................................................ -->
+	<xs:complexType name="ML_SphericalCS_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gmx:ML_SphericalCS"/>
+		</xs:sequence>
+		<xs:attributeGroup ref="gco:ObjectReference"/>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+	<xs:complexType name="ML_PolarCS_Type">
+		<xs:complexContent>
+			<xs:extension base="gml:PolarCSType">
+				<xs:sequence>
+					<xs:element name="alternativeExpression" type="gmx:CoordinateSystemAlt_PropertyType" maxOccurs="unbounded"/>
+				</xs:sequence>
+			</xs:extension>
+		</xs:complexContent>
+	</xs:complexType>
+	<!-- ........................................................................ -->
+	<xs:element name="ML_PolarCS" type="gmx:ML_PolarCS_Type" substitutionGroup="gml:PolarCS"/>
+	<!-- ........................................................................ -->
+	<xs:complexType name="ML_PolarCS_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gmx:ML_PolarCS"/>
+		</xs:sequence>
+		<xs:attributeGroup ref="gco:ObjectReference"/>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+	<xs:complexType name="ML_LinearCS_Type">
+		<xs:complexContent>
+			<xs:extension base="gml:LinearCSType">
+				<xs:sequence>
+					<xs:element name="alternativeExpression" type="gmx:CoordinateSystemAlt_PropertyType" maxOccurs="unbounded"/>
+				</xs:sequence>
+			</xs:extension>
+		</xs:complexContent>
+	</xs:complexType>
+	<!-- ........................................................................ -->
+	<xs:element name="ML_LinearCS" type="gmx:ML_LinearCS_Type" substitutionGroup="gml:LinearCS"/>
+	<!-- ........................................................................ -->
+	<xs:complexType name="ML_LinearCS_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gmx:ML_LinearCS"/>
+		</xs:sequence>
+		<xs:attributeGroup ref="gco:ObjectReference"/>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+	<!--========================== GML XSchema: datums.xsd ===========================-->
+	<xs:complexType name="ML_Ellipsoid_Type">
+		<xs:complexContent>
+			<xs:extension base="gml:EllipsoidType">
+				<xs:sequence>
+					<xs:element name="alternativeExpression" type="gmx:EllipsoidAlt_PropertyType" maxOccurs="unbounded"/>
+				</xs:sequence>
+			</xs:extension>
+		</xs:complexContent>
+	</xs:complexType>
+	<!-- ........................................................................ -->
+	<xs:element name="ML_Ellipsoid" type="gmx:ML_Ellipsoid_Type" substitutionGroup="gml:Ellipsoid"/>
+	<!-- ........................................................................ -->
+	<xs:complexType name="ML_Ellipsoid_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gmx:ML_Ellipsoid"/>
+		</xs:sequence>
+		<xs:attributeGroup ref="gco:ObjectReference"/>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+	<xs:complexType name="ML_PrimeMeridian_Type">
+		<xs:complexContent>
+			<xs:extension base="gml:PrimeMeridianType">
+				<xs:sequence>
+					<xs:element name="alternativeExpression" type="gmx:PrimeMeridianAlt_PropertyType" maxOccurs="unbounded"/>
+				</xs:sequence>
+			</xs:extension>
+		</xs:complexContent>
+	</xs:complexType>
+	<!-- ........................................................................ -->
+	<xs:element name="ML_PrimeMeridian" type="gmx:ML_PrimeMeridian_Type" substitutionGroup="gml:PrimeMeridian"/>
+	<!-- ........................................................................ -->
+	<xs:complexType name="ML_PrimeMeridian_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gmx:ML_PrimeMeridian"/>
+		</xs:sequence>
+		<xs:attributeGroup ref="gco:ObjectReference"/>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+	<xs:complexType name="ML_TemporalDatum_Type">
+		<xs:complexContent>
+			<xs:extension base="gml:TemporalDatumType">
+				<xs:sequence>
+					<xs:element name="alternativeExpression" type="gmx:DatumAlt_PropertyType" maxOccurs="unbounded"/>
+				</xs:sequence>
+			</xs:extension>
+		</xs:complexContent>
+	</xs:complexType>
+	<!-- ........................................................................ -->
+	<xs:element name="ML_TemporalDatum" type="gmx:ML_TemporalDatum_Type" substitutionGroup="gml:TemporalDatum"/>
+	<!-- ........................................................................ -->
+	<xs:complexType name="ML_TemporalDatum_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gmx:ML_TemporalDatum"/>
+		</xs:sequence>
+		<xs:attributeGroup ref="gco:ObjectReference"/>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+	<xs:complexType name="ML_VerticalDatum_Type">
+		<xs:complexContent>
+			<xs:extension base="gml:VerticalDatumType">
+				<xs:sequence>
+					<xs:element name="alternativeExpression" type="gmx:DatumAlt_PropertyType" maxOccurs="unbounded"/>
+				</xs:sequence>
+			</xs:extension>
+		</xs:complexContent>
+	</xs:complexType>
+	<!-- ........................................................................ -->
+	<xs:element name="ML_VerticalDatum" type="gmx:ML_VerticalDatum_Type" substitutionGroup="gml:VerticalDatum"/>
+	<!-- ........................................................................ -->
+	<xs:complexType name="ML_VerticalDatum_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gmx:ML_VerticalDatum"/>
+		</xs:sequence>
+		<xs:attributeGroup ref="gco:ObjectReference"/>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+	<xs:complexType name="ML_ImageDatum_Type">
+		<xs:complexContent>
+			<xs:extension base="gml:ImageDatumType">
+				<xs:sequence>
+					<xs:element name="alternativeExpression" type="gmx:DatumAlt_PropertyType" maxOccurs="unbounded"/>
+				</xs:sequence>
+			</xs:extension>
+		</xs:complexContent>
+	</xs:complexType>
+	<!-- ........................................................................ -->
+	<xs:element name="ML_ImageDatum" type="gmx:ML_ImageDatum_Type" substitutionGroup="gml:ImageDatum"/>
+	<!-- ........................................................................ -->
+	<xs:complexType name="ML_ImageDatum_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gmx:ML_ImageDatum"/>
+		</xs:sequence>
+		<xs:attributeGroup ref="gco:ObjectReference"/>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+	<xs:complexType name="ML_EngineeringDatum_Type">
+		<xs:complexContent>
+			<xs:extension base="gml:EngineeringDatumType">
+				<xs:sequence>
+					<xs:element name="alternativeExpression" type="gmx:DatumAlt_PropertyType" maxOccurs="unbounded"/>
+				</xs:sequence>
+			</xs:extension>
+		</xs:complexContent>
+	</xs:complexType>
+	<!-- ........................................................................ -->
+	<xs:element name="ML_EngineeringDatum" type="gmx:ML_EngineeringDatum_Type" substitutionGroup="gml:EngineeringDatum"/>
+	<!-- ........................................................................ -->
+	<xs:complexType name="ML_EngineeringDatum_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gmx:ML_EngineeringDatum"/>
+		</xs:sequence>
+		<xs:attributeGroup ref="gco:ObjectReference"/>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+	<xs:complexType name="ML_GeodeticDatum_Type">
+		<xs:complexContent>
+			<xs:extension base="gml:GeodeticDatumType">
+				<xs:sequence>
+					<xs:element name="alternativeExpression" type="gmx:DatumAlt_PropertyType" maxOccurs="unbounded"/>
+				</xs:sequence>
+			</xs:extension>
+		</xs:complexContent>
+	</xs:complexType>
+	<!-- ........................................................................ -->
+	<xs:element name="ML_GeodeticDatum" type="gmx:ML_GeodeticDatum_Type" substitutionGroup="gml:GeodeticDatum"/>
+	<!-- ........................................................................ -->
+	<xs:complexType name="ML_GeodeticDatum_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gmx:ML_GeodeticDatum"/>
+		</xs:sequence>
+		<xs:attributeGroup ref="gco:ObjectReference"/>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+	<!--==================== GML XSchema: coordinateOperations.xsd ======================-->
+	<xs:complexType name="ML_ConcatenatedOperation_Type">
+		<xs:complexContent>
+			<xs:extension base="gml:ConcatenatedOperationType">
+				<xs:sequence>
+					<xs:element name="alternativeExpression" type="gmx:OperationAlt_PropertyType" maxOccurs="unbounded"/>
+				</xs:sequence>
+			</xs:extension>
+		</xs:complexContent>
+	</xs:complexType>
+	<!-- ........................................................................ -->
+	<xs:element name="ML_ConcatenatedOperation" type="gmx:ML_ConcatenatedOperation_Type" substitutionGroup="gml:ConcatenatedOperation"/>
+	<!-- ........................................................................ -->
+	<xs:complexType name="ML_ConcatenatedOperation_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gmx:ML_ConcatenatedOperation"/>
+		</xs:sequence>
+		<xs:attributeGroup ref="gco:ObjectReference"/>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+	<xs:complexType name="ML_PassThroughOperation_Type">
+		<xs:complexContent>
+			<xs:extension base="gml:PassThroughOperationType">
+				<xs:sequence>
+					<xs:element name="alternativeExpression" type="gmx:OperationAlt_PropertyType" maxOccurs="unbounded"/>
+				</xs:sequence>
+			</xs:extension>
+		</xs:complexContent>
+	</xs:complexType>
+	<!-- ........................................................................ -->
+	<xs:element name="ML_PassThroughOperation" type="gmx:ML_PassThroughOperation_Type" substitutionGroup="gml:PassThroughOperation"/>
+	<!-- ........................................................................ -->
+	<xs:complexType name="ML_PassThroughOperation_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gmx:ML_PassThroughOperation"/>
+		</xs:sequence>
+		<xs:attributeGroup ref="gco:ObjectReference"/>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+	<xs:complexType name="ML_Transformation_Type">
+		<xs:complexContent>
+			<xs:extension base="gml:TransformationType">
+				<xs:sequence>
+					<xs:element name="alternativeExpression" type="gmx:OperationAlt_PropertyType" maxOccurs="unbounded"/>
+				</xs:sequence>
+			</xs:extension>
+		</xs:complexContent>
+	</xs:complexType>
+	<!-- ........................................................................ -->
+	<xs:element name="ML_Transformation" type="gmx:ML_Transformation_Type" substitutionGroup="gml:Transformation"/>
+	<!-- ........................................................................ -->
+	<xs:complexType name="ML_Transformation_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gmx:ML_Transformation"/>
+		</xs:sequence>
+		<xs:attributeGroup ref="gco:ObjectReference"/>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+	<xs:complexType name="ML_Conversion_Type">
+		<xs:complexContent>
+			<xs:extension base="gml:ConversionType">
+				<xs:sequence>
+					<xs:element name="alternativeExpression" type="gmx:OperationAlt_PropertyType" maxOccurs="unbounded"/>
+				</xs:sequence>
+			</xs:extension>
+		</xs:complexContent>
+	</xs:complexType>
+	<!-- ........................................................................ -->
+	<xs:element name="ML_Conversion" type="gmx:ML_Conversion_Type" substitutionGroup="gml:Conversion"/>
+	<!-- ........................................................................ -->
+	<xs:complexType name="ML_Conversion_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gmx:ML_Conversion"/>
+		</xs:sequence>
+		<xs:attributeGroup ref="gco:ObjectReference"/>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+	<xs:complexType name="ML_OperationMethod_Type">
+		<xs:complexContent>
+			<xs:extension base="gml:OperationMethodType">
+				<xs:sequence>
+					<xs:element name="alternativeExpression" type="gmx:OperationMethodAlt_PropertyType" maxOccurs="unbounded"/>
+				</xs:sequence>
+			</xs:extension>
+		</xs:complexContent>
+	</xs:complexType>
+	<!-- ........................................................................ -->
+	<xs:element name="ML_OperationMethod" type="gmx:ML_OperationMethod_Type" substitutionGroup="gml:OperationMethod"/>
+	<!-- ........................................................................ -->
+	<xs:complexType name="ML_OperationMethod_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gmx:ML_OperationMethod"/>
+		</xs:sequence>
+		<xs:attributeGroup ref="gco:ObjectReference"/>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+	<xs:complexType name="ML_OperationParameterGroup_Type">
+		<xs:complexContent>
+			<xs:extension base="gml:OperationParameterGroupType">
+				<xs:sequence>
+					<xs:element name="alternativeExpression" type="gmx:OperationParameterAlt_PropertyType" maxOccurs="unbounded"/>
+				</xs:sequence>
+			</xs:extension>
+		</xs:complexContent>
+	</xs:complexType>
+	<!-- ........................................................................ -->
+	<xs:element name="ML_OperationParameterGroup" type="gmx:ML_OperationParameterGroup_Type" substitutionGroup="gml:OperationParameterGroup"/>
+	<!-- ........................................................................ -->
+	<xs:complexType name="ML_OperationParameterGroup_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gmx:ML_OperationParameterGroup"/>
+		</xs:sequence>
+		<xs:attributeGroup ref="gco:ObjectReference"/>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+	<xs:complexType name="ML_OperationParameter_Type">
+		<xs:complexContent>
+			<xs:extension base="gml:OperationParameterType">
+				<xs:sequence>
+					<xs:element name="alternativeExpression" type="gmx:OperationParameterAlt_PropertyType" maxOccurs="unbounded"/>
+				</xs:sequence>
+			</xs:extension>
+		</xs:complexContent>
+	</xs:complexType>
+	<!-- ........................................................................ -->
+	<xs:element name="ML_OperationParameter" type="gmx:ML_OperationParameter_Type" substitutionGroup="gml:OperationParameter"/>
+	<!-- ........................................................................ -->
+	<xs:complexType name="ML_OperationParameter_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gmx:ML_OperationParameter"/>
+		</xs:sequence>
+		<xs:attributeGroup ref="gco:ObjectReference"/>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+	<!--===================== Alternative Expresssion types ==============================-->
+	<xs:complexType name="CrsAlt_Type">
+		<xs:annotation>
+			<xs:documentation>XML attributes contraints: - 1) Id is mandatory - 2) codeSpace (type xsd:anyURI) is mandatory</xs:documentation>
+		</xs:annotation>
+		<xs:complexContent>
+			<xs:extension base="gml:AbstractCRSType">
+				<xs:sequence>
+					<xs:element name="locale" type="gmd:PT_Locale_PropertyType"/>
+				</xs:sequence>
+				<xs:attribute name="codeSpace" type="xs:anyURI" use="required"/>
+			</xs:extension>
+		</xs:complexContent>
+	</xs:complexType>
+	<!-- ........................................................................ -->
+	<xs:element name="CrsAlt" type="gmx:CrsAlt_Type"/>
+	<!-- ........................................................................ -->
+	<xs:complexType name="CrsAlt_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gmx:CrsAlt"/>
+		</xs:sequence>
+		<xs:attributeGroup ref="gco:ObjectReference"/>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+	<xs:complexType name="CoordinateSystemAlt_Type">
+		<xs:annotation>
+			<xs:documentation>XML attributes contraints: - 1) Id is mandatory - 2) codeSpace (type xsd:anyURI) is mandatory</xs:documentation>
+		</xs:annotation>
+		<xs:complexContent>
+			<xs:extension base="gml:IdentifiedObjectType">
+				<xs:sequence>
+					<xs:element name="locale" type="gmd:PT_Locale_PropertyType"/>
+				</xs:sequence>
+				<xs:attributeGroup ref="gml:AggregationAttributeGroup"/>
+				<xs:attribute name="codeSpace" type="xs:anyURI" use="required"/>
+			</xs:extension>
+		</xs:complexContent>
+	</xs:complexType>
+	<!-- ........................................................................ -->
+	<xs:element name="CoordinateSystemAlt" type="gmx:CoordinateSystemAlt_Type"/>
+	<!-- ........................................................................ -->
+	<xs:complexType name="CoordinateSystemAlt_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gmx:CoordinateSystemAlt"/>
+		</xs:sequence>
+		<xs:attributeGroup ref="gco:ObjectReference"/>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+	<xs:complexType name="CoordinateSystemAxisAlt_Type">
+		<xs:annotation>
+			<xs:documentation>XML attributes contraints: - 1) Id is mandatory - 2) codeSpace (type xsd:anyURI) is mandatory</xs:documentation>
+		</xs:annotation>
+		<xs:complexContent>
+			<xs:extension base="gml:CoordinateSystemAxisType">
+				<xs:sequence>
+					<xs:element name="locale" type="gmd:PT_Locale_PropertyType"/>
+				</xs:sequence>
+				<xs:attribute name="codeSpace" type="xs:anyURI" use="required"/>
+			</xs:extension>
+		</xs:complexContent>
+	</xs:complexType>
+	<!-- ........................................................................ -->
+	<xs:element name="CoordinateSystemAxisAlt" type="gmx:CoordinateSystemAxisAlt_Type"/>
+	<!-- ........................................................................ -->
+	<xs:complexType name="CoordinateSystemAxisAlt_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gmx:CoordinateSystemAxisAlt"/>
+		</xs:sequence>
+		<xs:attributeGroup ref="gco:ObjectReference"/>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+	<xs:complexType name="DatumAlt_Type">
+		<xs:annotation>
+			<xs:documentation>XML attributes contraints: - 1) Id is mandatory - 2) codeSpace (type xsd:anyURI) is mandatory</xs:documentation>
+		</xs:annotation>
+		<xs:complexContent>
+			<xs:extension base="gml:AbstractDatumType">
+				<xs:sequence>
+					<xs:element name="locale" type="gmd:PT_Locale_PropertyType"/>
+				</xs:sequence>
+				<xs:attribute name="codeSpace" type="xs:anyURI" use="required"/>
+			</xs:extension>
+		</xs:complexContent>
+	</xs:complexType>
+	<!-- ........................................................................ -->
+	<xs:element name="DatumAlt" type="gmx:DatumAlt_Type"/>
+	<!-- ........................................................................ -->
+	<xs:complexType name="DatumAlt_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gmx:DatumAlt"/>
+		</xs:sequence>
+		<xs:attributeGroup ref="gco:ObjectReference"/>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+	<xs:complexType name="EllipsoidAlt_Type">
+		<xs:annotation>
+			<xs:documentation>XML attributes contraints: - 1) Id is mandatory - 2) codeSpace (type xsd:anyURI) is mandatory</xs:documentation>
+		</xs:annotation>
+		<xs:complexContent>
+			<xs:extension base="gml:IdentifiedObjectType">
+				<xs:sequence>
+					<xs:element name="locale" type="gmd:PT_Locale_PropertyType"/>
+				</xs:sequence>
+				<xs:attribute name="codeSpace" type="xs:anyURI" use="required"/>
+			</xs:extension>
+		</xs:complexContent>
+	</xs:complexType>
+	<!-- ........................................................................ -->
+	<xs:element name="EllipsoidAlt" type="gmx:EllipsoidAlt_Type"/>
+	<!-- ........................................................................ -->
+	<xs:complexType name="EllipsoidAlt_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gmx:EllipsoidAlt"/>
+		</xs:sequence>
+		<xs:attributeGroup ref="gco:ObjectReference"/>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+	<xs:complexType name="PrimeMeridianAlt_Type">
+		<xs:annotation>
+			<xs:documentation>XML attributes contraints: - 1) Id is mandatory - 2) codeSpace (type xsd:anyURI) is mandatory</xs:documentation>
+		</xs:annotation>
+		<xs:complexContent>
+			<xs:extension base="gml:IdentifiedObjectType">
+				<xs:sequence>
+					<xs:element name="locale" type="gmd:PT_Locale_PropertyType"/>
+				</xs:sequence>
+				<xs:attribute name="codeSpace" type="xs:anyURI" use="required"/>
+			</xs:extension>
+		</xs:complexContent>
+	</xs:complexType>
+	<!-- ........................................................................ -->
+	<xs:element name="PrimeMeridianAlt" type="gmx:PrimeMeridianAlt_Type"/>
+	<!-- ........................................................................ -->
+	<xs:complexType name="PrimeMeridianAlt_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gmx:PrimeMeridianAlt"/>
+		</xs:sequence>
+		<xs:attributeGroup ref="gco:ObjectReference"/>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+	<xs:complexType name="OperationAlt_Type">
+		<xs:annotation>
+			<xs:documentation>XML attributes contraints: - 1) Id is mandatory - 2) codeSpace (type xsd:anyURI) is mandatory</xs:documentation>
+		</xs:annotation>
+		<xs:complexContent>
+			<xs:extension base="gml:AbstractCoordinateOperationType">
+				<xs:sequence>
+					<xs:element name="locale" type="gmd:PT_Locale_PropertyType"/>
+				</xs:sequence>
+				<xs:attribute name="codeSpace" type="xs:anyURI" use="required"/>
+			</xs:extension>
+		</xs:complexContent>
+	</xs:complexType>
+	<!-- ........................................................................ -->
+	<xs:element name="OperationAlt" type="gmx:OperationAlt_Type"/>
+	<!-- ........................................................................ -->
+	<xs:complexType name="OperationAlt_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gmx:OperationAlt"/>
+		</xs:sequence>
+		<xs:attributeGroup ref="gco:ObjectReference"/>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+	<xs:complexType name="OperationMethodAlt_Type">
+		<xs:annotation>
+			<xs:documentation>XML attributes contraints: - 1) Id is mandatory - 2) codeSpace (type xsd:anyURI) is mandatory</xs:documentation>
+		</xs:annotation>
+		<xs:complexContent>
+			<xs:extension base="gml:IdentifiedObjectType">
+				<xs:sequence>
+					<xs:element name="locale" type="gmd:PT_Locale_PropertyType"/>
+				</xs:sequence>
+				<xs:attribute name="codeSpace" type="xs:anyURI" use="required"/>
+			</xs:extension>
+		</xs:complexContent>
+	</xs:complexType>
+	<!-- ........................................................................ -->
+	<xs:element name="OperationMethodAlt" type="gmx:OperationMethodAlt_Type"/>
+	<!-- ........................................................................ -->
+	<xs:complexType name="OperationMethodAlt_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gmx:OperationMethodAlt"/>
+		</xs:sequence>
+		<xs:attributeGroup ref="gco:ObjectReference"/>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+	<xs:complexType name="OperationParameterAlt_Type">
+		<xs:annotation>
+			<xs:documentation>XML attributes contraints: - 1) Id is mandatory - 2) codeSpace (type xsd:anyURI) is mandatory</xs:documentation>
+		</xs:annotation>
+		<xs:complexContent>
+			<xs:extension base="gml:OperationParameterType">
+				<xs:sequence>
+					<xs:element name="locale" type="gmd:PT_Locale_PropertyType"/>
+				</xs:sequence>
+				<xs:attribute name="codeSpace" type="xs:anyURI" use="required"/>
+			</xs:extension>
+		</xs:complexContent>
+	</xs:complexType>
+	<!-- ........................................................................ -->
+	<xs:element name="OperationParameterAlt" type="gmx:OperationParameterAlt_Type"/>
+	<!-- ........................................................................ -->
+	<xs:complexType name="OperationParameterAlt_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gmx:OperationParameterAlt"/>
+		</xs:sequence>
+		<xs:attributeGroup ref="gco:ObjectReference"/>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+	<!-- === End of file === -->
+</xs:schema>
diff --git a/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gmx/extendedTypes.xsd b/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gmx/extendedTypes.xsd
similarity index 80%
copy from pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gmx/extendedTypes.xsd
copy to pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gmx/extendedTypes.xsd
index 19553f2..761fae7 100644
--- a/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gmx/extendedTypes.xsd
+++ b/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gmx/extendedTypes.xsd
@@ -1,12 +1,13 @@
 <?xml version="1.0" encoding="utf-8"?>
-<xs:schema targetNamespace="http://www.isotc211.org/2005/gmx" elementFormDefault="qualified" version="0.1" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:gco="http://www.isotc211.org/2005/gco" xmlns:gmx="http://www.isotc211.org/2005/gmx">
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:gco="http://www.isotc211.org/2005/gco" xmlns:gmx="http://www.isotc211.org/2005/gmx" targetNamespace="http://www.isotc211.org/2005/gmx" elementFormDefault="qualified" version="2012-07-13">
 	<!-- ================================= Annotation ================================ -->
 	<xs:annotation>
-		<xs:documentation>This file was generated from ISO TC/211 UML class diagrams == 03-14-2005 12:00:20 ====== Handcrafted</xs:documentation>
+		<xs:documentation>Geographic Metadata XML (GMX) Schema is a component of the XML Schema Implementation of Geographic Information Metadata documented in ISO/TS 19139:2007. GMX includes all the definitions of http://www.isotc211.org/2005/gmx namespace. The root document of this namespace is the file gmx.xsd. This extendedTypes.xsd schema contains the XML definitions of FileName, Anchor and MimeFileType classes. These classes are fully described in 7.2 of ISO/TS 19139:2007.</xs:documentation>
 	</xs:annotation>
 	<!-- ================================== Imports ================================== -->
 	<xs:import namespace="http://www.isotc211.org/2005/gco" schemaLocation="../gco/gco.xsd"/>
-	<xs:import namespace="http://www.w3.org/1999/xlink" schemaLocation="../../../../../../../../../../pycsw/schemas/w3c/1999/xlink.xsd"/>
+	<xs:import namespace="http://www.w3.org/1999/xlink" schemaLocation="../../../../../../../../../core/schemas/w3c/1999/xlink.xsd"/>
+	<xs:include schemaLocation="gmx.xsd"/>
 	<!-- ########################################################################### -->
 	<!-- ########################################################################### -->
 	<!-- ================================== Classes ================================= -->
diff --git a/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gmx/gmx.xsd b/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gmx/gmx.xsd
new file mode 100644
index 0000000..0df5b37
--- /dev/null
+++ b/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gmx/gmx.xsd
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:gmx="http://www.isotc211.org/2005/gmx" targetNamespace="http://www.isotc211.org/2005/gmx" elementFormDefault="qualified" version="2012-07-13">
+	<!-- ================================= Annotation ================================ -->
+	<xs:annotation>
+		<xs:documentation>Geographic Metadata XML (GMX) Schema is a component of the XML Schema Implementation of Geographic Information Metadata documented in ISO/TS 19139:2007. GMX includes all the definitions of http://www.isotc211.org/2005/gmx namespace. The root document of this namespace is the file gmx.xsd.</xs:documentation>
+	</xs:annotation>
+	<!-- ================================== Imports ================================== -->
+	<xs:include schemaLocation="gmxUsage.xsd"/>
+	<!-- ########################################################################### -->
+	<!-- ########################################################################### -->
+	<!-- ================================== Classes ================================= -->
+</xs:schema>
diff --git a/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gmx/gmxUsage.xsd b/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gmx/gmxUsage.xsd
new file mode 100644
index 0000000..824e10b
--- /dev/null
+++ b/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gmx/gmxUsage.xsd
@@ -0,0 +1,128 @@
+<?xml version="1.0" encoding="utf-8"?>
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:gco="http://www.isotc211.org/2005/gco" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gmx="http://www.isotc211.org/2005/gmx" targetNamespace="http://www.isotc211.org/2005/gmx" elementFormDefault="qualified" version="2012-07-13">
+	<!-- ================================= Annotation ================================ -->
+	<xs:annotation>
+		<xs:documentation>Geographic Metadata XML (GMX) Schema is a component of the XML Schema Implementation of Geographic Information Metadata documented in ISO/TS 19139:2007. GMX includes all the definitions of http://www.isotc211.org/2005/gmx namespace. The root document of this namespace is the file gmx.xsd. This gmxUsage.xsd schema implements the UML conceptual schema defined in 7.4.1 of ISO/TS 19139:2007. It contains the implementation of the following classes: MX_Dataset, MX_Aggregate [...]
+	</xs:annotation>
+	<!-- ================================== Imports ================================== -->
+	<xs:import namespace="http://www.isotc211.org/2005/gmd" schemaLocation="../gmd/gmd.xsd"/>
+	<xs:import namespace="http://www.isotc211.org/2005/gco" schemaLocation="../gco/gco.xsd"/>
+	<xs:include schemaLocation="gmx.xsd"/>
+	<xs:include schemaLocation="catalogues.xsd"/>
+	<xs:include schemaLocation="extendedTypes.xsd"/>
+	<!-- ########################################################################### -->
+	<!-- ########################################################################### -->
+	<!-- ================================== Classes ================================= -->
+	<xs:complexType name="MX_Aggregate_Type">
+		<xs:complexContent>
+			<xs:extension base="gmd:AbstractDS_Aggregate_Type">
+				<xs:sequence>
+					<xs:element name="aggregateCatalogue" type="gmx:CT_Catalogue_PropertyType" minOccurs="0" maxOccurs="unbounded"/>
+					<xs:element name="aggregateFile" type="gmx:MX_SupportFile_PropertyType" minOccurs="0" maxOccurs="unbounded"/>
+				</xs:sequence>
+			</xs:extension>
+		</xs:complexContent>
+	</xs:complexType>
+	<!-- ........................................................................ -->
+	<xs:element name="MX_Aggregate" type="gmx:MX_Aggregate_Type" substitutionGroup="gmd:AbstractDS_Aggregate"/>
+	<!-- ........................................................................ -->
+	<xs:complexType name="MX_Aggregate_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gmx:MX_Aggregate"/>
+		</xs:sequence>
+		<xs:attributeGroup ref="gco:ObjectReference"/>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+	<xs:complexType name="MX_DataSet_Type">
+		<xs:complexContent>
+			<xs:extension base="gmd:DS_DataSet_Type">
+				<xs:sequence>
+					<xs:element name="dataFile" type="gmx:MX_DataFile_PropertyType" maxOccurs="unbounded"/>
+					<xs:element name="datasetCatalogue" type="gmx:CT_Catalogue_PropertyType" minOccurs="0" maxOccurs="unbounded"/>
+					<xs:element name="supportFile" type="gmx:MX_SupportFile_PropertyType" minOccurs="0" maxOccurs="unbounded"/>
+				</xs:sequence>
+			</xs:extension>
+		</xs:complexContent>
+	</xs:complexType>
+	<!-- ........................................................................ -->
+	<xs:element name="MX_DataSet" type="gmx:MX_DataSet_Type" substitutionGroup="gmd:DS_DataSet"/>
+	<!-- ........................................................................ -->
+	<xs:complexType name="MX_DataSet_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gmx:MX_DataSet"/>
+		</xs:sequence>
+		<xs:attributeGroup ref="gco:ObjectReference"/>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+	<xs:complexType name="MX_DataFile_Type">
+		<xs:complexContent>
+			<xs:extension base="gmx:AbstractMX_File_Type">
+				<xs:sequence>
+					<xs:element name="featureTypes" type="gco:GenericName_PropertyType" minOccurs="0" maxOccurs="unbounded"/>
+					<xs:element name="fileFormat" type="gmd:MD_Format_PropertyType"/>
+				</xs:sequence>
+			</xs:extension>
+		</xs:complexContent>
+	</xs:complexType>
+	<!-- ........................................................................ -->
+	<xs:element name="MX_DataFile" type="gmx:MX_DataFile_Type" substitutionGroup="gmx:AbstractMX_File"/>
+	<!-- ........................................................................ -->
+	<xs:complexType name="MX_DataFile_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gmx:MX_DataFile"/>
+		</xs:sequence>
+		<xs:attributeGroup ref="gco:ObjectReference"/>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+	<xs:complexType name="MX_SupportFile_Type">
+		<xs:complexContent>
+			<xs:extension base="gmx:AbstractMX_File_Type"/>
+		</xs:complexContent>
+	</xs:complexType>
+	<!-- ........................................................................ -->
+	<xs:element name="MX_SupportFile" type="gmx:MX_SupportFile_Type" substitutionGroup="gmx:AbstractMX_File"/>
+	<!-- ........................................................................ -->
+	<xs:complexType name="MX_SupportFile_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gmx:MX_SupportFile"/>
+		</xs:sequence>
+		<xs:attributeGroup ref="gco:ObjectReference"/>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+	<xs:complexType name="AbstractMX_File_Type" abstract="true">
+		<xs:complexContent>
+			<xs:extension base="gco:AbstractObject_Type">
+				<xs:sequence>
+					<xs:element name="fileName" type="gmx:FileName_PropertyType"/>
+					<xs:element name="fileDescription" type="gco:CharacterString_PropertyType"/>
+					<xs:element name="fileType" type="gmx:MimeFileType_PropertyType"/>
+				</xs:sequence>
+			</xs:extension>
+		</xs:complexContent>
+	</xs:complexType>
+	<!-- ........................................................................ -->
+	<xs:element name="AbstractMX_File" type="gmx:AbstractMX_File_Type" abstract="true"/>
+	<!-- ........................................................................ -->
+	<xs:complexType name="MX_File_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gmx:AbstractMX_File"/>
+		</xs:sequence>
+		<xs:attributeGroup ref="gco:ObjectReference"/>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+	<!-- ........................................................................ -->
+	<xs:element name="MX_ScopeCode" type="gco:CodeListValue_Type" substitutionGroup="gmd:MD_ScopeCode"/>
+	<!-- ........................................................................ -->
+	<xs:complexType name="MX_ScopeCode_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gmx:MX_ScopeCode"/>
+		</xs:sequence>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+</xs:schema>
diff --git a/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gmx/uomItem.xsd b/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gmx/uomItem.xsd
new file mode 100644
index 0000000..cdd8d4c
--- /dev/null
+++ b/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gmx/uomItem.xsd
@@ -0,0 +1,163 @@
+<?xml version="1.0" encoding="utf-8"?>
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml/3.2" xmlns:gco="http://www.isotc211.org/2005/gco" xmlns:gmx="http://www.isotc211.org/2005/gmx" targetNamespace="http://www.isotc211.org/2005/gmx" elementFormDefault="qualified" version="2012-07-13">
+	<!-- ================================= Annotation ================================ -->
+	<xs:annotation>
+		<xs:documentation>Geographic Metadata XML (GMX) Schema is a component of the XML Schema Implementation of Geographic Information Metadata documented in ISO/TS 19139:2007. GMX includes all the definitions of http://www.isotc211.org/2005/gmx namespace. The root document of this namespace is the file gmx.xsd. This uomItem.xsd schema implements the UML conceptual schema defined in 7.4.4.2 of ISO/TS 19139:2007. It contains the implementation of the UnitDefinition class.</xs:documentation>
+	</xs:annotation>
+	<!-- ================================== Imports ================================== -->
+	<xs:import namespace="http://www.isotc211.org/2005/gco" schemaLocation="../gco/gco.xsd"/>
+	<xs:import namespace="http://www.opengis.net/gml/3.2" schemaLocation="../../../../../../../../../core/schemas/ogc/gml/3.2.1/gml.xsd"/>
+	<xs:import namespace="http://www.isotc211.org/2005/gmd" schemaLocation="../gmd/gmd.xsd"/>
+	<xs:include schemaLocation="gmx.xsd"/>
+	<!-- ########################################################################### -->
+	<!-- ########################################################################### -->
+	<!-- ================================== Classes ================================= -->
+	<!-- ........................................................................ -->
+	<!-- ........................................................................ -->
+	<xs:complexType name="UnitDefinition_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gml:UnitDefinition"/>
+		</xs:sequence>
+		<xs:attributeGroup ref="gco:ObjectReference"/>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+	<!-- ........................................................................ -->
+	<!-- ........................................................................ -->
+	<xs:complexType name="BaseUnit_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gml:BaseUnit"/>
+		</xs:sequence>
+		<xs:attributeGroup ref="gco:ObjectReference"/>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+	<!-- ........................................................................ -->
+	<!-- ........................................................................ -->
+	<xs:complexType name="DerivedUnit_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gml:DerivedUnit"/>
+		</xs:sequence>
+		<xs:attributeGroup ref="gco:ObjectReference"/>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+	<!-- ........................................................................ -->
+	<!-- ........................................................................ -->
+	<xs:complexType name="ConventionalUnit_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gml:ConventionalUnit"/>
+		</xs:sequence>
+		<xs:attributeGroup ref="gco:ObjectReference"/>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+	<xs:complexType name="ML_BaseUnit_Type">
+		<xs:complexContent>
+			<xs:extension base="gml:BaseUnitType">
+				<xs:sequence>
+					<xs:element name="alternativeExpression" type="gmx:UomAlternativeExpression_PropertyType" maxOccurs="unbounded"/>
+				</xs:sequence>
+			</xs:extension>
+		</xs:complexContent>
+	</xs:complexType>
+	<!-- ........................................................................ -->
+	<xs:element name="ML_BaseUnit" type="gmx:ML_BaseUnit_Type" substitutionGroup="gml:BaseUnit"/>
+	<!-- ........................................................................ -->
+	<xs:complexType name="ML_BaseUnit_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gmx:ML_BaseUnit"/>
+		</xs:sequence>
+		<xs:attributeGroup ref="gco:ObjectReference"/>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+	<xs:complexType name="ML_DerivedUnit_Type">
+		<xs:complexContent>
+			<xs:extension base="gml:DerivedUnitType">
+				<xs:sequence>
+					<xs:element name="alternativeExpression" type="gmx:UomAlternativeExpression_PropertyType" maxOccurs="unbounded"/>
+				</xs:sequence>
+			</xs:extension>
+		</xs:complexContent>
+	</xs:complexType>
+	<!-- ........................................................................ -->
+	<xs:element name="ML_DerivedUnit" type="gmx:ML_DerivedUnit_Type" substitutionGroup="gml:DerivedUnit"/>
+	<!-- ........................................................................ -->
+	<xs:complexType name="ML_DerivedUnit_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gmx:ML_DerivedUnit"/>
+		</xs:sequence>
+		<xs:attributeGroup ref="gco:ObjectReference"/>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+	<xs:complexType name="ML_ConventionalUnit_Type">
+		<xs:complexContent>
+			<xs:extension base="gml:ConventionalUnitType">
+				<xs:sequence>
+					<xs:element name="alternativeExpression" type="gmx:UomAlternativeExpression_PropertyType" maxOccurs="unbounded"/>
+				</xs:sequence>
+			</xs:extension>
+		</xs:complexContent>
+	</xs:complexType>
+	<!-- ........................................................................ -->
+	<xs:element name="ML_ConventionalUnit" type="gmx:ML_ConventionalUnit_Type" substitutionGroup="gml:ConventionalUnit"/>
+	<!-- ........................................................................ -->
+	<xs:complexType name="ML_ConventionalUnit_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gmx:ML_ConventionalUnit"/>
+		</xs:sequence>
+		<xs:attributeGroup ref="gco:ObjectReference"/>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+	<xs:complexType name="ML_UnitDefinition_Type">
+		<xs:complexContent>
+			<xs:extension base="gml:UnitDefinitionType">
+				<xs:sequence>
+					<xs:element name="alternativeExpression" type="gmx:UomAlternativeExpression_PropertyType" maxOccurs="unbounded"/>
+				</xs:sequence>
+			</xs:extension>
+		</xs:complexContent>
+	</xs:complexType>
+	<!-- ........................................................................ -->
+	<xs:element name="ML_UnitDefinition" type="gmx:ML_UnitDefinition_Type" substitutionGroup="gml:UnitDefinition"/>
+	<!-- ........................................................................ -->
+	<xs:complexType name="ML_UnitDefinition_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gmx:ML_UnitDefinition"/>
+		</xs:sequence>
+		<xs:attributeGroup ref="gco:ObjectReference"/>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+	<!-- =========================================================================== -->
+	<!--===================== Alternative Expresssion type ===============================-->
+	<xs:complexType name="UomAlternativeExpression_Type">
+		<xs:annotation>
+			<xs:documentation>XML attributes contraints: - 1) Id is mandatory - 2) codeSpace (type xsd:anyURI) is mandatory</xs:documentation>
+		</xs:annotation>
+		<xs:complexContent>
+			<xs:extension base="gml:UnitDefinitionType">
+				<xs:sequence>
+					<xs:element name="locale" type="gmd:PT_Locale_PropertyType"/>
+				</xs:sequence>
+				<xs:attribute name="codeSpace" type="xs:anyURI" use="required"/>
+			</xs:extension>
+		</xs:complexContent>
+	</xs:complexType>
+	<!-- ........................................................................ -->
+	<xs:element name="UomAlternativeExpression" type="gmx:UomAlternativeExpression_Type"/>
+	<!-- ........................................................................ -->
+	<xs:complexType name="UomAlternativeExpression_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gmx:UomAlternativeExpression"/>
+		</xs:sequence>
+		<xs:attributeGroup ref="gco:ObjectReference"/>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+	<!-- =========================================================================== -->
+	<!-- === End of file === -->
+</xs:schema>
diff --git a/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gsr/ReadMe.txt b/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gsr/ReadMe.txt
new file mode 100644
index 0000000..6bbcd21
--- /dev/null
+++ b/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gsr/ReadMe.txt
@@ -0,0 +1,45 @@
+ISO(c) GSR schema ReadMe.txt
+------------------------------------------------------------------------------
+
+Geographic Spatial Referencing (GSR) extensible markup language
+
+GSR is a component of the XML Schema Implementation of Geographic
+Information Metadata documented in ISO/TS 19139:2007.
+
+GSR includes all the definitions of http://www.isotc211.org/2005/gsr
+namespace. The root document of this namespace is the file gsr.xsd.
+
+The most current schemas are available at:
+http://standards.iso.org/ittf/PubliclyAvailableStandards/ISO_19139_Schemas/
+
+-------------------------------------------------------------------------------
+
+2012-07-13 Nicolas Lesage on behalf of the ISO/TC 211 XML Maintenance Group
+	* Update of readme.txt file and schema annotations
+	* Use of absolute schema locations of imported namespaces
+	* Simplification of the schema location of included XML Schemas
+	* Addition of the version attribute to the schema element. The value of
+	  this attribute is expected to be the date of the last release of the
+	  XML schemas (e.g. 2012-07-13 for this release)
+	* Include root XML Schema document in all schema documents
+
+	Validation: Schemas have been validated with XML Spy 2010 Rel. 2 (MSXML 6.0)
+
+2009-03-16 Marcellin Prudham & Nicolas Lesage
+	* Change of GML namespace: http://www.opengis.net/gml (GML 3.2) => 
+	                           http://www.opengis.net/gml/3.2 (GML 3.2.1=ISO 19136)
+							   
+	Note: ISO/TS 19139:2007 (published 2007-04-17) normatively reference
+	ISO 19136 which was	published 2007-08-23. The major change applied to
+	ISO 19136 is the change of the namespace URI. Previous release of GSR
+	are not compliant with ISO/TS 19139:2007
+	
+	Validation: Schemas have been validated with XSV 2.10, Xerces J 2.7.1 and 
+	XML Spy 2009 (2009-03-02, IGN / France - Nicolas Lesage / Marcellin Prudham)
+							   
+2006-05-04 Marie-Pierre Escher & Nicolas Lesage 
+	* First official release of GSR
+	* GSR XML Schema files were generated from ISO/TC 211 UML class diagrams
+  	  in accordance with ISO/TS 19139:2007. The XML Schema generator is a
+	  Rational Rose Plug-in developed by IGN France (http://www.ign.fr).
+
diff --git a/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gsr/gsr.xsd b/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gsr/gsr.xsd
new file mode 100644
index 0000000..a3aacf3
--- /dev/null
+++ b/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gsr/gsr.xsd
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+<xs:schema targetNamespace="http://www.isotc211.org/2005/gsr" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:gsr="http://www.isotc211.org/2005/gsr" version="2012-07-13">
+	<!-- ================================= Annotation ================================ -->
+	<xs:annotation>
+		<xs:documentation>Geographic Spatial Referencing (GSR) extensible markup language is a component of the XML Schema Implementation of Geographic Information Metadata documented in ISO/TS 19139:2007. GSR includes all the definitions of http://www.isotc211.org/2005/gsr namespace. The root document of this namespace is the file gsr.xsd.</xs:documentation>
+	</xs:annotation>
+	<!-- ================================== Imports ================================== -->
+	<xs:include schemaLocation="spatialReferencing.xsd"/>
+	<!-- ########################################################################### -->
+	<!-- ########################################################################### -->
+	<!-- ================================== Classes ================================= -->
+</xs:schema>
diff --git a/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gsr/spatialReferencing.xsd b/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gsr/spatialReferencing.xsd
new file mode 100644
index 0000000..65ecbf8
--- /dev/null
+++ b/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gsr/spatialReferencing.xsd
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:gml="http://www.opengis.net/gml/3.2" xmlns:gco="http://www.isotc211.org/2005/gco" xmlns:gsr="http://www.isotc211.org/2005/gsr" targetNamespace="http://www.isotc211.org/2005/gsr" elementFormDefault="qualified" version="2012-07-13">
+	<!-- ================================= Annotation ================================ -->
+	<xs:annotation>
+		<xs:documentation>Geographic Spatial Referencing (GSR) extensible markup language is a component of the XML Schema Implementation of Geographic Information Metadata documented in ISO/TS 19139:2007. GSR includes all the definitions of http://www.isotc211.org/2005/gsr namespace. The root document of this namespace is the file gsr.xsd. This spatialReferencing.xsd schema contains the implementation of SC_CRS. The encoding of this class is mapped to an ISO 19136 XML type.</xs:documentation>
+	</xs:annotation>
+	<!-- ================================== Imports ================================== -->
+	<xs:import namespace="http://www.isotc211.org/2005/gco" schemaLocation="../gco/gco.xsd"/>
+	<xs:import namespace="http://www.opengis.net/gml/3.2" schemaLocation="../../../../../../../../../core/schemas/ogc/gml/3.2.1/gml.xsd"/>
+	<xs:include schemaLocation="gsr.xsd"/>
+	<!-- ########################################################################### -->
+	<!-- ########################################################################### -->
+	<!-- ================================== Classes ================================= -->
+	<!-- ........................................................................ -->
+	<!--==XCGE: gml:AbstractCRS==-->
+	<!-- ........................................................................ -->
+	<xs:complexType name="SC_CRS_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gml:AbstractCRS"/>
+		</xs:sequence>
+		<xs:attributeGroup ref="gco:ObjectReference"/>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+</xs:schema>
diff --git a/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gss/ReadMe.txt b/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gss/ReadMe.txt
new file mode 100644
index 0000000..d1d377a
--- /dev/null
+++ b/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gss/ReadMe.txt
@@ -0,0 +1,44 @@
+ISO(c) GSS schema ReadMe.txt
+------------------------------------------------------------------------------
+
+Geographic Spatial Schema (GSS) extensible markup language
+
+GSS is a component of the XML Schema Implementation of Geographic
+Information Metadata documented in ISO/TS 19139:2007.
+
+GSS includes all the definitions of http://www.isotc211.org/2005/gss
+namespace. The root document of this namespace is the file gss.xsd.
+
+The most current schemas are available at:
+http://standards.iso.org/ittf/PubliclyAvailableStandards/ISO_19139_Schemas/
+
+-------------------------------------------------------------------------------
+
+2012-07-13 Nicolas Lesage on behalf of the ISO/TC 211 XML Maintenance Group
+	* Update of readme.txt file and schema annotations
+	* Use of absolute schema locations of imported namespaces
+	* Simplification of the schema location of included XML Schemas
+	* Addition of the version attribute to the schema element. The value of
+	  this attribute is expected to be the date of the last release of the
+	  XML schemas (e.g. 2012-07-13 for this release)
+	* Include root XML Schema document in all schema documents
+
+	Validation: Schemas have been validated with XML Spy 2010 Rel. 2 (MSXML 6.0)
+
+2009-03-16 Marcellin Prudham & Nicolas Lesage
+	* Change of GML namespace: http://www.opengis.net/gml (GML 3.2) => 
+	                           http://www.opengis.net/gml/3.2 (GML 3.2.1=ISO 19136)
+							   
+	Note: ISO/TS 19139:2007 (published 2007-04-17) normatively reference
+	ISO 19136 which was	published 2007-08-23. The major change applied to
+	ISO 19136 is the change of the namespace URI. Previous release of GSS
+	are not compliant with ISO/TS 19139:2007
+	
+	Validation: Schemas have been validated with XSV 2.10, Xerces J 2.7.1 and 
+	XML Spy 2009 (2009-03-02, IGN / France - Nicolas Lesage / Marcellin Prudham)
+							   
+2006-05-04 Marie-Pierre Escher & Nicolas Lesage
+	* First official release of GSS
+	* GSS XML Schema files were generated from ISO/TC 211 UML class diagrams
+  	  in accordance with ISO/TS 19139:2007. The XML Schema generator is a
+	  Rational Rose Plug-in developed by IGN France (nicolas.lesage at ign.fr).
diff --git a/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gss/geometry.xsd b/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gss/geometry.xsd
new file mode 100644
index 0000000..2e93ea6
--- /dev/null
+++ b/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gss/geometry.xsd
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="utf-8"?>
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:gco="http://www.isotc211.org/2005/gco" xmlns:gml="http://www.opengis.net/gml/3.2" xmlns:gss="http://www.isotc211.org/2005/gss" targetNamespace="http://www.isotc211.org/2005/gss" elementFormDefault="qualified" version="2012-07-13">
+	<!-- ================================= Annotation ================================ -->
+	<xs:annotation>
+		<xs:documentation>Geographic Spatial Schema (GSS) extensible markup language is a component of the XML Schema Implementation of Geographic Information Metadata documented in ISO/TS 19139:2007. GSS includes all the definitions of http://www.isotc211.org/2005/gss namespace. The root document of this namespace is the file gss.xsd. This geometry.xsd schema contains the implementation of GM_Object and GM_Point. The encoding of these classes is mapped to ISO 19136 geometric types.</xs:docume [...]
+	</xs:annotation>
+	<!-- ================================== Imports ================================== -->
+	<xs:import namespace="http://www.opengis.net/gml/3.2" schemaLocation="../../../../../../../../../core/schemas/ogc/gml/3.2.1/gml.xsd"/>
+	<xs:import namespace="http://www.isotc211.org/2005/gco" schemaLocation="../gco/gco.xsd"/>
+	<xs:include schemaLocation="gss.xsd"/>
+	<!-- ########################################################################### -->
+	<!-- ########################################################################### -->
+	<!-- ================================== Classes ================================= -->
+	<!-- ........................................................................ -->
+	<!--==XCGE: gml:Point==-->
+	<!-- ........................................................................ -->
+	<xs:complexType name="GM_Point_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gml:Point"/>
+		</xs:sequence>
+		<xs:attributeGroup ref="gco:ObjectReference"/>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+	<!-- ........................................................................ -->
+	<!--==XCGE: gml:AbstractGeometry==-->
+	<!-- ........................................................................ -->
+	<xs:complexType name="GM_Object_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gml:AbstractGeometry"/>
+		</xs:sequence>
+		<xs:attributeGroup ref="gco:ObjectReference"/>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+</xs:schema>
diff --git a/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gss/gss.xsd b/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gss/gss.xsd
new file mode 100644
index 0000000..2594cfe
--- /dev/null
+++ b/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gss/gss.xsd
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+<xs:schema targetNamespace="http://www.isotc211.org/2005/gss" elementFormDefault="qualified"  xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:gss="http://www.isotc211.org/2005/gss" version="2012-07-13">
+	<!-- ================================= Annotation ================================ -->
+	<xs:annotation>
+		<xs:documentation>Geographic Spatial Schema (GSS) extensible markup language is a component of the XML Schema Implementation of Geographic Information Metadata documented in ISO/TS 19139:2007. GSS includes all the definitions of http://www.isotc211.org/2005/gss namespace. The root document of this namespace is the file gss.xsd.</xs:documentation>
+	</xs:annotation>
+	<!-- ================================== Imports ================================== -->
+	<xs:include schemaLocation="geometry.xsd"/>
+	<!-- ########################################################################### -->
+	<!-- ########################################################################### -->
+	<!-- ================================== Classes ================================= -->
+</xs:schema>
diff --git a/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gts/ReadMe.txt b/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gts/ReadMe.txt
new file mode 100644
index 0000000..29b1307
--- /dev/null
+++ b/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gts/ReadMe.txt
@@ -0,0 +1,44 @@
+ISO(c) GTS schema ReadMe.txt
+------------------------------------------------------------------------------
+
+Geographic Temporal Schema (GTS) extensible markup language
+
+GTS is a component of the XML Schema Implementation of Geographic
+Information Metadata documented in ISO/TS 19139:2007.
+
+GTS includes all the definitions of http://www.isotc211.org/2005/gts
+namespace. The root document of this namespace is the file gts.xsd.
+
+The most current schemas are available at:
+http://standards.iso.org/ittf/PubliclyAvailableStandards/ISO_19139_Schemas/
+
+-------------------------------------------------------------------------------
+
+2012-07-13 Nicolas Lesage on behalf of the ISO/TC 211 XML Maintenance Group
+	* Update of readme.txt file and schema annotations
+	* Use of absolute schema locations of imported namespaces
+	* Simplification of the schema location of included XML Schemas
+	* Addition of the version attribute to the schema element. The value of
+	  this attribute is expected to be the date of the last release of the
+	  XML schemas (e.g. 2012-07-13 for this release)
+	* Include root XML Schema document in all schema documents
+
+	Validation: Schemas have been validated with XML Spy 2010 Rel. 2 (MSXML 6.0)
+
+2009-03-16 Marcellin Prudham & Nicolas Lesage
+	* Change of GML namespace: http://www.opengis.net/gml (GML 3.2) => 
+	                           http://www.opengis.net/gml/3.2 (GML 3.2.1=ISO 19136)
+							   
+	Note: ISO/TS 19139:2007 (published 2007-04-17) normatively reference
+	ISO 19136 which was	published 2007-08-23. The major change applied to
+	ISO 19136 is the change of the namespace URI. Previous release of GTS
+	are not compliant with ISO/TS 19139:2007
+	
+	Validation: Schemas have been validated with XSV 2.10, Xerces J 2.7.1 and 
+	XML Spy 2009 (2009-03-02, IGN / France - Nicolas Lesage / Marcellin Prudham)
+							   
+2006-05-04 Marie-Pierre Escher & Nicolas Lesage
+	* First official release of GTS
+	* GTS XML Schema files were generated from ISO/TC 211 UML class diagrams
+  	  in accordance with ISO/TS 19139:2007. The XML Schema generator is a
+	  Rational Rose Plug-in developed by IGN France (http://www.ign.fr).
diff --git a/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gts/gts.xsd b/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gts/gts.xsd
new file mode 100644
index 0000000..a4184fd
--- /dev/null
+++ b/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gts/gts.xsd
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:gts="http://www.isotc211.org/2005/gts" targetNamespace="http://www.isotc211.org/2005/gts" elementFormDefault="qualified" version="2012-07-13">
+	<!-- ================================= Annotation ================================ -->
+	<xs:annotation>
+		<xs:documentation>Geographic Temporal Schema (GTS) extensible markup language is a component of the XML Schema Implementation of Geographic Information Metadata documented in ISO/TS 19139:2007. GTS includes all the definitions of http://www.isotc211.org/2005/gts namespace. The root document of this namespace is the file gts.xsd.</xs:documentation>
+	</xs:annotation>
+	<!-- ================================== Imports ================================== -->
+	<xs:include schemaLocation="temporalObjects.xsd"/>
+	<!-- ########################################################################### -->
+	<!-- ########################################################################### -->
+	<!-- ================================== Classes ================================= -->
+</xs:schema>
diff --git a/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gts/temporalObjects.xsd b/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gts/temporalObjects.xsd
new file mode 100644
index 0000000..6a37b3a
--- /dev/null
+++ b/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gts/temporalObjects.xsd
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:gco="http://www.isotc211.org/2005/gco" xmlns:gml="http://www.opengis.net/gml/3.2" xmlns:gts="http://www.isotc211.org/2005/gts" targetNamespace="http://www.isotc211.org/2005/gts" elementFormDefault="qualified" version="2012-07-13">
+	<!-- ================================= Annotation ================================ -->
+	<xs:annotation>
+		<xs:documentation>Geographic Temporal Schema (GTS) extensible markup language is a component of the XML Schema Implementation of Geographic Information Metadata documented in ISO/TS 19139:2007. GTS includes all the definitions of http://www.isotc211.org/2005/gts namespace. The root document of this namespace is the file gts.xsd. The temporalObjects.xsd schema contains the XML implementation of TM_Object, TM_Primitive and TM_PeriodDuration from ISO 19108. The encoding of these classes i [...]
+	</xs:annotation>
+	<!-- ================================== Imports ================================== -->
+	<xs:import namespace="http://www.opengis.net/gml/3.2" schemaLocation="../../../../../../../../../core/schemas/ogc/gml/3.2.1/gml.xsd"/>
+	<xs:import namespace="http://www.isotc211.org/2005/gco" schemaLocation="../gco/gco.xsd"/>
+	<xs:include schemaLocation="gts.xsd"/>
+	<!-- ########################################################################### -->
+	<!-- ########################################################################### -->
+	<!-- ================================== Classes ================================= -->
+	<!-- ........................................................................ -->
+	<!--==XCGE: gml:AbstractTimePrimitive==-->
+	<!-- ........................................................................ -->
+	<xs:complexType name="TM_Primitive_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gml:AbstractTimePrimitive"/>
+		</xs:sequence>
+		<xs:attributeGroup ref="gco:ObjectReference"/>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+	<!-- ........................................................................ -->
+	<xs:element name="TM_PeriodDuration" type="xs:duration"/>
+	<!-- ........................................................................ -->
+	<xs:complexType name="TM_PeriodDuration_PropertyType">
+		<xs:sequence minOccurs="0">
+			<xs:element ref="gts:TM_PeriodDuration"/>
+		</xs:sequence>
+		<xs:attribute ref="gco:nilReason"/>
+	</xs:complexType>
+	<!-- =========================================================================== -->
+</xs:schema>
diff --git a/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/resources/ReadMe.txt b/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/resources/ReadMe.txt
new file mode 100644
index 0000000..2cdbe53
--- /dev/null
+++ b/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/resources/ReadMe.txt
@@ -0,0 +1,20 @@
+ISO(c) - ISO/TS 19139:2007 resources
+------------------------------------------------------------------------------
+
+ISO/TS 19139:2007 resources are XML Files provided with the XML
+Schema Implementations defined in ISO/TS 19139-2. Those resources are:
+- Catalogues of Codelist, Units of measure (uom) and Coordinate Reference
+  Systems (CRS)
+- sample XML
+
+-------------------------------------------------------------------------------
+
+2012-07-13 Nicolas Lesage on behalf of the ISO/TC 211 XML Maintenance Group
+	* Update of Readme.txt file
+	* Use of absolute schema locations
+	* Adoption of W3C Implementation of XLink:
+
+	Validation: XML Files have been validated with XML Spy 2010 Rel. 2 (MSXML 6.0)
+
+
+No history...
diff --git a/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/resources/Codelist/ML_gmxCodelists.xml b/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/resources/codelist/ML_gmxCodelists.xml
similarity index 95%
copy from pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/resources/Codelist/ML_gmxCodelists.xml
copy to pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/resources/codelist/ML_gmxCodelists.xml
index 3400509..1008415 100644
--- a/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/resources/Codelist/ML_gmxCodelists.xml
+++ b/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/resources/codelist/ML_gmxCodelists.xml
@@ -1,5 +1,17 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<CT_CodelistCatalogue xmlns="http://www.isotc211.org/2005/gmx" xmlns:gco="http://www.isotc211.org/2005/gco" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.isotc211.org/2005/gmx ../../gmx/gmx.xsd http://www.isotc211.org/2005/gmd ../../gmd/gmd.xsd http://www.isotc211.org/2005/gco ../../gco/gco.xsd http://www.w3.org/1999/xlink . [...]
+<!-- 
+CORRECTIONS referenced 2012-07-13 #01
+AUTHOR: XML Maintenance group - Nicolas Lesage
+PURPOSE: Use of absolute path in xsi:schemaLocation
+DESCRIPTION:
+- ../gmx/gmx.xsd replaced by http://schemas.opengis.net/iso/19139/20070417/gmx/gmx.xsd
+- ../gmd/gmd.xsd replaced by http://schemas.opengis.net/iso/19139/20070417/gmd/gmd.xsd
+- ../gco/gco.xsd replaced by http://schemas.opengis.net/iso/19139/20070417/gco/gco.xsd
+- ../xlink/xlinks.xsd replaced by http://www.w3.org/1999/xlink.xsd
+- ../gml/gml.xsd replaced by http://schemas.opengis.net/gml/3.2.1/gml.xsd
+
+-->
+<CT_CodelistCatalogue xmlns="http://www.isotc211.org/2005/gmx" xmlns:gco="http://www.isotc211.org/2005/gco" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml/3.2" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.isotc211.org/2005/gmx http://schemas.opengis.net/iso/19139/20070417/gmx/gmx.xsd http://www.isotc211.org/2005/gmd http://schemas.opengis.net/iso/19139/20070417/gmd/gmd.x [...]
 	<!--=====Catalogue description=====-->
 	<name>
 		<gco:CharacterString>ML_gmxCodelists</gco:CharacterString>
@@ -23,14 +35,24 @@
 	</versionDate>
 	<!--=== for Cultural and Linguistic Adaptability ===-->
 	<!--Default language-->
-	<language><gmd:LanguageCode codeList="#LanguageCode" codeListValue="eng">English</gmd:LanguageCode></language>
-	<characterSet><gmd:MD_CharacterSetCode codeList="#MD_CharacterSetCode" codeListValue="utf8">UTF 8</gmd:MD_CharacterSetCode></characterSet>
+	<language>
+		<gmd:LanguageCode codeList="#LanguageCode" codeListValue="eng">English</gmd:LanguageCode>
+	</language>
+	<characterSet>
+		<gmd:MD_CharacterSetCode codeList="#MD_CharacterSetCode" codeListValue="utf8">UTF 8</gmd:MD_CharacterSetCode>
+	</characterSet>
 	<!-- List of the 'locales' into which free text values can be translated-->
 	<locale>
 		<gmd:PT_Locale id="fra">
-			<gmd:languageCode><gmd:LanguageCode codeList="#LanguageCode" codeListValue="fra">French</gmd:LanguageCode></gmd:languageCode>
-			<gmd:country><gmd:Country codeList="#Country" codeListValue="FR">France</gmd:Country></gmd:country>
-			<gmd:characterEncoding><gmd:MD_CharacterSetCode codeList="#MD_CharacterSetCode" codeListValue="utf8">UTF 8</gmd:MD_CharacterSetCode></gmd:characterEncoding>
+			<gmd:languageCode>
+				<gmd:LanguageCode codeList="#LanguageCode" codeListValue="fra">French</gmd:LanguageCode>
+			</gmd:languageCode>
+			<gmd:country>
+				<gmd:Country codeList="#Country" codeListValue="FR">France</gmd:Country>
+			</gmd:country>
+			<gmd:characterEncoding>
+				<gmd:MD_CharacterSetCode codeList="#MD_CharacterSetCode" codeListValue="utf8">UTF 8</gmd:MD_CharacterSetCode>
+			</gmd:characterEncoding>
 		</gmd:PT_Locale>
 	</locale>
 	<!--============================================================================-->
diff --git a/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/resources/Codelist/gmxCodelists.xml b/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/resources/codelist/gmxCodelists.xml
similarity index 97%
copy from pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/resources/Codelist/gmxCodelists.xml
copy to pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/resources/codelist/gmxCodelists.xml
index 9da91d5..e1dc5ba 100644
--- a/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/resources/Codelist/gmxCodelists.xml
+++ b/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/resources/codelist/gmxCodelists.xml
@@ -1,5 +1,32 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<CT_CodelistCatalogue xmlns="http://www.isotc211.org/2005/gmx" xmlns:gco="http://www.isotc211.org/2005/gco" xmlns:gml="http://www.opengis.net/gml" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.isotc211.org/2005/gmx ../../gmx/gmx.xsd http://www.isotc211.org/2005/gco ../../gco/gco.xsd http://www.opengis.net/gml ../../gml/gml.xsd http://www.w3.org/1999/xlink ../../../../../../../../pycsw/schemas/w3c/xlink/xlink.xsd">
+<!-- 
+CORRECTIONS referenced 2012-07-13 #01
+AUTHOR: XML Maintenance group - Nicolas Lesage
+PURPOSE: Use of absolute path in xsi:schemaLocation
+DESCRIPTION:
+- ../gmx/gmx.xsd replaced by http://schemas.opengis.net/iso/19139/20070417/gmx/gmx.xsd
+- ../gco/gco.xsd replaced by http://schemas.opengis.net/iso/19139/20070417/gco/gco.xsd
+- ../xlink/xlinks.xsd replaced by http://www.w3.org/1999/xlink.xsd
+- ../gml/gml.xsd replaced by http://schemas.opengis.net/gml/3.2.1/gml.xsd
+
+CORRECTIONS referenced 2012-07-13 #02
+AUTHOR: XML Maintenance group - Nicolas Lesage
+PURPOSE: Invalid description of MD_DatatypeCode_codelist
+DESCRIPTION:
+<gml:description>descriptor of a set of objects that share the same attributes, operations, methods, relationships, and behavior</gml:description>
+has been replaced by:
+<gml:description>flexible enumeration useful for expressing a long list of values, can be extended</gml:description>
+
+CORRECTIONS referenced by 2008-09-11 #NN
+AUTHOR : IGN (France) contact: nicolas.lesage at ign.fr
+PURPOSE : Correction of 3 typographical errors 
+DESCRIPTION : 
+#01: 'unknwon' replaced by 'unknown'
+#02: 'MD_MaintenanceFrequencyCode_quartely' replaced by 'MD_MaintenanceFrequencyCode_quarterly'
+#03: 'quartely' replaced by 'quarterly'
+-->
+<!-- 2012-07-13 #01 -->
+<CT_CodelistCatalogue xmlns="http://www.isotc211.org/2005/gmx" xmlns:gco="http://www.isotc211.org/2005/gco" xmlns:gml="http://www.opengis.net/gml/3.2" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.isotc211.org/2005/gmx http://schemas.opengis.net/iso/19139/20070417/gmx/gmx.xsd http://www.isotc211.org/2005/gco http://schemas.opengis.net/iso/19139/20070417/gco/gco.xsd http://www.opengis.net/gml/3.2 http://sche [...]
 	<!--=====Catalogue description=====-->
 	<name>
 		<gco:CharacterString>gmxCodelists</gco:CharacterString>
@@ -678,7 +705,8 @@
 			</codeEntry>
 			<codeEntry>
 				<CodeDefinition gml:id="MD_DatatypeCode_codelist">
-					<gml:description>descriptor of a set of objects that share the same attributes, operations, methods, relationships, and behavior</gml:description>
+					<!-- 2012-07-13 #02 -->
+					<gml:description>flexible enumeration useful for expressing a long list of values, can be extended</gml:description>
 					<gml:identifier codeSpace="ISOTC211/19115">codelist</gml:identifier>
 				</CodeDefinition>
 			</codeEntry>
@@ -1006,9 +1034,17 @@
 				</CodeDefinition>
 			</codeEntry>
 			<codeEntry>
+				<!-- CHANGE 2008-09-11 #02 -->
+				<CodeDefinition gml:id="MD_MaintenanceFrequencyCode_quarterly">
+				<!-- CHANGE 2008-09-11 #02
 				<CodeDefinition gml:id="MD_MaintenanceFrequencyCode_quartely">
+				-->
 					<gml:description>data is updated every three months</gml:description>
+					<!-- CHANGE 2008-09-11 #03 -->
+					<gml:identifier codeSpace="ISOTC211/19115">quarterly</gml:identifier>
+					<!-- CHANGE 2008-09-11 #03
 					<gml:identifier codeSpace="ISOTC211/19115">quartely</gml:identifier>
+					-->
 				</CodeDefinition>
 			</codeEntry>
 			<codeEntry>
@@ -1044,7 +1080,11 @@
 			<codeEntry>
 				<CodeDefinition gml:id="MD_MaintenanceFrequencyCode_unknown">
 					<gml:description>frequency of maintenance for the data is not known</gml:description>
+					<!-- CHANGE 2008-09-11 #01-->
+					<gml:identifier codeSpace="ISOTC211/19115">unknown</gml:identifier>
+					<!-- CHANGE 2008-09-11 #01
 					<gml:identifier codeSpace="ISOTC211/19115">unknwon</gml:identifier>
+					-->
 				</CodeDefinition>
 			</codeEntry>
 		</CodeListDictionary>
diff --git a/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/resources/codelist/tcCodelists.xml b/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/resources/codelist/tcCodelists.xml
new file mode 100644
index 0000000..aec0666
--- /dev/null
+++ b/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/resources/codelist/tcCodelists.xml
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+CORRECTIONS referenced 2012-07-13 #01
+AUTHOR: XML Maintenance group - Nicolas Lesage
+PURPOSE: Use of absolute path in xsi:schemaLocation
+DESCRIPTION:
+- ../gmx/gmx.xsd replaced by http://schemas.opengis.net/iso/19139/20070417/gmx/gmx.xsd
+- ../gco/gco.xsd replaced by http://schemas.opengis.net/iso/19139/20070417/gco/gco.xsd
+- ../xlink/xlinks.xsd replaced by http://www.w3.org/1999/xlink.xsd
+- ../gml/gml.xsd replaced by http://schemas.opengis.net/gml/3.2.1/gml.xsd
+
+-->
+<CT_CodelistCatalogue xmlns="http://www.isotc211.org/2005/gmx" xmlns:gco="http://www.isotc211.org/2005/gco" xmlns:gml="http://www.opengis.net/gml/3.2" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.isotc211.org/2005/gmx http://schemas.opengis.net/iso/19139/20070417/gmx/gmx.xsd http://www.isotc211.org/2005/gco http://schemas.opengis.net/iso/19139/20070417/gco/gco.xsd http://www.opengis.net/gml/3.2 http://sche [...]
+	<!--=====Catalogue description=====-->
+	<name>
+		<gco:CharacterString>tcCodelists</gco:CharacterString>
+	</name>
+	<scope>
+		<gco:CharacterString>Codelists used in the type catalogue schema</gco:CharacterString>
+	</scope>
+	<fieldOfApplication>
+		<gco:CharacterString>Type catalogues</gco:CharacterString>
+	</fieldOfApplication>
+	<versionNumber>
+		<gco:CharacterString>0.1</gco:CharacterString>
+	</versionNumber>
+	<versionDate>
+		<gco:Date>2007-06-14</gco:Date>
+	</versionDate>
+	<!--============================================================================-->
+	<!--============================================================================-->
+	<!--============================= Codelists =======================================-->
+	<codelistItem>
+		<CodeListDictionary gml:id="TC_AggregationType">
+			<gml:description>specifies aggregation semantics: specifies whether the value of each property is a single value ("noAggregation") which is the default case or if a single property instance has an aggregate value in which case the value specifies the aggregation type ("bag", "set", "sequence"). Note that this value is independent from the cardinality.</gml:description>
+			<gml:identifier codeSpace="urn:x-nato:def:schema-xsd:NATO:0.1:tc">TC_AggregationType</gml:identifier>
+			<codeEntry>
+				<CodeDefinition gml:id="TC_AggregationType_noAggregation">
+					<gml:description>single value - no aggregation (default)</gml:description>
+					<gml:identifier codeSpace="urn:x-nato:def:schema-xsd:NATO:0.1:tc">noAggregation</gml:identifier>
+				</CodeDefinition>
+			</codeEntry>
+			<codeEntry>
+				<CodeDefinition gml:id="TC_AggregationType_bag">
+					<gml:description>aggregation semantics: bag</gml:description>
+					<gml:identifier codeSpace="urn:x-nato:def:schema-xsd:NATO:0.1:tc">bag</gml:identifier>
+				</CodeDefinition>
+			</codeEntry>
+			<codeEntry>
+				<CodeDefinition gml:id="TC_AggregationType_set">
+					<gml:description>aggregation semantics: set</gml:description>
+					<gml:identifier codeSpace="urn:x-nato:def:schema-xsd:NATO:0.1:tc">set</gml:identifier>
+				</CodeDefinition>
+			</codeEntry>
+			<codeEntry>
+				<CodeDefinition gml:id="TC_AggregationType_sequence">
+					<gml:description>aggregation semantics: sequence (ordered bag)</gml:description>
+					<gml:identifier codeSpace="urn:x-nato:def:schema-xsd:NATO:0.1:tc">sequence</gml:identifier>
+				</CodeDefinition>
+			</codeEntry>
+		</CodeListDictionary>
+	</codelistItem>
+</CT_CodelistCatalogue>
diff --git a/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/resources/crs/ML_gmxCrs.xml b/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/resources/crs/ML_gmxCrs.xml
similarity index 52%
copy from pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/resources/crs/ML_gmxCrs.xml
copy to pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/resources/crs/ML_gmxCrs.xml
index ce3020a..c082d76 100644
--- a/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/resources/crs/ML_gmxCrs.xml
+++ b/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/resources/crs/ML_gmxCrs.xml
@@ -1,25 +1,60 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<CT_CrsCatalogue xmlns="http://www.isotc211.org/2005/gmx" xmlns:gco="http://www.isotc211.org/2005/gco" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.isotc211.org/2005/gmx ../../gmx/gmx.xsd http://www.isotc211.org/2005/gmd ../../gmd/gmd.xsd http://www.isotc211.org/2005/gco ../../gco/gco.xsd http://www.w3.org/1999/xlink ../../ [...]
+<!-- 
+CORRECTIONS referenced 2012-07-13 #01
+AUTHOR: XML Maintenance group - Nicolas Lesage
+PURPOSE: Use of absolute path in xsi:schemaLocation
+DESCRIPTION:
+- ../gmx/gmx.xsd replaced by http://schemas.opengis.net/iso/19139/20070417/gmx/gmx.xsd
+- ../gmd/gmd.xsd replaced by http://schemas.opengis.net/iso/19139/20070417/gmd/gmd.xsd
+- ../gco/gco.xsd replaced by http://schemas.opengis.net/iso/19139/20070417/gco/gco.xsd
+- ../xlink/xlinks.xsd replaced by http://www.w3.org/1999/xlink.xsd
+- ../gml/gml.xsd replaced by http://schemas.opengis.net/gml/3.2.1/gml.xsd
+
+-->
+<CT_CrsCatalogue xmlns="http://www.isotc211.org/2005/gmx" xmlns:gco="http://www.isotc211.org/2005/gco" xmlns:gml="http://www.opengis.net/gml/3.2" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.isotc211.org/2005/gmx http://schemas.opengis.net/iso/19139/20070417/gmx/gmx.xsd http://www.isotc211.org/2005/gmd http://schemas.opengis.net/iso/19139/20070417/gmd/gmd.xsd ht [...]
+
 	<!--=====Catalogue description=====-->
-	<name><gco:CharacterString>ML_gmxCrs</gco:CharacterString></name>
+	<name>
+		<gco:CharacterString>ML_gmxCrs</gco:CharacterString>
+	</name>
 	<scope xsi:type="gmd:PT_FreeText_PropertyType">
 		<gco:CharacterString>CRS catalogue for description of gmx metadata dataset</gco:CharacterString>
-		<gmd:PT_FreeText><gmd:textGroup><gmd:LocalisedCharacterString locale="#xpointer(//*[@id='fra'])">Catalogue des paramètres géodésiques pour la description de jeux de métadonnées conformes aux schémas gmx</gmd:LocalisedCharacterString></gmd:textGroup></gmd:PT_FreeText>
+		<gmd:PT_FreeText>
+			<gmd:textGroup>
+				<gmd:LocalisedCharacterString locale="#xpointer(//*[@id='fra'])">Catalogue des paramètres géodésiques pour la description de jeux de métadonnées conformes aux schémas gmx</gmd:LocalisedCharacterString>
+			</gmd:textGroup>
+		</gmd:PT_FreeText>
 	</scope>
-	<fieldOfApplication><gco:CharacterString>GMX (and imported) namespace</gco:CharacterString></fieldOfApplication>
-	<versionNumber><gco:CharacterString>0.0</gco:CharacterString></versionNumber>
-	<versionDate><gco:Date>2005-03-29</gco:Date></versionDate>
+	<fieldOfApplication>
+		<gco:CharacterString>GMX (and imported) namespace</gco:CharacterString>
+	</fieldOfApplication>
+	<versionNumber>
+		<gco:CharacterString>0.0</gco:CharacterString>
+	</versionNumber>
+	<versionDate>
+		<gco:Date>2005-03-29</gco:Date>
+	</versionDate>
 	<!--=== for Cultural and Linguistic Adaptability ===-->
 	<!--Default language-->
-	<language><gmd:LanguageCode codeList="../codelist/ML_gmxCodelists.xml#LanguageCode" codeListValue="eng">English</gmd:LanguageCode></language>
-	<characterSet><gmd:MD_CharacterSetCode codeList="../codelist/ML_gmxCodelists.xml#MD_CharacterSetCode" codeListValue="utf8">UTF 8</gmd:MD_CharacterSetCode></characterSet>
+	<language>
+		<gmd:LanguageCode codeList="../codelist/ML_gmxCodelists.xml#LanguageCode" codeListValue="eng">English</gmd:LanguageCode>
+	</language>
+	<characterSet>
+		<gmd:MD_CharacterSetCode codeList="../codelist/ML_gmxCodelists.xml#MD_CharacterSetCode" codeListValue="utf8">UTF 8</gmd:MD_CharacterSetCode>
+	</characterSet>
 	<!--List of the 'locales' into which free text values can be translated-->
 	<locale>
 		<gmd:PT_Locale id="fra">
-			<gmd:languageCode><gmd:LanguageCode codeList="../codelist/ML_gmxCodelists.xml#LanguageCode" codeListValue="french">French</gmd:LanguageCode></gmd:languageCode>
-			<gmd:country><gmd:Country codeList="../Codelist/ML_gmxCodelists.xm#Country" codeListValue="FR">France</gmd:Country></gmd:country>
-			<gmd:characterEncoding><gmd:MD_CharacterSetCode codeList="../Codelist/ML_gmxCodelists.xm#MD_CharacterSetCode" codeListValue="utf8">UTF 8</gmd:MD_CharacterSetCode></gmd:characterEncoding>
-			</gmd:PT_Locale>
+			<gmd:languageCode>
+				<gmd:LanguageCode codeList="../codelist/ML_gmxCodelists.xml#LanguageCode" codeListValue="french">French</gmd:LanguageCode>
+			</gmd:languageCode>
+			<gmd:country>
+				<gmd:Country codeList="../Codelist/ML_gmxCodelists.xm#Country" codeListValue="FR">France</gmd:Country>
+			</gmd:country>
+			<gmd:characterEncoding>
+				<gmd:MD_CharacterSetCode codeList="../Codelist/ML_gmxCodelists.xm#MD_CharacterSetCode" codeListValue="utf8">UTF 8</gmd:MD_CharacterSetCode>
+			</gmd:characterEncoding>
+		</gmd:PT_Locale>
 	</locale>
 	<!--============================================================================-->
 	<!--============================================================================-->
@@ -30,8 +65,21 @@
 			<gml:identifier codeSpace="EPSG_v65">4326</gml:identifier>
 			<gml:name codeSpace="IGN-F">WGS84G</gml:name>
 			<gml:name>World Geodetic System 1984</gml:name>
-			<gml:domainOfValidity><gmd:EX_Extent><gmd:geographicElement><gmd:EX_GeographicDescription>
-				<gmd:geographicIdentifier><gmd:MD_Identifier><gmd:code><gco:CharacterString>World</gco:CharacterString></gmd:code></gmd:MD_Identifier> </gmd:geographicIdentifier></gmd:EX_GeographicDescription></gmd:geographicElement></gmd:EX_Extent></gml:domainOfValidity>
+			<gml:domainOfValidity>
+				<gmd:EX_Extent>
+					<gmd:geographicElement>
+						<gmd:EX_GeographicDescription>
+							<gmd:geographicIdentifier>
+								<gmd:MD_Identifier>
+									<gmd:code>
+										<gco:CharacterString>World</gco:CharacterString>
+									</gmd:code>
+								</gmd:MD_Identifier>
+							</gmd:geographicIdentifier>
+						</gmd:EX_GeographicDescription>
+					</gmd:geographicElement>
+				</gmd:EX_Extent>
+			</gml:domainOfValidity>
 			<gml:scope>not known</gml:scope>
 			<gml:usesEllipsoidalCS xlink:href="#xpointer(//*[@gml:id='EPSG6422'])"/>
 			<gml:usesGeodeticDatum xlink:href="#xpointer(//*[@gml:id='EPSG6422')]"/>
@@ -41,10 +89,23 @@
 					<gml:identifier codeSpace="EPSG_v65">4326</gml:identifier>
 					<gml:name codeSpace="IGN-F">WGS84G</gml:name>
 					<gml:name>WGS 1984</gml:name>
-					<gml:domainOfValidity><gmd:EX_Extent><gmd:geographicElement><gmd:EX_GeographicDescription>
-				<gmd:geographicIdentifier><gmd:MD_Identifier><gmd:code><gco:CharacterString>Monde</gco:CharacterString></gmd:code></gmd:MD_Identifier> </gmd:geographicIdentifier></gmd:EX_GeographicDescription></gmd:geographicElement></gmd:EX_Extent></gml:domainOfValidity>
+					<gml:domainOfValidity>
+						<gmd:EX_Extent>
+							<gmd:geographicElement>
+								<gmd:EX_GeographicDescription>
+									<gmd:geographicIdentifier>
+										<gmd:MD_Identifier>
+											<gmd:code>
+												<gco:CharacterString>Monde</gco:CharacterString>
+											</gmd:code>
+										</gmd:MD_Identifier>
+									</gmd:geographicIdentifier>
+								</gmd:EX_GeographicDescription>
+							</gmd:geographicElement>
+						</gmd:EX_Extent>
+					</gml:domainOfValidity>
 					<gml:scope>inconnu</gml:scope>
-					<locale  xlink:href="#xpointer(//*[@id='fra'])"/>
+					<locale xlink:href="#xpointer(//*[@id='fra'])"/>
 				</CrsAlt>
 			</alternativeExpression>
 		</ML_GeodeticCRS>
@@ -62,7 +123,7 @@
 	<!--========================== Coordinate system axis ==============================-->
 	<!--*** Latitude ***-->
 	<axis>
-		<gml:CoordinateSystemAxis gml:id="EPSG9901" gml:uom="../uom/ML_gmxUom.xsd#xpointer(//*[@gml:id='deg'])">
+		<gml:CoordinateSystemAxis gml:id="EPSG9901" uom="../uom/ML_gmxUom.xsd#xpointer(//*[@gml:id='deg'])">
 			<gml:identifier codeSpace="EPSG_v65">9901</gml:identifier>
 			<gml:name>Geodetic latitude</gml:name>
 			<gml:axisAbbrev>Lat</gml:axisAbbrev>
@@ -71,7 +132,7 @@
 	</axis>
 	<!--*** Longitude ***-->
 	<axis>
-		<gml:CoordinateSystemAxis gml:id="EPSG9902" gml:uom="../uom/ML_gmxUom.xsd#xpointer(//*[@gml:id='deg'])">
+		<gml:CoordinateSystemAxis gml:id="EPSG9902" uom="../uom/ML_gmxUom.xsd#xpointer(//*[@gml:id='deg'])">
 			<gml:identifier codeSpace="EPSG_v65">9902</gml:identifier>
 			<gml:name>Geodetic longitude</gml:name>
 			<gml:axisAbbrev>Lon</gml:axisAbbrev>
@@ -96,9 +157,11 @@
 			<gml:identifier codeSpace="EPSG_v65">7030</gml:identifier>
 			<gml:name>WGS 84</gml:name>
 			<gml:semiMajorAxis uom="../uom/ML_gmxUom.xsd#xpointer(//*[@gml:id='m'])">6378137</gml:semiMajorAxis>
-			<gml:secondDefiningParameter><gml:SecondDefiningParameter>
+			<gml:secondDefiningParameter>
+				<gml:SecondDefiningParameter>
 					<gml:inverseFlattening uom="../uom/ML_gmxUom.xsd#xpointer(//*[@gml:id='m'])">298.2572</gml:inverseFlattening>
-			</gml:SecondDefiningParameter></gml:secondDefiningParameter>
+				</gml:SecondDefiningParameter>
+			</gml:secondDefiningParameter>
 		</gml:Ellipsoid>
 	</ellipsoid>
 	<!--============================== Prime meridians =================================-->
diff --git a/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/resources/crs/gmxCrs.xml b/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/resources/crs/gmxCrs.xml
similarity index 77%
copy from pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/resources/crs/gmxCrs.xml
copy to pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/resources/crs/gmxCrs.xml
index 456218e..4f7e07c 100644
--- a/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/resources/crs/gmxCrs.xml
+++ b/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/resources/crs/gmxCrs.xml
@@ -1,11 +1,33 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<CT_CrsCatalogue xmlns="http://www.isotc211.org/2005/gmx" xmlns:gco="http://www.isotc211.org/2005/gco" xmlns:gml="http://www.opengis.net/gml" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.isotc211.org/2005/gmx ../../gmx/gmx.xsd http://www.isotc211.org/2005/gmd ../../gmd/gmd.xsd http://www.isotc211.org/2005/gco ../../gco/gco.xsd http://www.w3.org/1999/xlink ../../ [...]
+<!-- 
+CORRECTIONS referenced 2012-07-13 #01
+AUTHOR: XML Maintenance group - Nicolas Lesage
+PURPOSE: Use of absolute path in xsi:schemaLocation
+DESCRIPTION:
+- ../gmx/gmx.xsd replaced by http://schemas.opengis.net/iso/19139/20070417/gmx/gmx.xsd
+- ../gmd/gmd.xsd replaced by http://schemas.opengis.net/iso/19139/20070417/gmd/gmd.xsd
+- ../gco/gco.xsd replaced by http://schemas.opengis.net/iso/19139/20070417/gco/gco.xsd
+- ../xlink/xlinks.xsd replaced by http://www.w3.org/1999/xlink.xsd
+- ../gml/gml.xsd replaced by http://schemas.opengis.net/gml/3.2.1/gml.xsd
+
+-->
+<CT_CrsCatalogue xmlns="http://www.isotc211.org/2005/gmx" xmlns:gco="http://www.isotc211.org/2005/gco" xmlns:gml="http://www.opengis.net/gml/3.2" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.isotc211.org/2005/gmx http://schemas.opengis.net/iso/19139/20070417/gmx/gmx.xsd http://www.isotc211.org/2005/gmd http://schemas.opengis.net/iso/19139/20070417/gmd/gmd.xsd ht [...]
 	<!--=====Catalogue description=====-->
-	<name><gco:CharacterString>gmxCrs</gco:CharacterString></name>
-	<scope><gco:CharacterString>CRS parameters dictionary</gco:CharacterString></scope>
-	<fieldOfApplication><gco:CharacterString>GMX (and imported) namespace</gco:CharacterString></fieldOfApplication>
-	<versionNumber><gco:CharacterString>0.0</gco:CharacterString></versionNumber>
-	<versionDate><gco:Date>2005-03-18</gco:Date></versionDate>
+	<name>
+		<gco:CharacterString>gmxCrs</gco:CharacterString>
+	</name>
+	<scope>
+		<gco:CharacterString>CRS parameters dictionary</gco:CharacterString>
+	</scope>
+	<fieldOfApplication>
+		<gco:CharacterString>GMX (and imported) namespace</gco:CharacterString>
+	</fieldOfApplication>
+	<versionNumber>
+		<gco:CharacterString>0.0</gco:CharacterString>
+	</versionNumber>
+	<versionDate>
+		<gco:Date>2005-03-18</gco:Date>
+	</versionDate>
 	<!--============================================================================-->
 	<!--============================================================================-->
 	<!--======================= Coordinate reference systems ============================-->
@@ -15,8 +37,14 @@
 			<gml:identifier codeSpace="EPSG_v65">4326</gml:identifier>
 			<gml:name codeSpace="IGN-F">WGS84G</gml:name>
 			<gml:name>World Geodetic System 1984</gml:name>
-			<gml:domainOfValidity><gmd:EX_Extent><gmd:geographicElement><gmd:EX_GeographicDescription>
-				<gmd:geographicIdentifier><gmd:MD_Identifier><gmd:code><gco:CharacterString>World: Afghanistan, Albania, Algeria, American Samoa, Andorra, Angola, Anguilla, Antarctica, Antigua and Barbuda, Argentina, Armenia, Aruba, Australia, 
+			<gml:domainOfValidity>
+				<gmd:EX_Extent>
+					<gmd:geographicElement>
+						<gmd:EX_GeographicDescription>
+							<gmd:geographicIdentifier>
+								<gmd:MD_Identifier>
+									<gmd:code>
+										<gco:CharacterString>World: Afghanistan, Albania, Algeria, American Samoa, Andorra, Angola, Anguilla, Antarctica, Antigua and Barbuda, Argentina, Armenia, Aruba, Australia, 
 	Austria, Azerbaijan, Bahamas, Bahrain, Bangladesh, Barbados, Belgium, Belgium, Belize, Benin, Bermuda, Bhutan, Bolivia, Bosnia and Herzegowina, 
 	Botswana, Bouvet Island, Brazil, British Indian Ocean Territory, British Virgin Islands, Brunei Darussalam, Bulgaria, Burkina Faso, Burundi, Cambodia, 
 	Cameroon, Canada, Cape Verde, Cayman Islands, Central African Republic, Chad, Chile, China, Christmas Island, Cocos (Keeling) Islands, Comoros, 
@@ -37,7 +65,14 @@
 	Tajikistan, United Republic of Tanzania, Thailand, The Democratic Republic of the Congo (Zaire), Togo, Tokelau, Tonga, Trinidad and Tobago, Tunisia, 
 	Turkey, Turkmenistan, Turks and Caicos Islands, Tuvalu, Uganda, Ukraine, United Arab Emirates (UAE), United Kingdom (UK), United States (USA), 
 	United States Minor Outlying Islands, Uruguay, Uzbekistan, Vanuatu, Venezuela, Vietnam, US Virgin Islands, Wallis and Futuna, Western Sahara, Yemen, 
-	Yugoslavia - Union of Serbia and Montenegro, Zambia, Zimbabwe.</gco:CharacterString></gmd:code></gmd:MD_Identifier> </gmd:geographicIdentifier></gmd:EX_GeographicDescription></gmd:geographicElement></gmd:EX_Extent></gml:domainOfValidity>
+	Yugoslavia - Union of Serbia and Montenegro, Zambia, Zimbabwe.</gco:CharacterString>
+									</gmd:code>
+								</gmd:MD_Identifier>
+							</gmd:geographicIdentifier>
+						</gmd:EX_GeographicDescription>
+					</gmd:geographicElement>
+				</gmd:EX_Extent>
+			</gml:domainOfValidity>
 			<gml:scope>not known</gml:scope>
 			<gml:ellipsoidalCS xlink:href="#xpointer(//*[@gml:id='EPSG6422'])"/>
 			<gml:geodeticDatum xlink:href="#xpointer(//*[@gml:id='EPSG6326')]"/>
@@ -49,11 +84,25 @@
 			<gml:identifier codeSpace="EPSG_v65">32638</gml:identifier>
 			<gml:name codeSpace="IGN-F">UTM38W84</gml:name>
 			<gml:name>WGS 84 / UTM zone 38N</gml:name>
-			<gml:domainOfValidity><gmd:EX_Extent><gmd:geographicElement><gmd:EX_GeographicDescription>
-				<gmd:geographicIdentifier><gmd:MD_Identifier><gmd:code><gco:CharacterString>Between 42 and 48 deg East; northern hemisphere. Armenia. Azerbaijan. Djibouti. Eritrea. Ethiopia. Georgia. Islamic Republic of Iran. Iraq. Kazakstan. Kuwait. Russian Federation. Saudi Arabia. Somalia. Tukey. Yemen.</gco:CharacterString></gmd:code></gmd:MD_Identifier> </gmd:geographicIdentifier></gmd:EX_GeographicDescription></gmd:geographicElement></gmd:EX_Extent></gml:domainOfValidity>
+			<gml:domainOfValidity>
+				<gmd:EX_Extent>
+					<gmd:geographicElement>
+						<gmd:EX_GeographicDescription>
+							<gmd:geographicIdentifier>
+								<gmd:MD_Identifier>
+									<gmd:code>
+										<gco:CharacterString>Between 42 and 48 deg East; northern hemisphere. Armenia. Azerbaijan. Djibouti. Eritrea. Ethiopia. Georgia. Islamic Republic of Iran. Iraq. Kazakstan. Kuwait. Russian Federation. Saudi Arabia. Somalia. Tukey. Yemen.</gco:CharacterString>
+									</gmd:code>
+								</gmd:MD_Identifier>
+							</gmd:geographicIdentifier>
+						</gmd:EX_GeographicDescription>
+					</gmd:geographicElement>
+				</gmd:EX_Extent>
+			</gml:domainOfValidity>
 			<gml:scope>not known</gml:scope>
 			<gml:conversion xlink:href="#xpointer(//*[@gml:id='EPSG16038'])"/>
-			<gml:baseGeodeticCRS xlink:href="#xpointer(//*[@gml:id='EPSG4326'])"/><!--WGS84 - CRS-->
+			<gml:baseGeodeticCRS xlink:href="#xpointer(//*[@gml:id='EPSG4326'])"/>
+			<!--WGS84 - CRS-->
 			<gml:cartesianCS xlink:href="#EPSG4400"/>
 		</gml:ProjectedCRS>
 	</crs>
@@ -65,7 +114,7 @@
 			<gml:identifier codeSpace="EPSG_v65">6422</gml:identifier>
 			<gml:name>CS ellipsoidal2D</gml:name>
 			<gml:axis xlink:href="#xpointer(//*[@gml:id='EPSG9901'])"/>
-			<gml:axis xlink:href="#xpointer(//*[@gml:id='EPSG9902'])"/>		
+			<gml:axis xlink:href="#xpointer(//*[@gml:id='EPSG9902'])"/>
 		</gml:EllipsoidalCS>
 	</coordinateSystem>
 	<!--*** Cartesian - 2D ***-->
@@ -81,7 +130,7 @@
 	<!--========================== Coordinate system axis ==============================-->
 	<!--*** Latitude ***-->
 	<axis>
-		<gml:CoordinateSystemAxis gml:id="EPSG9901" gml:uom="../uom/gmxUom.xsd#xpointer(//*[@gml:id='deg'])">
+		<gml:CoordinateSystemAxis gml:id="EPSG9901" uom="../uom/gmxUom.xsd#xpointer(//*[@gml:id='deg'])">
 			<gml:identifier codeSpace="EPSG_v65">9901</gml:identifier>
 			<gml:name>Geodetic latitude</gml:name>
 			<gml:axisAbbrev>Lat</gml:axisAbbrev>
@@ -90,7 +139,7 @@
 	</axis>
 	<!--*** Longitude ***-->
 	<axis>
-		<gml:CoordinateSystemAxis gml:id="EPSG9902" gml:uom="../uom/gmxUom.xsd#xpointer(//*[@gml:id='deg'])">
+		<gml:CoordinateSystemAxis gml:id="EPSG9902" uom="../uom/gmxUom.xsd#xpointer(//*[@gml:id='deg'])">
 			<gml:identifier codeSpace="EPSG_v65">9902</gml:identifier>
 			<gml:name>Geodetic longitude</gml:name>
 			<gml:axisAbbrev>Lon</gml:axisAbbrev>
@@ -99,7 +148,7 @@
 	</axis>
 	<!--*** Northing ***-->
 	<axis>
-		<gml:CoordinateSystemAxis gml:id="EPSG9907" gml:uom="../uom/gmxUom.xsd#xpointer(//*[@gml:id='m'])">
+		<gml:CoordinateSystemAxis gml:id="EPSG9907" uom="../uom/gmxUom.xsd#xpointer(//*[@gml:id='m'])">
 			<gml:identifier codeSpace="EPSG_v65">9907</gml:identifier>
 			<gml:name>Northing</gml:name>
 			<gml:axisAbbrev>N</gml:axisAbbrev>
@@ -108,7 +157,7 @@
 	</axis>
 	<!--*** Easting ***-->
 	<axis>
-		<gml:CoordinateSystemAxis gml:id="EPSG9906" gml:uom="../uom/gmxUom.xsd#xpointer(//*[@gml:id='m'])">
+		<gml:CoordinateSystemAxis gml:id="EPSG9906" uom="../uom/gmxUom.xsd#xpointer(//*[@gml:id='m'])">
 			<gml:identifier codeSpace="EPSG_v65">9906</gml:identifier>
 			<gml:name>Easting</gml:name>
 			<gml:axisAbbrev>E</gml:axisAbbrev>
@@ -133,9 +182,11 @@
 			<gml:identifier codeSpace="EPSG_v65">7030</gml:identifier>
 			<gml:name>WGS 84</gml:name>
 			<gml:semiMajorAxis uom="../uom/gmxUom.xsd#xpointer(//*[@gml:id='m'])">6378137</gml:semiMajorAxis>
-			<gml:secondDefiningParameter><gml:SecondDefiningParameter>
+			<gml:secondDefiningParameter>
+				<gml:SecondDefiningParameter>
 					<gml:inverseFlattening uom="../uom/gmxUom.xsd#xpointer(//*[@gml:id='m'])">298.2572</gml:inverseFlattening>
-			</gml:SecondDefiningParameter></gml:secondDefiningParameter>
+				</gml:SecondDefiningParameter>
+			</gml:secondDefiningParameter>
 		</gml:Ellipsoid>
 	</ellipsoid>
 	<!--============================== Prime meridians =================================-->
diff --git a/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/resources/example/fr-fr.xml b/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/resources/example/fr-fr.xml
new file mode 100644
index 0000000..98d928f
--- /dev/null
+++ b/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/resources/example/fr-fr.xml
@@ -0,0 +1,83 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+CORRECTIONS referenced 2012-07-13 #01
+AUTHOR: XML Maintenance group - Nicolas Lesage
+PURPOSE: Use of absolute path in xsi:schemaLocation
+DESCRIPTION:
+- ../gmd/gmd.xsd replaced by http://schemas.opengis.net/iso/19139/20070417/gmd/gmd.xsd
+- ../gco/gco.xsd replaced by http://schemas.opengis.net/iso/19139/20070417/gco/gco.xsd
+- ../xlink/xlinks.xsd replaced by http://www.w3.org/1999/xlink.xsd
+- ../gml/gml.xsd replaced by http://schemas.opengis.net/gml/3.2.1/gml.xsd
+
+--><PT_LocaleContainer xmlns="http://www.isotc211.org/2005/gmd" xmlns:gco="http://www.isotc211.org/2005/gco" xmlns:gml="http://www.opengis.net/gml/3.2" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.isotc211.org/2005/gmd http://schemas.opengis.net/iso/19139/20070417/gmd/gmd.xsd http://www.isotc211.org/2005/gco http://schemas.opengis.net/iso/19139/20070417/gco/gco.xsd http://www.opengis.net/gml/3.2 http://sch [...]
+	<!--==========================================-->
+	<!--===========Translation file Header ============-->
+	<!--===Text description===-->
+	<description>
+		<gco:CharacterString>France-France</gco:CharacterString>
+	</description>
+	<!--===Locale===-->
+	<locale>
+		<PT_Locale id="locale-fr">
+			<languageCode>
+				<LanguageCode codeList="../Codelist/ML_gmxCodelists.xml#LanguageCode" codeListValue="fra">French</LanguageCode>
+			</languageCode>
+			<country>
+				<Country codeList="../Codelist/ML_gmxCodelists.xml#Country" codeListValue="FR">FR</Country>
+			</country>
+			<characterEncoding>
+				<MD_CharacterSetCode codeList="../Codelist/ML_gmxCodelists.xml#MD_CharacterSetCode" codeListValue="utf8">UTF 8</MD_CharacterSetCode>
+			</characterEncoding>
+		</PT_Locale>
+	</locale>
+	<!--===Dates [creation / revision]===-->
+	<date>
+		<CI_Date>
+			<date>
+				<gco:Date>2005-03-18</gco:Date>
+			</date>
+			<dateType>
+				<CI_DateTypeCode codeList="../Codelist/ML_gmxCodelists.xml#CI_DateTypeCode" codeListValue="creation" codeSpace="fra">création</CI_DateTypeCode>
+			</dateType>
+		</CI_Date>
+	</date>
+	<date>
+		<CI_Date>
+			<date>
+				<gco:Date>2006-02-03</gco:Date>
+			</date>
+			<dateType>
+				<CI_DateTypeCode codeList="../Codelist/ML_gmxCodelists.xml#CI_DateTypeCode" codeListValue="../Codelist/ML_gmxCodelists.xml#CI_DateTypeCode_revision" codeSpace="fra">révision</CI_DateTypeCode>
+			</dateType>
+		</CI_Date>
+	</date>
+	<!--===Responsible party [author]===-->
+	<responsibleParty>
+		<CI_ResponsibleParty>
+			<organisationName>
+				<gco:CharacterString>french translation team</gco:CharacterString>
+			</organisationName>
+			<role>
+				<CI_RoleCode codeList="../Codelist/ML_gmxCodelists.xml#CI_RoleCode" codeListValue="author" codeSpace="fra">auteur</CI_RoleCode>
+			</role>
+		</CI_ResponsibleParty>
+	</responsibleParty>
+	<!--============================================================================-->
+	<!--============================================================================-->
+	<!--=========================== Translation items ===================================-->
+	<!--+++abstract : Brief narrative summary of the content of the resource+++-->
+	<localisedString>
+		<LocalisedCharacterString id="abstract-fr" locale="#fr-fr">Résumé succint du contenu du jeu de données</LocalisedCharacterString>
+	</localisedString>
+	<!--++++++-->
+	<localisedString/>
+	<!--++++++-->
+	<localisedString/>
+	<!--++++++-->
+	<localisedString/>
+	<!--++++++-->
+	<localisedString/>
+	<!--++++++-->
+	<localisedString/>
+	<!--=== EOF ===-->
+</PT_LocaleContainer>
diff --git a/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/resources/uom/ML_gmxUom.xml b/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/resources/uom/ML_gmxUom.xml
new file mode 100644
index 0000000..9710190
--- /dev/null
+++ b/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/resources/uom/ML_gmxUom.xml
@@ -0,0 +1,125 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+CORRECTIONS referenced 2012-07-13 #01
+AUTHOR: XML Maintenance group - Nicolas Lesage
+PURPOSE: Use of absolute path in xsi:schemaLocation
+DESCRIPTION:
+- ../gmx/gmx.xsd replaced by http://schemas.opengis.net/iso/19139/20070417/gmx/gmx.xsd
+- ../gmd/gmd.xsd replaced by http://schemas.opengis.net/iso/19139/20070417/gmd/gmd.xsd
+- ../gco/gco.xsd replaced by http://schemas.opengis.net/iso/19139/20070417/gco/gco.xsd
+- ../xlink/xlinks.xsd replaced by http://www.w3.org/1999/xlink.xsd
+- ../gml/gml.xsd replaced by http://schemas.opengis.net/gml/3.2.1/gml.xsd
+
+-->
+<CT_UomCatalogue xmlns="http://www.isotc211.org/2005/gmx" xmlns:gco="http://www.isotc211.org/2005/gco" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml/3.2" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.isotc211.org/2005/gmx http://schemas.opengis.net/iso/19139/20070417/gmx/gmx.xsd http://www.isotc211.org/2005/gmd http://schemas.opengis.net/iso/19139/20070417/gmd/gmd.xsd ht [...]
+	<!--=====Catalogue description=====-->
+	<name>
+		<gco:CharacterString>uom</gco:CharacterString>
+	</name>
+	<scope xsi:type="gmd:PT_FreeText_PropertyType">
+		<gco:CharacterString>units of measure dictionary compliant with SI definitions</gco:CharacterString>
+		<gmd:PT_FreeText>
+			<gmd:textGroup>
+				<gmd:LocalisedCharacterString locale="#xpointer(//*[@id='fra'])">dictionnaire d'unités de mesure conforme avec les définitions du Système International (SI)</gmd:LocalisedCharacterString>
+			</gmd:textGroup>
+		</gmd:PT_FreeText>
+	</scope>
+	<fieldOfApplication>
+		<gco:CharacterString>GMX (and imported) namespace</gco:CharacterString>
+	</fieldOfApplication>
+	<versionNumber>
+		<gco:CharacterString>0.0</gco:CharacterString>
+	</versionNumber>
+	<versionDate>
+		<gco:Date>2005-06-18</gco:Date>
+	</versionDate>
+	<!--=== for Cultural and Linguistic Adaptability ===-->
+	<!--Default language-->
+	<language>
+		<gmd:LanguageCode codeList="../Codelist/ML_gmxCodelists.xml#LanguageCode" codeListValue="eng">English</gmd:LanguageCode>
+	</language>
+	<characterSet>
+		<gmd:MD_CharacterSetCode codeList="../Codelist/ML_gmxCodelists.xml#MD_CharacterSetCode" codeListValue="utf8">UTF 8</gmd:MD_CharacterSetCode>
+	</characterSet>
+	<!--List of the 'locales' into which free text values can be translated-->
+	<locale>
+		<gmd:PT_Locale id="fra">
+			<gmd:languageCode>
+				<gmd:LanguageCode codeList="../Codelist/ML_gmxCodelists.xml#LanguageCode" codeListValue="fra">French</gmd:LanguageCode>
+			</gmd:languageCode>
+			<gmd:country>
+				<gmd:Country codeList="../Codelist/ML_gmxCodelists.xm#Country" codeListValue="FR">France</gmd:Country>
+			</gmd:country>
+			<gmd:characterEncoding>
+				<gmd:MD_CharacterSetCode codeList="../Codelist/ML_gmxCodelists.xm#MD_CharacterSetCode" codeListValue="utf8">UTF 8</gmd:MD_CharacterSetCode>
+			</gmd:characterEncoding>
+		</gmd:PT_Locale>
+	</locale>
+	<!--============================================================================-->
+	<!--============================================================================-->
+	<!--============================= UOM items ======================================-->
+	<!--====== METER =====-->
+	<uomItem>
+		<ML_BaseUnit gml:id="m">
+			<gml:description>The metre is the length of the path travelled by ligth in vaccum during a time interval of 1/299 792 458 of a second</gml:description>
+			<gml:identifier codeSpace="http://www.bipm.fr/en/si/base_units">metre</gml:identifier>
+			<gml:quantityType>length</gml:quantityType>
+			<gml:catalogSymbol codeSpace="http://www1.bipm.org/en/si/base_units">m</gml:catalogSymbol>
+			<gml:unitsSystem xlink:href="http://www.bipm.fr/en/SI"/>
+			<!--==alternative definition(s)==-->
+			<alternativeExpression>
+				<UomAlternativeExpression gml:id="m_fr" codeSpace="fra">
+					<gml:description>unité de longueur de référence dans le système international, correspond à la distance parcourue par la lumière dans le vide pendant 1/299 792 458 seconde</gml:description>
+					<gml:identifier codeSpace="http://www.bipm.fr/fr/si/base_units">metre</gml:identifier>
+					<gml:name>mètre</gml:name>
+					<gml:quantityType>longueur</gml:quantityType>
+					<locale xlink:href="#xpointer(//*[@id='fra'])"/>
+				</UomAlternativeExpression>
+			</alternativeExpression>
+			<!--......................................-->
+		</ML_BaseUnit>
+	</uomItem>
+	<!--====== DEGREE =====-->
+	<uomItem>
+		<ML_ConventionalUnit gml:id="deg">
+			<gml:description>Measure of angle equal to Pi/180 radians, widely used in geography</gml:description>
+			<gml:identifier codeSpace="ISO31-1">degree</gml:identifier>
+			<gml:quantityType>angle</gml:quantityType>
+			<gml:conversionToPreferredUnit uom="#xpointer(//*[@gml:id='rad'])">
+				<gml:factor>1.74532925199433E-02</gml:factor>
+			</gml:conversionToPreferredUnit>
+			<!--==alternative definition(s)==-->
+			<alternativeExpression>
+				<UomAlternativeExpression gml:id="deg_fr" codeSpace="fra">
+					<gml:description>Unité d'angle de référence en géographie égale à Pi/180 radians.</gml:description>
+					<gml:identifier codeSpace="ISO31-1">degree</gml:identifier>
+					<gml:name>degré</gml:name>
+					<gml:quantityType>angle</gml:quantityType>
+					<locale xlink:href="#xpointer(//*[@id='fra'])"/>
+				</UomAlternativeExpression>
+			</alternativeExpression>
+		</ML_ConventionalUnit>
+	</uomItem>
+	<!--====== RADIAN =====-->
+	<uomItem>
+		<ML_DerivedUnit gml:id="rad">
+			<gml:description>Radian is an unit of angle measure. It is defined as the ratio of arc length to the radius of the circle.</gml:description>
+			<gml:identifier codeSpace="http://www1.bipm.org/en/si/derived_units">radian</gml:identifier>
+			<gml:quantityType>plane angle</gml:quantityType>
+			<gml:catalogSymbol codeSpace="http://www1.bipm.org/en/si/derived_units">rad</gml:catalogSymbol>
+			<gml:derivationUnitTerm uom="#xpointer(//*[@gml:id='m'])" exponent="1"/>
+			<gml:derivationUnitTerm uom="#xpointer(//*[@gml:id='m'])" exponent="-1"/>
+			<!--==alternative definition(s)==-->
+			<alternativeExpression>
+				<UomAlternativeExpression gml:id="rad_fr" codeSpace="fra">
+					<gml:description>Le radian est une unité de mesaure angulaire définie comme le ratio entre le rayon et la longueur de l'arc.</gml:description>
+					<gml:identifier codeSpace="http://www1.bipm.org/en/si/derived_units">radian</gml:identifier>
+					<gml:name>radian</gml:name>
+					<gml:quantityType>angle planaire</gml:quantityType>
+					<locale xlink:href="#xpointer(//*[@id='fra'])"/>
+				</UomAlternativeExpression>
+			</alternativeExpression>
+		</ML_DerivedUnit>
+	</uomItem>
+	<!--=== EOF ===-->
+</CT_UomCatalogue>
diff --git a/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/resources/uom/gmxUom.xml b/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/resources/uom/gmxUom.xml
new file mode 100644
index 0000000..ad0eaeb
--- /dev/null
+++ b/pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/resources/uom/gmxUom.xml
@@ -0,0 +1,66 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+CORRECTIONS referenced 2012-07-13 #01
+AUTHOR: XML Maintenance group - Nicolas Lesage
+PURPOSE: Use of absolute path in xsi:schemaLocation
+DESCRIPTION:
+- ../gmx/gmx.xsd replaced by http://schemas.opengis.net/iso/19139/20070417/gmx/gmx.xsd
+- ../gco/gco.xsd replaced by http://schemas.opengis.net/iso/19139/20070417/gco/gco.xsd
+- ../xlink/xlinks.xsd replaced by http://www.w3.org/1999/xlink.xsd
+- ../gml/gml.xsd replaced by http://schemas.opengis.net/gml/3.2.1/gml.xsd
+
+-->
+<CT_UomCatalogue xmlns="http://www.isotc211.org/2005/gmx" xmlns:gco="http://www.isotc211.org/2005/gco" xmlns:gml="http://www.opengis.net/gml/3.2" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.isotc211.org/2005/gmx http://schemas.opengis.net/iso/19139/20070417/gmx/gmx.xsd http://www.isotc211.org/2005/gco http://schemas.opengis.net/iso/19139/20070417/gco/gco.xsd http://www.opengis.net/gml/3.2 http://schemas.o [...]
+	<!--=====Catalogue description=====-->
+	<name>
+		<gco:CharacterString>gmxUom</gco:CharacterString>
+	</name>
+	<scope>
+		<gco:CharacterString>units of measure dictionary compliant with SI definitions</gco:CharacterString>
+	</scope>
+	<fieldOfApplication>
+		<gco:CharacterString>ISO/TC 211 GMX (and imported) namespace</gco:CharacterString>
+	</fieldOfApplication>
+	<versionNumber>
+		<gco:CharacterString>0.0</gco:CharacterString>
+	</versionNumber>
+	<versionDate>
+		<gco:Date>2005-03-18</gco:Date>
+	</versionDate>
+	<!--============================================================================-->
+	<!--============================================================================-->
+	<!--============================= UOM items ======================================-->
+	<!--====== METRE =====-->
+	<uomItem>
+		<gml:BaseUnit gml:id="m">
+			<gml:description>The metre is the length of the path travelled by ligth in vaccum during a time interval of 1/299 792 458 of a second</gml:description>
+			<gml:identifier codeSpace="http://www.bipm.fr/en/si/base_units">metre</gml:identifier>
+			<gml:quantityType>length</gml:quantityType>
+			<gml:catalogSymbol codeSpace="http://www.bipm.org/en/si/base_units">m</gml:catalogSymbol>
+			<gml:unitsSystem xlink:href="http://www.bipm.fr/en/si"/>
+		</gml:BaseUnit>
+	</uomItem>
+	<!--====== DEGREE =====-->
+	<uomItem>
+		<gml:ConventionalUnit gml:id="deg">
+			<gml:description>Measure of angle equal to Pi/180 radians, widely used in geography</gml:description>
+			<gml:identifier codeSpace="ISO31-1">degree</gml:identifier>
+			<gml:quantityType>angle</gml:quantityType>
+			<gml:conversionToPreferredUnit uom="#xpointer(//*[@gml:id='rad'])">
+				<gml:factor>1.74532925199433E-02</gml:factor>
+			</gml:conversionToPreferredUnit>
+		</gml:ConventionalUnit>
+	</uomItem>
+	<!--====== RADIAN =====-->
+	<uomItem>
+		<gml:DerivedUnit gml:id="rad">
+			<gml:description>Radian is an unit of angle measure. It is defined as the ratio of arc length to the radius of the circle.</gml:description>
+			<gml:identifier codeSpace="http://www.bipm.fr/en/s/derived_unitsi">radian</gml:identifier>
+			<gml:quantityType>plane angle</gml:quantityType>
+			<gml:catalogSymbol codeSpace="http://www1.bipm.org/en/si/derived_units">rad</gml:catalogSymbol>
+			<gml:derivationUnitTerm uom="#xpointer(//*[@gml:id='m'])" exponent="1"/>
+			<gml:derivationUnitTerm uom="#xpointer(//*[@gml:id='m'])" exponent="-1"/>
+		</gml:DerivedUnit>
+	</uomItem>
+	<!--=== EOF ===-->
+</CT_UomCatalogue>
diff --git a/pycsw/plugins/profiles/ebrim/__init__.py b/pycsw/plugins/profiles/ebrim/__init__.py
index f98f82b..08a4c3d 100644
--- a/pycsw/plugins/profiles/ebrim/__init__.py
+++ b/pycsw/plugins/profiles/ebrim/__init__.py
@@ -1,9 +1,9 @@
-# -*- coding: ISO-8859-15 -*-
+# -*- coding: utf-8 -*-
 # =================================================================
 #
 # Authors: Tom Kralidis <tomkralidis at gmail.com>
 #
-# Copyright (c) 2011 Tom Kralidis
+# Copyright (c) 2015 Tom Kralidis
 #
 # Permission is hereby granted, free of charge, to any person
 # obtaining a copy of this software and associated documentation
diff --git a/pycsw/plugins/profiles/ebrim/ebrim.py b/pycsw/plugins/profiles/ebrim/ebrim.py
index 3a3bd20..e801491 100644
--- a/pycsw/plugins/profiles/ebrim/ebrim.py
+++ b/pycsw/plugins/profiles/ebrim/ebrim.py
@@ -1,9 +1,9 @@
-# -*- coding: iso-8859-15 -*-
+# -*- coding: utf-8 -*-
 # =================================================================
 #
 # Authors: Tom Kralidis <tomkralidis at gmail.com>
 #
-# Copyright (c) 2011 Tom Kralidis
+# Copyright (c) 2015 Tom Kralidis
 #
 # Permission is hereby granted, free of charge, to any person
 # obtaining a copy of this software and associated documentation
@@ -29,10 +29,14 @@
 # =================================================================
 
 import os
-from lxml import etree
-from pycsw import config, server, util
+from pycsw.core.etree import etree
+from pycsw.core import config, util
+from pycsw.ogc.csw.csw2 import write_boundingbox
 from pycsw.plugins.profiles import profile
 
+from six import text_type
+
+
 class EBRIM(profile.Profile):
     ''' EBRim class '''
     def __init__(self, model, namespaces, context):
@@ -40,6 +44,7 @@ class EBRIM(profile.Profile):
         self.context = context
 
         self.namespaces = {
+            'ebrim': 'http://www.opengis.net/cat/wrs/1.0',
             'rim': 'urn:oasis:names:tc:ebxml-regrep:xsd:rim:3.0',
             'wrs': 'http://www.opengis.net/cat/wrs/1.0'
         }
@@ -103,10 +108,10 @@ class EBRIM(profile.Profile):
         util.nspath_eval('csw:SchemaComponent', self.context.namespaces),
         schemaLanguage='XMLSCHEMA', targetNamespace=self.namespace)
 
-        schema_file = os.path.join(self.context.pycsw_home,
-                                   'plugins', 'profiles', 'ebrim',
-                                   'schemas', 'ogc', 'csw', '2.0.2',
-                                   'profiles', 'ebrim', '1.0', 'csw-ebrim.xsd')
+        schema_file = os.path.join(self.context.pycsw_home, 'plugins',
+                                   'profiles', 'ebrim', 'schemas', 'ogc',
+                                   'csw', '2.0.2', 'profiles', 'ebrim',
+                                   '1.0', 'csw-ebrim.xsd')
 
         schema = etree.parse(schema_file, self.context.parser).getroot()
 
@@ -146,13 +151,13 @@ class EBRIM(profile.Profile):
             etree.SubElement(node, util.nspath_eval('rim:ExternalIdentifier', self.namespaces), value=identifier, identificationScheme='foo', registryObject=str(util.getqattr(result, self.context.md_core_model['mappings']['pycsw:Relation'])), id=identifier)
 
             name = etree.SubElement(node, util.nspath_eval('rim:Name', self.namespaces))
-            etree.SubElement(name, util.nspath_eval('rim:LocalizedString', self.namespaces), value=unicode(util.getqattr(result, self.context.md_core_model['mappings']['pycsw:Title'])))
+            etree.SubElement(name, util.nspath_eval('rim:LocalizedString', self.namespaces), value=text_type(util.getqattr(result, self.context.md_core_model['mappings']['pycsw:Title'])))
 
             description = etree.SubElement(node, util.nspath_eval('rim:Description', self.namespaces))
-            etree.SubElement(description, util.nspath_eval('rim:LocalizedString', self.namespaces), value=unicode(util.getqattr(result, self.context.md_core_model['mappings']['pycsw:Abstract'])))
+            etree.SubElement(description, util.nspath_eval('rim:LocalizedString', self.namespaces), value=text_type(util.getqattr(result, self.context.md_core_model['mappings']['pycsw:Abstract'])))
 
             val = util.getqattr(result, self.context.md_core_model['mappings']['pycsw:BoundingBox'])
-            bboxel = server.write_boundingbox(val, self.context.namespaces)
+            bboxel = write_boundingbox(val, self.context.namespaces)
 
             if bboxel is not None:
                 bboxslot = etree.SubElement(node, util.nspath_eval('rim:Slot', self.namespaces),
diff --git a/pycsw/plugins/profiles/ebrim/schemas/ogc/csw/2.0.2/profiles/ebrim/1.0/csw-ebrim.xsd b/pycsw/plugins/profiles/ebrim/schemas/ogc/csw/2.0.2/profiles/ebrim/1.0/csw-ebrim.xsd
index 1296e7e..09b88b8 100644
--- a/pycsw/plugins/profiles/ebrim/schemas/ogc/csw/2.0.2/profiles/ebrim/1.0/csw-ebrim.xsd
+++ b/pycsw/plugins/profiles/ebrim/schemas/ogc/csw/2.0.2/profiles/ebrim/1.0/csw-ebrim.xsd
@@ -26,11 +26,11 @@
   <xsd:import namespace="urn:oasis:names:tc:ebxml-regrep:xsd:rim:3.0" 
     schemaLocation="http://docs.oasis-open.org/regrep/v3.0/schema/rim.xsd" />
   <xsd:import namespace="http://www.opengis.net/cat/csw/2.0.2"
-    schemaLocation="../../../../../../../../../../../../pycsw/schemas/ogc/csw/2.0.2/CSW-publication.xsd"/>
+    schemaLocation="http://schemas.opengis.net/csw/2.0.2/CSW-publication.xsd"/>
   <xsd:import namespace="http://www.w3.org/1999/xlink" 
-    schemaLocation="../../../../../../../../../../../../pycsw/schemas/w3c/1999/xlink.xsd"/>
+    schemaLocation="http://www.w3.org/1999/xlink.xsd"/>
   <xsd:import namespace="http://www.opengis.net/ogc"
-    schemaLocation="../../../../../../../../../../../../pycsw/schemas/ogc/filter/1.1.0/filter.xsd"/>
+    schemaLocation="http://schemas.opengis.net/filter/1.1.0/filter.xsd"/>
     
   <xsd:element name="Capabilities" type="csw:CapabilitiesType" />
   <xsd:element name="RecordId" type="wrs:RecordIdType" 
diff --git a/pycsw/plugins/profiles/profile.py b/pycsw/plugins/profiles/profile.py
index f3b44fb..422402f 100644
--- a/pycsw/plugins/profiles/profile.py
+++ b/pycsw/plugins/profiles/profile.py
@@ -1,10 +1,11 @@
-# -*- coding: iso-8859-15 -*-
+# -*- coding: utf-8 -*-
 # =================================================================
 #
 # Authors: Tom Kralidis <tomkralidis at gmail.com>
-#                Angelos Tzotsos <tzotsos at gmail.com>
+#          Angelos Tzotsos <tzotsos at gmail.com>
 #
-# Copyright (c) 2011 Tom Kralidis
+# Copyright (c) 2015 Tom Kralidis
+# Copyright (c) 2015 Angelos Tzotsos
 #
 # Permission is hereby granted, free of charge, to any person
 # obtaining a copy of this software and associated documentation
@@ -49,8 +50,9 @@ class Profile(object):
         self.prefixes = prefixes
         self.repository = repository
 
-        model['operations']['DescribeRecord']['parameters']\
-        ['typeName']['values'].append(self.typename)
+        if 'DescribeRecord' in model['operations']:
+            model['operations']['DescribeRecord']['parameters']\
+            ['typeName']['values'].append(self.typename)
 
         model['operations']['GetRecords']['parameters']['outputSchema']\
         ['values'].append(self.outputschema)
@@ -77,7 +79,7 @@ class Profile(object):
 
     def check_parameters(self):
         ''' Perform extra parameters checking.
-            Return dict with keys "locator", "code", "text" or None ''' 
+            Return dict with keys "locator", "code", "text" or None '''
         raise NotImplementedError
 
     def get_extendedcapabilities(self):
@@ -87,7 +89,7 @@ class Profile(object):
     def get_schemacomponents(self):
         ''' Return schema components as lxml.etree.Element list '''
         raise NotImplementedError
-    
+
     def check_getdomain(self, kvp):
         '''Perform extra profile specific checks in the GetDomain request'''
         raise NotImplementedError
@@ -97,43 +99,43 @@ class Profile(object):
         raise NotImplementedError
 
     def transform2dcmappings(self, queryables):
-        ''' Transform information model mappings into csw:Record mappings ''' 
+        ''' Transform information model mappings into csw:Record mappings '''
         raise NotImplementedError
 
 def load_profiles(path, cls, profiles):
-    ''' load CSW profiles, return dict by class name ''' 
+    ''' load CSW profiles, return dict by class name '''
 
     def look_for_subclass(modulename):
         module = __import__(modulename)
- 
+
         dmod = module.__dict__
         for modname in modulename.split('.')[1:]:
             dmod = dmod[modname].__dict__
- 
+
         for key, entry in dmod.items():
             if key == cls.__name__:
                 continue
- 
+
             try:
                 if issubclass(entry, cls):
                     aps['plugins'][key] = entry
             except TypeError:
                 continue
- 
+
     aps = {}
     aps['plugins'] = {}
     aps['loaded'] = {}
 
     for prof in profiles.split(','):
-        # fgdc, atom, dif are supported in core
+        # fgdc, atom, dif, gm03 are supported in core
         # no need to specify them explicitly anymore
         # provide deprecation warning
         # https://github.com/geopython/pycsw/issues/118
-        if prof in ['fgdc', 'atom', 'dif']:
+        if prof in ['fgdc', 'atom', 'dif', 'gm03']:
             warnings.warn('%s is now a core module, and does not need to be'
                           ' specified explicitly.  So you can remove %s from '
                           'server.profiles' % (prof, prof))
-        else: 
+        else:
             modulename='%s.%s.%s' % (path.replace(os.sep, '.'), prof, prof)
             look_for_subclass(modulename)
     return aps
diff --git a/pycsw/plugins/repository/__init__.py b/pycsw/plugins/repository/__init__.py
index 0b17d0e..08a4c3d 100644
--- a/pycsw/plugins/repository/__init__.py
+++ b/pycsw/plugins/repository/__init__.py
@@ -1,9 +1,9 @@
-# -*- coding: ISO-8859-15 -*-
+# -*- coding: utf-8 -*-
 # =================================================================
 #
 # Authors: Tom Kralidis <tomkralidis at gmail.com>
 #
-# Copyright (c) 2012 Tom Kralidis
+# Copyright (c) 2015 Tom Kralidis
 #
 # Permission is hereby granted, free of charge, to any person
 # obtaining a copy of this software and associated documentation
diff --git a/pycsw/plugins/repository/geonode/__init__.py b/pycsw/plugins/repository/geonode/__init__.py
index 0b17d0e..08a4c3d 100644
--- a/pycsw/plugins/repository/geonode/__init__.py
+++ b/pycsw/plugins/repository/geonode/__init__.py
@@ -1,9 +1,9 @@
-# -*- coding: ISO-8859-15 -*-
+# -*- coding: utf-8 -*-
 # =================================================================
 #
 # Authors: Tom Kralidis <tomkralidis at gmail.com>
 #
-# Copyright (c) 2012 Tom Kralidis
+# Copyright (c) 2015 Tom Kralidis
 #
 # Permission is hereby granted, free of charge, to any person
 # obtaining a copy of this software and associated documentation
diff --git a/pycsw/plugins/repository/geonode/geonode_.py b/pycsw/plugins/repository/geonode/geonode_.py
index d3ce993..559556a 100644
--- a/pycsw/plugins/repository/geonode/geonode_.py
+++ b/pycsw/plugins/repository/geonode/geonode_.py
@@ -1,9 +1,9 @@
-# -*- coding: iso-8859-15 -*-
+# -*- coding: utf-8 -*-
 # =================================================================
 #
 # Authors: Tom Kralidis <tomkralidis at gmail.com>
 #
-# Copyright (c) 2012 Tom Kralidis
+# Copyright (c) 2015 Tom Kralidis
 #
 # Permission is hereby granted, free of charge, to any person
 # obtaining a copy of this software and associated documentation
@@ -33,7 +33,7 @@ from django.db import connection
 from django.db.models import Avg, Max, Min, Count
 from django.conf import settings
 
-from pycsw import util
+from pycsw.core import util
 from geonode.base.models import ResourceBase
 
 class GeoNodeRepository(object):
@@ -68,7 +68,7 @@ class GeoNodeRepository(object):
                 self.queryables[qname] = {}
 
                 for qkey, qvalue in \
-                self.context.model['typenames'][tname]['queryables'][qname].iteritems():
+                self.context.model['typenames'][tname]['queryables'][qname].items():
                     self.queryables[qname][qkey] = qvalue
 
         # flatten all queryables
diff --git a/pycsw/formats/__init__.py b/pycsw/plugins/repository/hhypermap/__init__.py
similarity index 97%
rename from pycsw/formats/__init__.py
rename to pycsw/plugins/repository/hhypermap/__init__.py
index 0b17d0e..1cc40dc 100644
--- a/pycsw/formats/__init__.py
+++ b/pycsw/plugins/repository/hhypermap/__init__.py
@@ -3,7 +3,7 @@
 #
 # Authors: Tom Kralidis <tomkralidis at gmail.com>
 #
-# Copyright (c) 2012 Tom Kralidis
+# Copyright (c) 2016 Tom Kralidis
 #
 # Permission is hereby granted, free of charge, to any person
 # obtaining a copy of this software and associated documentation
diff --git a/pycsw/plugins/repository/odc/odc.py b/pycsw/plugins/repository/hhypermap/hhypermap.py
similarity index 64%
copy from pycsw/plugins/repository/odc/odc.py
copy to pycsw/plugins/repository/hhypermap/hhypermap.py
index 9801e1c..752f71a 100644
--- a/pycsw/plugins/repository/odc/odc.py
+++ b/pycsw/plugins/repository/hhypermap/hhypermap.py
@@ -1,9 +1,9 @@
-#-*- coding: iso-8859-15 -*-
+# -*- coding: iso-8859-15 -*-
 # =================================================================
 #
 # Authors: Tom Kralidis <tomkralidis at gmail.com>
 #
-# Copyright (c) 2012 Tom Kralidis
+# Copyright (c) 2016 Tom Kralidis
 #
 # Permission is hereby granted, free of charge, to any person
 # obtaining a copy of this software and associated documentation
@@ -28,17 +28,24 @@
 #
 # =================================================================
 
-import os, sys
-
 from django.db import models
 from django.db import connection
 from django.db.models import Avg, Max, Min, Count
 from django.conf import settings
 
-from pycsw import util
-from OpenDataCatalog.opendata.models import Resource
+from pycsw.core import util
+from aggregator.models import Layer, Resource, Service
+
+HYPERMAP_SERVICE_TYPES = {
+    # 'HHypermap enum': 'CSW enum'
+    'http://www.opengis.net/wms': 'OGC:WMS',
+    'http://www.opengis.net/wmts/1.0': 'OGC:WMTS',
+    'https://wiki.osgeo.org/wiki/TMS': 'OSGeo:TMS',
+    'urn:x-esri:serviceType:ArcGIS:MapServer': 'ESRI:ArcGIS:MapServer',
+    'urn:x-esri:serviceType:ArcGIS:ImageServer': 'ESRI:ArcGIS:ImageServer'
+}
 
-class OpenDataCatalogRepository(object):
+class HHypermapRepository(object):
     ''' Class to interact with underlying repository '''
     def __init__(self, context, repo_filter=None):
         ''' Initialize repository '''
@@ -46,13 +53,15 @@ class OpenDataCatalogRepository(object):
         self.context = context
         self.filter = repo_filter
         self.fts = False
+        self.label = 'HHypermap'
+        self.local_ingest = True
 
         self.dbtype = settings.DATABASES['default']['ENGINE'].split('.')[-1]
 
-        # ODC PostgreSQL installs are not PostGIS enabled
+        # HHypermap PostgreSQL installs are PostGIS enabled
         if self.dbtype == 'postgresql_psycopg2':
-            self.dbtype = 'postgresql'
-            
+            self.dbtype = 'postgresql+postgis+wkt'
+
         if self.dbtype in ['sqlite', 'sqlite3']:  # load SQLite query bindings
             cursor = connection.cursor()
             connection.connection.create_function(
@@ -70,7 +79,7 @@ class OpenDataCatalogRepository(object):
                 self.queryables[qname] = {}
 
                 for qkey, qvalue in \
-                self.context.model['typenames'][tname]['queryables'][qname].iteritems():
+                self.context.model['typenames'][tname]['queryables'][qname].items():
                     self.queryables[qname][qkey] = qvalue
 
         # flatten all queryables
@@ -80,16 +89,16 @@ class OpenDataCatalogRepository(object):
             self.queryables['_all'].update(self.queryables[qbl])
         self.queryables['_all'].update(self.context.md_core_model['mappings'])
 
+        self.context.model['operations']['Harvest']['parameters']['ResourceType']['values'] = HYPERMAP_SERVICE_TYPES.keys()
+        self.context.model['operations']['Transaction']['parameters']['TransactionSchemas']['values'] = HYPERMAP_SERVICE_TYPES.keys()
+
+    def dataset(self):
+        ''' Stub to mock a pycsw dataset object for Transactions'''
+        return type('Resource', (object,), {})
+
     def query_ids(self, ids):
         ''' Query by list of identifiers '''
-
-        # identifiers are URN masked, where the last token of the identifier
-        # is opendata.models.Resource.id (integer)
-        # if ids are passed which are not int, silently return (does not exist)
-        try:
-            return self._get_repo_filter(Resource.objects).filter(id__in=[s.split(':')[-1] for s in ids]).all()
-        except Exception as err:
-            return []
+        return self._get_repo_filter(Resource.objects).filter(id__in=ids).all()
 
     def query_domain(self, domain, typenames, domainquerytype='list',
         count=False):
@@ -110,7 +119,7 @@ class OpenDataCatalogRepository(object):
     def query_insert(self, direction='max'):
         ''' Query to get latest (default) or earliest update to repository '''
         from datetime import datetime
-        if direction == 'min':
+        if direction=='min':
             return Resource.objects.aggregate(
                 Min('last_updated'))['last_updated__min'].strftime('%Y-%m-%dT%H:%M:%SZ')
         return self._get_repo_filter(Resource.objects).aggregate(
@@ -118,7 +127,7 @@ class OpenDataCatalogRepository(object):
 
     def query_source(self, source):
         ''' Query by source '''
-        return self._get_repo_filter(Resource.objects).filter(source=source)
+        return self._get_repo_filter(Resource.objects).filter(url=source)
 
     def query(self, constraint, sortby=None, typenames=None,
         maxrecords=10, startposition=0):
@@ -141,15 +150,51 @@ class OpenDataCatalogRepository(object):
                     desc = True
                 query = query.all()
                 return [str(total), sorted(query, key=lambda x: float(util.get_geometry_area(getattr(x, sortby['propertyname']))), reverse=desc)[startposition:startposition+int(maxrecords)]]
-            if sortby['order'] == 'DESC':
-                pname = '-%s' % sortby['propertyname']
             else:
-                pname = sortby['propertyname']
-            return [str(total), \
-            query.order_by(pname)[startposition:startposition+int(maxrecords)]]
+                if sortby['order'] == 'DESC':
+                    pname = '-%s' % sortby['propertyname']
+                else:
+                    pname = sortby['propertyname']
+                return [str(total), \
+                query.order_by(pname)[startposition:startposition+int(maxrecords)]]
         else:  # no sort
             return [str(total), query.all()[startposition:startposition+int(maxrecords)]]
 
+    def insert(self, resourcetype, source):
+        ''' Insert a record into the repository '''
+
+        if resourcetype not in HYPERMAP_SERVICE_TYPES.keys():
+           raise RuntimeError('Unsupported Service Type')
+
+        return self._insert_or_update(resourcetype, source, mode='insert')
+
+    def _insert_or_update(self, resourcetype, source, mode='insert'):
+        ''' Insert or update a record in the repository '''
+
+        try:
+            s = Service(type=HYPERMAP_SERVICE_TYPES[resourcetype], url=source)
+            s.save()
+        except Exception as err:
+           raise RuntimeError('HHypermap error: %s' % err)
+
+        # return a list of ids that were inserted or updated
+        ids = []
+        for res in Resource.objects.filter(url=source).all():
+            ids.append({'identifier': res.id_string, 'title': res.title})
+        return ids
+        
+    def delete(self, constraint):
+        ''' Delete a record from the repository '''
+
+        # FIXME: id_string is a virtual property and cannot be queried against
+        constraint['where'] = constraint['where'].replace('id_string', 'id')
+
+        results = self._get_repo_filter(Service.objects).extra(where=[constraint['where']],
+                                                               params=constraint['values']).all()
+        deleted = len(results)
+        results.delete()
+        return deleted
+
     def _get_repo_filter(self, query):
         ''' Apply repository wide side filter / mask query '''
         if self.filter is not None:
diff --git a/pycsw/plugins/repository/odc/__init__.py b/pycsw/plugins/repository/odc/__init__.py
index 0b17d0e..08a4c3d 100644
--- a/pycsw/plugins/repository/odc/__init__.py
+++ b/pycsw/plugins/repository/odc/__init__.py
@@ -1,9 +1,9 @@
-# -*- coding: ISO-8859-15 -*-
+# -*- coding: utf-8 -*-
 # =================================================================
 #
 # Authors: Tom Kralidis <tomkralidis at gmail.com>
 #
-# Copyright (c) 2012 Tom Kralidis
+# Copyright (c) 2015 Tom Kralidis
 #
 # Permission is hereby granted, free of charge, to any person
 # obtaining a copy of this software and associated documentation
diff --git a/pycsw/plugins/repository/odc/odc.py b/pycsw/plugins/repository/odc/odc.py
index 9801e1c..c336b5f 100644
--- a/pycsw/plugins/repository/odc/odc.py
+++ b/pycsw/plugins/repository/odc/odc.py
@@ -1,9 +1,9 @@
-#-*- coding: iso-8859-15 -*-
+#-*- coding: utf-8 -*-
 # =================================================================
 #
 # Authors: Tom Kralidis <tomkralidis at gmail.com>
 #
-# Copyright (c) 2012 Tom Kralidis
+# Copyright (c) 2015 Tom Kralidis
 #
 # Permission is hereby granted, free of charge, to any person
 # obtaining a copy of this software and associated documentation
@@ -35,7 +35,7 @@ from django.db import connection
 from django.db.models import Avg, Max, Min, Count
 from django.conf import settings
 
-from pycsw import util
+from pycsw.core import util
 from OpenDataCatalog.opendata.models import Resource
 
 class OpenDataCatalogRepository(object):
@@ -52,7 +52,7 @@ class OpenDataCatalogRepository(object):
         # ODC PostgreSQL installs are not PostGIS enabled
         if self.dbtype == 'postgresql_psycopg2':
             self.dbtype = 'postgresql'
-            
+
         if self.dbtype in ['sqlite', 'sqlite3']:  # load SQLite query bindings
             cursor = connection.cursor()
             connection.connection.create_function(
@@ -70,7 +70,7 @@ class OpenDataCatalogRepository(object):
                 self.queryables[qname] = {}
 
                 for qkey, qvalue in \
-                self.context.model['typenames'][tname]['queryables'][qname].iteritems():
+                self.context.model['typenames'][tname]['queryables'][qname].items():
                     self.queryables[qname][qkey] = qvalue
 
         # flatten all queryables
diff --git a/pycsw/server.py b/pycsw/server.py
index eb9a146..3562d4d 100644
--- a/pycsw/server.py
+++ b/pycsw/server.py
@@ -1,10 +1,12 @@
-# -*- coding: iso-8859-15 -*-
+# -*- coding: utf-8 -*-
 # =================================================================
 #
 # Authors: Tom Kralidis <tomkralidis at gmail.com>
 #          Angelos Tzotsos <tzotsos at gmail.com>
 #
-# Copyright (c) 2010 Tom Kralidis
+# Copyright (c) 2016 Tom Kralidis
+# Copyright (c) 2015 Angelos Tzotsos
+# Copyright (c) 2016 James Dickens
 #
 # Permission is hereby granted, free of charge, to any person
 # obtaining a copy of this software and associated documentation
@@ -29,26 +31,29 @@
 #
 # =================================================================
 
+import logging
 import os
+from six.moves.urllib.parse import quote, unquote
+from six.moves.urllib.parse import urlparse
+from six import StringIO
+from six.moves.configparser import SafeConfigParser
 import sys
-import cgi
-from urllib2 import quote, unquote
-import urlparse
-from cStringIO import StringIO
-from ConfigParser import SafeConfigParser
-from lxml import etree
+from time import time
+
+from pycsw.core.etree import etree
+from pycsw import oaipmh, opensearch, sru
 from pycsw.plugins.profiles import profile as pprofile
 import pycsw.plugins.outputschemas
-from pycsw import config, fes, log, metadata, util, sru, oaipmh, opensearch
-import logging
+from pycsw.core import config, log, util
+from pycsw.ogc.csw import csw2, csw3
 
 LOGGER = logging.getLogger(__name__)
 
 
 class Csw(object):
-    ''' Base CSW server '''
-    def __init__(self, rtconfig=None, env=None):
-        ''' Initialize CSW '''
+    """ Base CSW server """
+    def __init__(self, rtconfig=None, env=None, version='3.0.0'):
+        """ Initialize CSW """
 
         if not env:
             self.environ = os.environ
@@ -71,7 +76,9 @@ class Csw(object):
         self.soap = False
         self.request = None
         self.exception = False
+        self.status = 'OK'
         self.profiles = None
+        self.manager = False
         self.outputschemas = {}
         self.mimetype = 'application/xml; charset=UTF-8'
         self.encoding = 'UTF-8'
@@ -79,6 +86,15 @@ class Csw(object):
         self.domainquerytype = 'list'
         self.orm = 'django'
         self.language = {'639_code': 'en', 'text': 'english'}
+        self.process_time_start = time()
+
+        # define CSW implementation object (default CSW3)
+        self.iface = csw3.Csw3(server_csw=self)
+        self.request_version = version
+
+        if self.request_version == '2.0.2':
+            self.iface = csw2.Csw2(server_csw=self)
+            self.context.set_model('csw')
 
         # load user configuration
         try:
@@ -87,46 +103,40 @@ class Csw(object):
             else:
                 self.config = SafeConfigParser()
                 if isinstance(rtconfig, dict):  # dictionary
-                    for section, options in rtconfig.iteritems():
+                    for section, options in rtconfig.items():
                         self.config.add_section(section)
-                        for k, v in options.iteritems():
+                        for k, v in options.items():
                             self.config.set(section, k, v)
                 else:  # configuration file
                     import codecs
                     with codecs.open(rtconfig, encoding='utf-8') as scp:
                         self.config.readfp(scp)
-        except Exception as err:
-            self.response = self.exceptionreport(
-            'NoApplicableCode', 'service',
-            'Error opening configuration %s' % rtconfig)
+        except Exception:
+            self.response = self.iface.exceptionreport(
+                'NoApplicableCode', 'service',
+                'Error opening configuration %s' % rtconfig
+            )
             return
 
         # set server.home safely
         # TODO: make this more abstract
-        self.config.set('server', 'home', os.path.dirname(
-        os.path.join(os.path.dirname(__file__), '..')))
+        self.config.set(
+            'server', 'home',
+            os.path.dirname(os.path.join(os.path.dirname(__file__), '..'))
+        )
 
         self.context.pycsw_home = self.config.get('server', 'home')
         self.context.url = self.config.get('server', 'url')
 
-        # configure transaction support, if specified in config
-        self._gen_manager()
-
         log.setup_logger(self.config)
 
         LOGGER.debug('running configuration %s' % rtconfig)
         LOGGER.debug(str(self.environ['QUERY_STRING']))
 
-        # generate domain model
-        # NOTE: We should probably avoid this sort of mutable state for WSGI
-        if 'GetDomain' not in self.context.model['operations']:
-            self.context.model['operations']['GetDomain'] = \
-            self.context.gen_domains()
-
         # set OGC schemas location
         if not self.config.has_option('server', 'ogc_schemas_base'):
             self.config.set('server', 'ogc_schemas_base',
-            self.context.ogc_schemas_base)
+                            self.context.ogc_schemas_base)
 
         # set mimetype
         if self.config.has_option('server', 'mimetype'):
@@ -142,16 +152,16 @@ class Csw(object):
 
         # set XML pretty print
         if (self.config.has_option('server', 'pretty_print') and
-        self.config.get('server', 'pretty_print') == 'true'):
+                self.config.get('server', 'pretty_print') == 'true'):
             self.pretty_print = 1
-        
+
         # set Spatial Ranking option
         if (self.config.has_option('server', 'spatial_ranking') and
-        self.config.get('server', 'spatial_ranking') == 'true'):
+                self.config.get('server', 'spatial_ranking') == 'true'):
             util.ranking_enabled = True
 
         # set language default
-        if (self.config.has_option('server', 'language')):
+        if self.config.has_option('server', 'language'):
             try:
                 LOGGER.info('Setting language')
                 lang_code = self.config.get('server', 'language').split('-')[0]
@@ -160,23 +170,6 @@ class Csw(object):
             except:
                 pass
 
-        # generate distributed search model, if specified in config
-        if self.config.has_option('server', 'federatedcatalogues'):
-            LOGGER.debug('Configuring distributed search.')
-
-            self.context.model['constraints']['FederatedCatalogues'] = \
-            {'values': []}
-
-            for fedcat in \
-            self.config.get('server', 'federatedcatalogues').split(','):
-                self.context.model\
-                ['constraints']['FederatedCatalogues']['values'].append(fedcat)
-
-        LOGGER.debug('Setting MaxRecordDefault')
-        if self.config.has_option('server', 'maxrecords'):
-            self.context.model['constraints']['MaxRecordDefault']['values'] = \
-            [self.config.get('server', 'maxrecords')]
-
         LOGGER.debug('Configuration: %s.' % self.config)
         LOGGER.debug('Model: %s.' % self.context.model)
 
@@ -185,150 +178,43 @@ class Csw(object):
             # override default repository mappings
             try:
                 import imp
-                module = self.config.get('repository','mappings')
-                modulename = '%s' % \
-                os.path.splitext(module)[0].replace(os.sep, '.')
-                LOGGER.debug(
-                'Loading custom repository mappings from %s.' % module)
+                module = self.config.get('repository', 'mappings')
+                modulename = '%s' % os.path.splitext(module)[0].replace(
+                    os.sep, '.')
+                LOGGER.debug('Loading custom repository mappings '
+                             'from %s.' % module)
                 mappings = imp.load_source(modulename, module)
                 self.context.md_core_model = mappings.MD_CORE_MODEL
                 self.context.refresh_dc(mappings.MD_CORE_MODEL)
             except Exception as err:
-                self.response = self.exceptionreport(
-                'NoApplicableCode', 'service',
-                'Could not load repository.mappings %s' % str(err))
-
-        # load profiles
-        LOGGER.debug('Loading profiles.')
-
-        if self.config.has_option('server', 'profiles'):
-            self.profiles = pprofile.load_profiles(
-            os.path.join('pycsw', 'plugins', 'profiles'),
-            pprofile.Profile,
-            self.config.get('server', 'profiles'))
-
-            for prof in self.profiles['plugins'].keys():
-                tmp = self.profiles['plugins'][prof](self.context.model,
-                self.context.namespaces, self.context)
-
-                key = tmp.outputschema  # to ref by outputschema
-                self.profiles['loaded'][key] = tmp
-                self.profiles['loaded'][key].extend_core(
-                self.context.model, self.context.namespaces,
-                self.config)
-
-            LOGGER.debug('Profiles loaded: %s.' %
-            self.profiles['loaded'].keys())
+                self.response = self.iface.exceptionreport(
+                    'NoApplicableCode', 'service',
+                    'Could not load repository.mappings %s' % str(err)
+                )
 
-        # load profiles
+        # load outputschemas
         LOGGER.debug('Loading outputschemas.')
 
         for osch in pycsw.plugins.outputschemas.__all__:
-            mod = getattr(__import__('pycsw.plugins.outputschemas.%s' % osch).plugins.outputschemas, osch)
-            self.context.model['operations']['GetRecords']['parameters']['outputSchema']['values'].append(mod.NAMESPACE)
-            self.context.model['operations']['GetRecordById']['parameters']['outputSchema']['values'].append(mod.NAMESPACE)
-            if 'Harvest' in self.context.model['operations']:
-                self.context.model['operations']['Harvest']['parameters']['ResourceType']['values'].append(mod.NAMESPACE)
+            output_schema_module = __import__(
+                'pycsw.plugins.outputschemas.%s' % osch)
+            mod = getattr(output_schema_module.plugins.outputschemas, osch)
             self.outputschemas[mod.NAMESPACE] = mod
 
         LOGGER.debug('Outputschemas loaded: %s.' % self.outputschemas)
-
         LOGGER.debug('Namespaces: %s' % self.context.namespaces)
 
-        # init repository
-        # look for tablename, set 'records' as default
-        if not self.config.has_option('repository', 'table'):
-            self.config.set('repository', 'table', 'records')
-
-        repo_filter = None
-        if self.config.has_option('repository', 'filter'):
-            repo_filter = self.config.get('repository', 'filter')
-
-        if (self.config.has_option('repository', 'source') and
-            self.config.get('repository', 'source') == 'geonode'):
-
-            # load geonode repository
-            from pycsw.plugins.repository.geonode import geonode_
-
-            try:
-                self.repository = \
-                geonode_.GeoNodeRepository(self.context, repo_filter)
-                LOGGER.debug('GeoNode repository loaded (geonode): %s.' % \
-                self.repository.dbtype)
-            except Exception as err:
-                self.response = self.exceptionreport(
-                'NoApplicableCode', 'service',
-                'Could not load repository (geonode): %s' % str(err))
-
-        elif (self.config.has_option('repository', 'source') and
-            self.config.get('repository', 'source') == 'odc'):
-
-            # load odc repository
-            from pycsw.plugins.repository.odc import odc
-
-            try:
-                self.repository = \
-                odc.OpenDataCatalogRepository(self.context, repo_filter)
-                LOGGER.debug('OpenDataCatalog repository loaded (geonode): %s.' % \
-                self.repository.dbtype)
-            except Exception as err:
-                self.response = self.exceptionreport(
-                'NoApplicableCode', 'service',
-                'Could not load repository (odc): %s' % str(err))
-
-        else:  # load default repository
-            self.orm = 'sqlalchemy'
-            from pycsw import repository
-            try:
-                self.repository = \
-                repository.Repository(self.config.get('repository', 'database'),
-                self.context, self.environ.get('local.app_root', None),
-                self.config.get('repository', 'table'), repo_filter)
-                LOGGER.debug('Repository loaded (local): %s.' \
-                % self.repository.dbtype)
-            except Exception as err:
-                self.response = self.exceptionreport(
-                'NoApplicableCode', 'service',
-                'Could not load repository (local): %s' % str(err))
-
     def expand_path(self, path):
-        ''' return safe path for WSGI environments '''
+        """ return safe path for WSGI environments """
         if 'local.app_root' in self.environ and not os.path.isabs(path):
             return os.path.join(self.environ['local.app_root'], path)
         else:
             return path
 
-    def dispatch_cgi(self):
-        ''' CGI handler '''
-
-        if hasattr(self,'response'):
-            return self._write_response()
-
-        LOGGER.debug('CGI mode detected')
-
-        cgifs = cgi.FieldStorage(keep_blank_values=1)
-
-        if cgifs.file:  # it's a POST request
-            postdata = cgifs.file.read()
-            self.requesttype = 'POST'
-            self.request = postdata
-            LOGGER.debug('Request type: POST.  Request:\n%s\n', self.request)
-            self.kvp = self.parse_postdata(postdata)
-
-        else:  # it's a GET request
-            self.requesttype = 'GET'
-            self.request = 'http://%s%s' % \
-            (self.environ['HTTP_HOST'], self.environ['REQUEST_URI'])
-            LOGGER.debug('Request type: GET.  Request:\n%s\n', self.request)
-            for key in cgifs.keys():
-                self.kvp[key.lower()] = cgifs[key].value
-
-        return self.dispatch()
-
     def dispatch_wsgi(self):
-        ''' WSGI handler '''
+        """ WSGI handler """
 
-        if hasattr(self,'response'):
+        if hasattr(self, 'response'):
             return self._write_response()
 
         LOGGER.debug('WSGI mode detected')
@@ -339,12 +225,9 @@ class Csw(object):
             except (ValueError):
                 request_body_size = 0
 
-            postdata = self.environ['wsgi.input'].read(request_body_size)
-
             self.requesttype = 'POST'
-            self.request = postdata
+            self.request = self.environ['wsgi.input'].read(request_body_size)
             LOGGER.debug('Request type: POST.  Request:\n%s\n', self.request)
-            self.kvp = self.parse_postdata(postdata)
 
         else:  # it's a GET request
             self.requesttype = 'GET'
@@ -377,41 +260,208 @@ class Csw(object):
             kvp = {}
 
             for pairstr in pairs:
-                pair = pairstr.split("=")
-                pair[0] = pair[0].lower()
-                pair = [unquote(a) for a in pair]
-
-                if len(pair) is 1:
-                    kvp[pair[0]] = ""
-                else:
-                    kvp[pair[0]] = pair[1]
-
+                pair = [unquote(a) for a in pairstr.split("=")]
+                kvp[pair[0]] = pair[1] if len(pair) > 1 else ""
             self.kvp = kvp
 
         return self.dispatch()
 
     def opensearch(self):
-        ''' enable OpenSearch '''
+        """ enable OpenSearch """
         if not self.opensearchobj:
             self.opensearchobj = opensearch.OpenSearch(self.context)
 
         return self.opensearchobj
 
     def sru(self):
-        ''' enable SRU '''
+        """ enable SRU """
         if not self.sruobj:
             self.sruobj = sru.Sru(self.context)
 
         return self.sruobj
 
     def oaipmh(self):
-        ''' enable OAI-PMH '''
+        """ enable OAI-PMH """
         if not self.oaipmhobj:
             self.oaipmhobj = oaipmh.OAIPMH(self.context, self.config)
         return self.oaipmhobj
 
     def dispatch(self, writer=sys.stdout, write_headers=True):
-        ''' Handle incoming HTTP request '''
+        """ Handle incoming HTTP request """
+
+        if self.requesttype == 'GET':
+            self.kvp = self.normalize_kvp(self.kvp)
+            version_202 = ('version' in self.kvp and
+                           self.kvp['version'] == '2.0.2')
+            accept_version_202 = ('acceptversions' in self.kvp and
+                                  '2.0.2' in self.kvp['acceptversions'])
+            if version_202 or accept_version_202:
+                self.request_version = '2.0.2'
+        elif self.requesttype == 'POST':
+            if self.request.find(b'2.0.2') != -1:
+                self.request_version = '2.0.2'
+
+        if (not isinstance(self.kvp, str) and 'mode' in self.kvp and
+                self.kvp['mode'] == 'sru'):
+            self.mode = 'sru'
+            self.request_version = '2.0.2'
+            LOGGER.debug('SRU mode detected; processing request.')
+            self.kvp = self.sru().request_sru2csw(self.kvp)
+
+        if (not isinstance(self.kvp, str) and 'mode' in self.kvp and
+                self.kvp['mode'] == 'oaipmh'):
+            self.mode = 'oaipmh'
+            self.request_version = '2.0.2'
+            LOGGER.debug('OAI-PMH mode detected; processing request.')
+            self.oaiargs = dict((k, v) for k, v in self.kvp.items() if k)
+            self.kvp = self.oaipmh().request(self.kvp)
+
+        if self.request_version == '2.0.2':
+            self.iface = csw2.Csw2(server_csw=self)
+            self.context.set_model('csw')
+
+        # configure transaction support, if specified in config
+        self._gen_manager()
+
+        namespaces = self.context.namespaces
+        ops = self.context.model['operations']
+        constraints = self.context.model['constraints']
+        # generate domain model
+        # NOTE: We should probably avoid this sort of mutable state for WSGI
+        if 'GetDomain' not in ops:
+            ops['GetDomain'] = self.context.gen_domains()
+
+        # generate distributed search model, if specified in config
+        if self.config.has_option('server', 'federatedcatalogues'):
+            LOGGER.debug('Configuring distributed search.')
+
+            constraints['FederatedCatalogues'] = {'values': []}
+
+            for fedcat in self.config.get('server',
+                                          'federatedcatalogues').split(','):
+                constraints['FederatedCatalogues']['values'].append(fedcat)
+
+        for key, value in self.outputschemas.items():
+            get_records_params = ops['GetRecords']['parameters']
+            get_records_params['outputSchema']['values'].append(
+                value.NAMESPACE)
+            get_records_by_id_params = ops['GetRecordById']['parameters']
+            get_records_by_id_params['outputSchema']['values'].append(
+                value.NAMESPACE)
+            if 'Harvest' in ops:
+                harvest_params = ops['Harvest']['parameters']
+                harvest_params['ResourceType']['values'].append(
+                    value.NAMESPACE)
+
+        LOGGER.debug('Setting MaxRecordDefault')
+        if self.config.has_option('server', 'maxrecords'):
+            constraints['MaxRecordDefault']['values'] = [
+                self.config.get('server', 'maxrecords')]
+
+        # load profiles
+        if self.config.has_option('server', 'profiles'):
+            self.profiles = pprofile.load_profiles(
+                os.path.join('pycsw', 'plugins', 'profiles'),
+                pprofile.Profile,
+                self.config.get('server', 'profiles')
+            )
+
+            for prof in self.profiles['plugins'].keys():
+                tmp = self.profiles['plugins'][prof](self.context.model,
+                                                     namespaces,
+                                                     self.context)
+
+                key = tmp.outputschema  # to ref by outputschema
+                self.profiles['loaded'][key] = tmp
+                self.profiles['loaded'][key].extend_core(self.context.model,
+                                                         namespaces,
+                                                         self.config)
+
+            LOGGER.debug('Profiles loaded: %s.' %
+            list(self.profiles['loaded'].keys()))
+
+        # init repository
+        # look for tablename, set 'records' as default
+        if not self.config.has_option('repository', 'table'):
+            self.config.set('repository', 'table', 'records')
+
+        repo_filter = None
+        if self.config.has_option('repository', 'filter'):
+            repo_filter = self.config.get('repository', 'filter')
+
+        if (self.config.has_option('repository', 'source') and
+                self.config.get('repository', 'source') == 'geonode'):
+
+            # load geonode repository
+            from pycsw.plugins.repository.geonode import geonode_
+
+            try:
+                self.repository = geonode_.GeoNodeRepository(self.context,
+                                                             repo_filter)
+                LOGGER.debug('GeoNode repository loaded '
+                             '(geonode): %s.' % self.repository.dbtype)
+            except Exception as err:
+                self.response = self.iface.exceptionreport(
+                    'NoApplicableCode', 'service',
+                    'Could not load repository (geonode): %s' % str(err)
+                )
+
+        elif (self.config.has_option('repository', 'source') and
+                self.config.get('repository', 'source') == 'HHypermap'):
+
+            # load HHypermap repository
+            from pycsw.plugins.repository.hhypermap import hhypermap
+
+            try:
+                self.repository = hhypermap.HHypermapRepository(self.context,
+                                                                repo_filter)
+                LOGGER.debug('HHypermap repository loaded '
+                             '(hhypermap): %s.' % self.repository.dbtype)
+            except Exception as err:
+                self.response = self.iface.exceptionreport(
+                    'NoApplicableCode', 'service',
+                    'Could not load repository (hhypermap): %s' % str(err)
+                )
+
+        elif (self.config.has_option('repository', 'source') and
+                self.config.get('repository', 'source') == 'odc'):
+
+            # load odc repository
+            from pycsw.plugins.repository.odc import odc
+
+            try:
+                self.repository = odc.OpenDataCatalogRepository(self.context,
+                                                                repo_filter)
+                LOGGER.debug('OpenDataCatalog repository loaded '
+                             '(geonode): %s.' % self.repository.dbtype)
+            except Exception as err:
+                self.response = self.iface.exceptionreport(
+                    'NoApplicableCode', 'service',
+                    'Could not load repository (odc): %s' % str(err)
+                )
+
+        else:  # load default repository
+            self.orm = 'sqlalchemy'
+            from pycsw.core import repository
+            try:
+                self.repository = repository.Repository(
+                    self.config.get('repository', 'database'),
+                    self.context,
+                    self.environ.get('local.app_root', None),
+                    self.config.get('repository', 'table'),
+                    repo_filter
+                )
+                LOGGER.debug(
+                    'Repository loaded (local): %s.' % self.repository.dbtype)
+            except Exception as err:
+                self.response = self.iface.exceptionreport(
+                    'NoApplicableCode', 'service',
+                    'Could not load repository (local): %s' % str(err)
+                )
+
+        if self.requesttype == 'POST':
+            LOGGER.debug(self.iface.version)
+            self.kvp = self.iface.parse_postdata(self.request)
 
         error = 0
 
@@ -420,7 +470,7 @@ class Csw(object):
             locator = 'service'
             text = self.kvp
             if (self.kvp.find('the document is not valid') != -1 or
-                self.kvp.find('document not well-formed') != -1):
+                    self.kvp.find('document not well-formed') != -1):
                 code = 'NoApplicableCode'
             else:
                 code = 'InvalidParameterValue'
@@ -428,34 +478,41 @@ class Csw(object):
         LOGGER.debug('HTTP Headers:\n%s.' % self.environ)
         LOGGER.debug('Parsed request parameters: %s' % self.kvp)
 
-        if (not isinstance(self.kvp, str) and
-        'mode' in self.kvp and self.kvp['mode'] == 'sru'):
-            self.mode = 'sru'
-            LOGGER.debug('SRU mode detected; processing request.')
-            self.kvp = self.sru().request_sru2csw(self.kvp)
-
-        if (not isinstance(self.kvp, str) and
-        'mode' in self.kvp and self.kvp['mode'] == 'opensearch'):
+        if (not isinstance(self.kvp, str) and 'mode' in self.kvp and
+                self.kvp['mode'] == 'opensearch'):
             self.mode = 'opensearch'
             LOGGER.debug('OpenSearch mode detected; processing request.')
             self.kvp['outputschema'] = 'http://www.w3.org/2005/Atom'
 
-        if (not isinstance(self.kvp, str) and
-        'mode' in self.kvp and self.kvp['mode'] == 'oaipmh'):
-            self.mode = 'oaipmh'
-            LOGGER.debug('OAI-PMH mode detected; processing request.')
-            self.oaiargs =  dict((k, v) for k, v in self.kvp.items() if k)
-            self.kvp = self.oaipmh().request(self.kvp)
+        if ((self.kvp == {'': ''} and self.request_version == '3.0.0') or
+                (len(self.kvp) == 1 and 'config' in self.kvp)):
+            LOGGER.debug('Turning on default csw30:Capabilities for base URL')
+            self.kvp = {
+                'service': 'CSW',
+                'acceptversions': '3.0.0',
+                'request': 'GetCapabilities'
+            }
+            http_accept = self.environ.get('HTTP_ACCEPT', '')
+            if 'application/opensearchdescription+xml' in http_accept:
+                self.mode = 'opensearch'
+                self.kvp['outputschema'] = 'http://www.w3.org/2005/Atom'
 
         if error == 0:
             # test for the basic keyword values (service, version, request)
-            for k in ['service', 'version', 'request']:
+            basic_options = ['service', 'request']
+            request = self.kvp.get('request', '')
+            own_version_integer = util.get_version_integer(
+                self.request_version)
+            if self.request_version == '2.0.2':
+                basic_options.append('version')
+
+            for k in basic_options:
                 if k not in self.kvp:
-                    if (k == 'version' and 'request' in self.kvp and
-                    self.kvp['request'] == 'GetCapabilities'):
+                    if (k in ['version', 'acceptversions'] and
+                            request == 'GetCapabilities'):
                         pass
                     else:
-                        error   = 1
+                        error = 1
                         locator = k
                         code = 'MissingParameterValue'
                         text = 'Missing keyword: %s' % k
@@ -472,46 +529,45 @@ class Csw(object):
                     Value MUST be CSW' % self.kvp['service']
 
                 # test version
-                if ('version' in self.kvp and
-                    util.get_version_integer(self.kvp['version']) !=
-                    util.get_version_integer('2.0.2') and
-                    self.kvp['request'] != 'GetCapabilities'):
+                kvp_version = self.kvp.get('version', '')
+                kvp_version_integer = util.get_version_integer(kvp_version)
+                if (request != 'GetCapabilities' and
+                        kvp_version_integer != own_version_integer):
                     error = 1
                     locator = 'version'
                     code = 'InvalidParameterValue'
-                    text = 'Invalid value for version: %s.\
-                    Value MUST be 2.0.2' % self.kvp['version']
+                    text = ('Invalid value for version: %s. Value MUST be '
+                            '2.0.2 or 3.0.0' % kvp_version)
 
                 # check for GetCapabilities acceptversions
                 if 'acceptversions' in self.kvp:
                     for vers in self.kvp['acceptversions'].split(','):
-                        if (util.get_version_integer(vers) ==
-                            util.get_version_integer('2.0.2')):
+                        vers_integer = util.get_version_integer(vers)
+                        if vers_integer == own_version_integer:
                             break
                         else:
                             error = 1
                             locator = 'acceptversions'
                             code = 'VersionNegotiationFailed'
-                            text = 'Invalid parameter value in acceptversions:\
-                            %s. Value MUST be 2.0.2' % \
-                            self.kvp['acceptversions']
+                            text = ('Invalid parameter value in '
+                                    'acceptversions: %s. Value MUST be '
+                                    '2.0.2 or 3.0.0' %
+                                    self.kvp['acceptversions'])
 
                 # test request
                 if self.kvp['request'] not in \
-                    self.context.model['operations'].keys():
+                    self.context.model['operations']:
                     error = 1
                     locator = 'request'
-                    if self.kvp['request'] in ['Transaction','Harvest']:
+                    if request in ['Transaction', 'Harvest']:
                         code = 'OperationNotSupported'
-                        text = '%s operations are not supported' % \
-                        self.kvp['request']
+                        text = '%s operations are not supported' % request
                     else:
                         code = 'InvalidParameterValue'
-                        text = 'Invalid value for request: %s' % \
-                        self.kvp['request']
+                        text = 'Invalid value for request: %s' % request
 
         if error == 1:  # return an ExceptionReport
-            self.response = self.exceptionreport(code, locator, text)
+            self.response = self.iface.exceptionreport(code, locator, text)
 
         else:  # process per the request value
 
@@ -519,1904 +575,184 @@ class Csw(object):
                 # set flag to process asynchronously
                 import threading
                 self.async = True
-                if ('requestid' not in self.kvp
-                or self.kvp['requestid'] is None):
+                request_id = self.kvp.get('requestid', None)
+                if request_id is None:
                     import uuid
                     self.kvp['requestid'] = str(uuid.uuid4())
 
             if self.kvp['request'] == 'GetCapabilities':
-                self.response = self.getcapabilities()
+                self.response = self.iface.getcapabilities()
             elif self.kvp['request'] == 'DescribeRecord':
-                self.response = self.describerecord()
+                self.response = self.iface.describerecord()
             elif self.kvp['request'] == 'GetDomain':
-                self.response = self.getdomain()
+                self.response = self.iface.getdomain()
             elif self.kvp['request'] == 'GetRecords':
                 if self.async:  # process asynchronously
-                    threading.Thread(target=self.getrecords).start()
-                    self.response = self._write_acknowledgement()
+                    threading.Thread(target=self.iface.getrecords).start()
+                    self.response = self.iface._write_acknowledgement()
                 else:
-                    self.response = self.getrecords()
+                    self.response = self.iface.getrecords()
             elif self.kvp['request'] == 'GetRecordById':
-                self.response = self.getrecordbyid()
+                self.response = self.iface.getrecordbyid()
             elif self.kvp['request'] == 'GetRepositoryItem':
-                self.response = self.getrepositoryitem()
+                self.response = self.iface.getrepositoryitem()
             elif self.kvp['request'] == 'Transaction':
-                self.response = self.transaction()
+                self.response = self.iface.transaction()
             elif self.kvp['request'] == 'Harvest':
                 if self.async:  # process asynchronously
-                    threading.Thread(target=self.harvest).start()
-                    self.response = self._write_acknowledgement()
+                    threading.Thread(target=self.iface.harvest).start()
+                    self.response = self.iface._write_acknowledgement()
                 else:
-                    self.response = self.harvest()
+                    self.response = self.iface.harvest()
             else:
-                self.response = self.exceptionreport('InvalidParameterValue',
-                'request', 'Invalid request parameter: %s' %
-                self.kvp['request'])
+                self.response = self.iface.exceptionreport(
+                    'InvalidParameterValue', 'request',
+                    'Invalid request parameter: %s' % self.kvp['request']
+                )
 
         if self.mode == 'sru':
             LOGGER.debug('SRU mode detected; processing response.')
             self.response = self.sru().response_csw2sru(self.response,
-                            self.environ)
+                                                        self.environ)
         elif self.mode == 'opensearch':
             LOGGER.debug('OpenSearch mode detected; processing response.')
             self.response = self.opensearch().response_csw2opensearch(
-                            self.response, self.config)
+                self.response, self.config)
 
         elif self.mode == 'oaipmh':
             LOGGER.debug('OAI-PMH mode detected; processing response.')
-            self.response = self.oaipmh().response(self.response,
-                            self.oaiargs, self.repository, self.config.get('server', 'url'))
+            self.response = self.oaipmh().response(
+                self.response, self.oaiargs, self.repository,
+                self.config.get('server', 'url')
+            )
 
         return self._write_response()
 
-    def exceptionreport(self, code, locator, text):
-        ''' Generate ExceptionReport '''
-        self.exception = True
-
-        try:
-            language = self.config.get('server', 'language')
-            ogc_schemas_base = self.config.get('server', 'ogc_schemas_base')
-        except:
-            language = 'en-US'
-            ogc_schemas_base = self.context.ogc_schemas_base
-
-        node = etree.Element(util.nspath_eval('ows:ExceptionReport',
-        self.context.namespaces), nsmap=self.context.namespaces,
-        version='1.2.0', language=language)
-
-        node.attrib[util.nspath_eval('xsi:schemaLocation',
-        self.context.namespaces)] = \
-        '%s %s/ows/1.0.0/owsExceptionReport.xsd' % \
-        (self.context.namespaces['ows'], ogc_schemas_base)
-
-        exception = etree.SubElement(node, util.nspath_eval('ows:Exception',
-        self.context.namespaces),
-        exceptionCode=code, locator=locator)
-
-        etree.SubElement(exception,
-        util.nspath_eval('ows:ExceptionText',
-        self.context.namespaces)).text = text
-
-        return node
-
     def getcapabilities(self):
-        ''' Handle GetCapabilities request '''
-        serviceidentification = True
-        serviceprovider = True
-        operationsmetadata = True
-        if 'sections' in self.kvp:
-            serviceidentification = False
-            serviceprovider = False
-            operationsmetadata = False
-            for section in self.kvp['sections'].split(','):
-                if section == 'ServiceIdentification':
-                    serviceidentification = True
-                if section == 'ServiceProvider':
-                    serviceprovider = True
-                if section == 'OperationsMetadata':
-                    operationsmetadata = True
-
-        # check extra parameters that may be def'd by profiles
-        if self.profiles is not None:
-            for prof in self.profiles['loaded'].keys():
-                result = \
-                self.profiles['loaded'][prof].check_parameters(self.kvp)
-                if result is not None:
-                    return self.exceptionreport(result['code'],
-                    result['locator'], result['text'])
-
-        # @updateSequence: get latest update to repository
-        try:
-            updatesequence = \
-            util.get_time_iso2unix(self.repository.query_insert())
-        except:
-            updatesequence = None
-
-        node = etree.Element(util.nspath_eval('csw:Capabilities',
-        self.context.namespaces),
-        nsmap=self.context.namespaces, version='2.0.2',
-        updateSequence=str(updatesequence))
-
-        if 'updatesequence' in self.kvp:
-            if int(self.kvp['updatesequence']) == updatesequence:
-                return node
-            elif int(self.kvp['updatesequence']) > updatesequence:
-                return self.exceptionreport('InvalidUpdateSequence',
-                'updatesequence',
-                'outputsequence specified (%s) is higher than server\'s \
-                updatesequence (%s)' % (self.kvp['updatesequence'],
-                updatesequence))
-
-        node.attrib[util.nspath_eval('xsi:schemaLocation',
-        self.context.namespaces)] = '%s %s/csw/2.0.2/CSW-discovery.xsd' % \
-        (self.context.namespaces['csw'],
-         self.config.get('server', 'ogc_schemas_base'))
-
-        metadata_main = dict(self.config.items('metadata:main'))
-
-        if serviceidentification:
-            LOGGER.debug('Writing section ServiceIdentification.')
-
-            serviceidentification = etree.SubElement(node, \
-            util.nspath_eval('ows:ServiceIdentification',
-            self.context.namespaces))
-
-            etree.SubElement(serviceidentification,
-            util.nspath_eval('ows:Title', self.context.namespaces)).text = \
-            metadata_main.get('identification_title', 'missing')
-
-            etree.SubElement(serviceidentification,
-            util.nspath_eval('ows:Abstract', self.context.namespaces)).text = \
-            metadata_main.get('identification_abstract', 'missing')
-
-            keywords = etree.SubElement(serviceidentification,
-            util.nspath_eval('ows:Keywords', self.context.namespaces))
-
-            for k in \
-            metadata_main.get('identification_keywords').split(','):
-                etree.SubElement(
-                keywords, util.nspath_eval('ows:Keyword',
-                self.context.namespaces)).text = k
-
-            etree.SubElement(keywords,
-            util.nspath_eval('ows:Type', self.context.namespaces),
-            codeSpace='ISOTC211/19115').text = \
-            metadata_main.get('identification_keywords_type', 'missing')
-
-            etree.SubElement(serviceidentification,
-            util.nspath_eval('ows:ServiceType', self.context.namespaces),
-            codeSpace='OGC').text = 'CSW'
-
-            etree.SubElement(serviceidentification,
-            util.nspath_eval('ows:ServiceTypeVersion',
-            self.context.namespaces)).text = '2.0.2'
-
-            etree.SubElement(serviceidentification,
-            util.nspath_eval('ows:Fees', self.context.namespaces)).text = \
-            metadata_main.get('identification_fees', 'missing')
-
-            etree.SubElement(serviceidentification,
-            util.nspath_eval('ows:AccessConstraints',
-            self.context.namespaces)).text = \
-            metadata_main.get('identification_accessconstraints', 'missing')
-
-        if serviceprovider:
-            LOGGER.debug('Writing section ServiceProvider.')
-            serviceprovider = etree.SubElement(node,
-            util.nspath_eval('ows:ServiceProvider', self.context.namespaces))
-
-            etree.SubElement(serviceprovider,
-            util.nspath_eval('ows:ProviderName', self.context.namespaces)).text = \
-            metadata_main.get('provider_name', 'missing')
-
-            providersite = etree.SubElement(serviceprovider,
-            util.nspath_eval('ows:ProviderSite', self.context.namespaces))
-
-            providersite.attrib[util.nspath_eval('xlink:type',
-            self.context.namespaces)] = 'simple'
-
-            providersite.attrib[util.nspath_eval('xlink:href',
-            self.context.namespaces)] = \
-            metadata_main.get('provider_url', 'missing')
-
-            servicecontact = etree.SubElement(serviceprovider,
-            util.nspath_eval('ows:ServiceContact', self.context.namespaces))
-
-            etree.SubElement(servicecontact,
-            util.nspath_eval('ows:IndividualName',
-            self.context.namespaces)).text = \
-            metadata_main.get('contact_name', 'missing')
-
-            etree.SubElement(servicecontact,
-            util.nspath_eval('ows:PositionName',
-            self.context.namespaces)).text = \
-            metadata_main.get('contact_position', 'missing')
-
-            contactinfo = etree.SubElement(servicecontact,
-            util.nspath_eval('ows:ContactInfo', self.context.namespaces))
-
-            phone = etree.SubElement(contactinfo, util.nspath_eval('ows:Phone',
-            self.context.namespaces))
-
-            etree.SubElement(phone, util.nspath_eval('ows:Voice',
-            self.context.namespaces)).text = \
-            metadata_main.get('contact_phone', 'missing')
-
-            etree.SubElement(phone, util.nspath_eval('ows:Facsimile',
-            self.context.namespaces)).text = \
-            metadata_main.get('contact_fax', 'missing')
-
-            address = etree.SubElement(contactinfo,
-            util.nspath_eval('ows:Address', self.context.namespaces))
-
-            etree.SubElement(address,
-            util.nspath_eval('ows:DeliveryPoint',
-            self.context.namespaces)).text = \
-            metadata_main.get('contact_address', 'missing')
-
-            etree.SubElement(address, util.nspath_eval('ows:City',
-            self.context.namespaces)).text = \
-            metadata_main.get('contact_city', 'missing')
-
-            etree.SubElement(address,
-            util.nspath_eval('ows:AdministrativeArea',
-            self.context.namespaces)).text = \
-            metadata_main.get('contact_stateorprovince', 'missing')
-
-            etree.SubElement(address,
-            util.nspath_eval('ows:PostalCode',
-            self.context.namespaces)).text = \
-            metadata_main.get('contact_postalcode', 'missing')
-
-            etree.SubElement(address,
-            util.nspath_eval('ows:Country', self.context.namespaces)).text = \
-            metadata_main.get('contact_country', 'missing')
-
-            etree.SubElement(address,
-            util.nspath_eval('ows:ElectronicMailAddress',
-            self.context.namespaces)).text = \
-            metadata_main.get('contact_email', 'missing')
-
-            url = etree.SubElement(contactinfo,
-            util.nspath_eval('ows:OnlineResource', self.context.namespaces))
-
-            url.attrib[util.nspath_eval('xlink:type',
-            self.context.namespaces)] = 'simple'
-
-            url.attrib[util.nspath_eval('xlink:href',
-            self.context.namespaces)] = \
-            metadata_main.get('contact_url', 'missing')
-
-            etree.SubElement(contactinfo,
-            util.nspath_eval('ows:HoursOfService',
-            self.context.namespaces)).text = \
-            metadata_main.get('contact_hours', 'missing')
-
-            etree.SubElement(contactinfo,
-            util.nspath_eval('ows:ContactInstructions',
-            self.context.namespaces)).text = \
-            metadata_main.get('contact_instructions', 'missing')
-
-            etree.SubElement(servicecontact,
-            util.nspath_eval('ows:Role', self.context.namespaces),
-            codeSpace='ISOTC211/19115').text = \
-            metadata_main.get('contact_role', 'missing')
-
-        if operationsmetadata:
-            LOGGER.debug('Writing section OperationsMetadata.')
-            operationsmetadata = etree.SubElement(node,
-            util.nspath_eval('ows:OperationsMetadata',
-            self.context.namespaces))
-
-            for operation in self.context.model['operations'].keys():
-                oper = etree.SubElement(operationsmetadata,
-                util.nspath_eval('ows:Operation', self.context.namespaces),
-                name=operation)
-
-                dcp = etree.SubElement(oper, util.nspath_eval('ows:DCP',
-                self.context.namespaces))
-
-                http = etree.SubElement(dcp, util.nspath_eval('ows:HTTP',
-                self.context.namespaces))
-
-                if self.context.model['operations'][operation]['methods']['get']:
-                    get = etree.SubElement(http, util.nspath_eval('ows:Get',
-                    self.context.namespaces))
-
-                    get.attrib[util.nspath_eval('xlink:type',\
-                    self.context.namespaces)] = 'simple'
-
-                    get.attrib[util.nspath_eval('xlink:href',\
-                    self.context.namespaces)] = self.config.get('server', 'url')
-
-                if self.context.model['operations'][operation]['methods']['post']:
-                    post = etree.SubElement(http, util.nspath_eval('ows:Post',
-                    self.context.namespaces))
-                    post.attrib[util.nspath_eval('xlink:type',
-                    self.context.namespaces)] = 'simple'
-                    post.attrib[util.nspath_eval('xlink:href',
-                    self.context.namespaces)] = \
-                    self.config.get('server', 'url')
-
-                for parameter in \
-                self.context.model['operations'][operation]['parameters']:
-                    param = etree.SubElement(oper,
-                    util.nspath_eval('ows:Parameter',
-                    self.context.namespaces), name=parameter)
-
-                    for val in \
-                    self.context.model['operations'][operation]\
-                    ['parameters'][parameter]['values']:
-                        etree.SubElement(param,
-                        util.nspath_eval('ows:Value',
-                        self.context.namespaces)).text = val
-
-                if operation == 'GetRecords':  # advertise queryables
-                    for qbl in self.repository.queryables.keys():
-                        if qbl != '_all':
-                            param = etree.SubElement(oper,
-                            util.nspath_eval('ows:Constraint',
-                            self.context.namespaces), name=qbl)
-
-                            for qbl2 in self.repository.queryables[qbl]:
-                                etree.SubElement(param,
-                                util.nspath_eval('ows:Value',
-                                self.context.namespaces)).text = qbl2
-
-                    if self.profiles is not None:
-                        for con in self.context.model[\
-                        'operations']['GetRecords']['constraints'].keys():
-                            param = etree.SubElement(oper,
-                            util.nspath_eval('ows:Constraint',
-                            self.context.namespaces), name = con)
-                            for val in self.context.model['operations']\
-                            ['GetRecords']['constraints'][con]['values']:
-                                etree.SubElement(param,
-                                util.nspath_eval('ows:Value',
-                                self.context.namespaces)).text = val
-
-            for parameter in self.context.model['parameters'].keys():
-                param = etree.SubElement(operationsmetadata,
-                util.nspath_eval('ows:Parameter', self.context.namespaces),
-                name=parameter)
-
-                for val in self.context.model['parameters'][parameter]['values']:
-                    etree.SubElement(param, util.nspath_eval('ows:Value',
-                    self.context.namespaces)).text = val
-
-            for constraint in self.context.model['constraints'].keys():
-                param = etree.SubElement(operationsmetadata,
-                util.nspath_eval('ows:Constraint', self.context.namespaces),
-                name=constraint)
-
-                for val in self.context.model['constraints'][constraint]['values']:
-                    etree.SubElement(param, util.nspath_eval('ows:Value',
-                    self.context.namespaces)).text = val
-
-            if self.profiles is not None:
-                for prof in self.profiles['loaded'].keys():
-                    ecnode = \
-                    self.profiles['loaded'][prof].get_extendedcapabilities()
-                    if ecnode is not None:
-                        operationsmetadata.append(ecnode)
-
-        # always write out Filter_Capabilities
-        LOGGER.debug('Writing section Filter_Capabilities.')
-        fltcaps = etree.SubElement(node,
-        util.nspath_eval('ogc:Filter_Capabilities', self.context.namespaces))
-
-        spatialcaps = etree.SubElement(fltcaps,
-        util.nspath_eval('ogc:Spatial_Capabilities', self.context.namespaces))
-
-        geomops = etree.SubElement(spatialcaps,
-        util.nspath_eval('ogc:GeometryOperands', self.context.namespaces))
-
-        for geomtype in \
-        fes.MODEL['GeometryOperands']['values']:
-            etree.SubElement(geomops,
-            util.nspath_eval('ogc:GeometryOperand',
-            self.context.namespaces)).text = geomtype
-
-        spatialops = etree.SubElement(spatialcaps,
-        util.nspath_eval('ogc:SpatialOperators', self.context.namespaces))
-
-        for spatial_comparison in \
-        fes.MODEL['SpatialOperators']['values']:
-            etree.SubElement(spatialops,
-            util.nspath_eval('ogc:SpatialOperator', self.context.namespaces),
-            name=spatial_comparison)
-
-        scalarcaps = etree.SubElement(fltcaps,
-        util.nspath_eval('ogc:Scalar_Capabilities', self.context.namespaces))
-
-        etree.SubElement(scalarcaps, util.nspath_eval('ogc:LogicalOperators',
-        self.context.namespaces))
-
-        cmpops = etree.SubElement(scalarcaps,
-        util.nspath_eval('ogc:ComparisonOperators', self.context.namespaces))
-
-        for cmpop in fes.MODEL['ComparisonOperators'].keys():
-            etree.SubElement(cmpops,
-            util.nspath_eval('ogc:ComparisonOperator',
-            self.context.namespaces)).text = \
-            fes.MODEL['ComparisonOperators'][cmpop]['opname']
-
-        arithops = etree.SubElement(scalarcaps,
-        util.nspath_eval('ogc:ArithmeticOperators', self.context.namespaces))
-
-        functions = etree.SubElement(arithops,
-        util.nspath_eval('ogc:Functions', self.context.namespaces))
-
-        functionames = etree.SubElement(functions,
-        util.nspath_eval('ogc:FunctionNames', self.context.namespaces))
-
-        for fnop in sorted(fes.MODEL['Functions'].keys()):
-            etree.SubElement(functionames,
-            util.nspath_eval('ogc:FunctionName', self.context.namespaces),
-            nArgs=fes.MODEL['Functions'][fnop]['args']).text = fnop
-
-        idcaps = etree.SubElement(fltcaps,
-        util.nspath_eval('ogc:Id_Capabilities', self.context.namespaces))
-
-        for idcap in fes.MODEL['Ids']['values']:
-            etree.SubElement(idcaps, util.nspath_eval('ogc:%s' % idcap,
-            self.context.namespaces))
-
-        return node
+        """ Handle GetCapabilities request """
+        return self.iface.getcapabilities()
 
     def describerecord(self):
-        ''' Handle DescribeRecord request '''
-
-        if 'typename' not in self.kvp or \
-        len(self.kvp['typename']) == 0:  # missing typename
-        # set to return all typenames
-            self.kvp['typename'] = ['csw:Record']
-
-            if self.profiles is not None:
-                for prof in self.profiles['loaded'].keys():
-                    self.kvp['typename'].append(
-                    self.profiles['loaded'][prof].typename)
-
-        elif self.requesttype == 'GET':  # pass via GET
-            self.kvp['typename'] = self.kvp['typename'].split(',')
-
-        if ('outputformat' in self.kvp and
-            self.kvp['outputformat'] not in
-            self.context.model['operations']['DescribeRecord']
-            ['parameters']['outputFormat']['values']):  # bad outputformat
-            return self.exceptionreport('InvalidParameterValue',
-            'outputformat', 'Invalid value for outputformat: %s' %
-            self.kvp['outputformat'])
-
-        if ('schemalanguage' in self.kvp and
-            self.kvp['schemalanguage'] not in
-            self.context.model['operations']['DescribeRecord']['parameters']
-            ['schemaLanguage']['values']):  # bad schemalanguage
-            return self.exceptionreport('InvalidParameterValue',
-            'schemalanguage', 'Invalid value for schemalanguage: %s' %
-            self.kvp['schemalanguage'])
-
-        node = etree.Element(util.nspath_eval('csw:DescribeRecordResponse',
-        self.context.namespaces), nsmap=self.context.namespaces)
-
-        node.attrib[util.nspath_eval('xsi:schemaLocation',
-        self.context.namespaces)] = \
-        '%s %s/csw/2.0.2/CSW-discovery.xsd' % (self.context.namespaces['csw'],
-        self.config.get('server', 'ogc_schemas_base'))
-
-        for typename in self.kvp['typename']:
-            if typename.find(':') == -1:  # unqualified typename
-                return self.exceptionreport('InvalidParameterValue',
-                'typename', 'Typename not qualified: %s' % typename)
-            if typename == 'csw:Record':   # load core schema
-                LOGGER.debug('Writing csw:Record schema.')
-                schemacomponent = etree.SubElement(node,
-                util.nspath_eval('csw:SchemaComponent', self.context.namespaces),
-                schemaLanguage='XMLSCHEMA',
-                targetNamespace=self.context.namespaces['csw'])
-
-                path = os.path.join(self.config.get('server', 'home'),
-                'schemas', 'ogc', 'csw', '2.0.2', 'record.xsd')
-
-                dublincore = etree.parse(path, self.context.parser).getroot()
-
-                schemacomponent.append(dublincore)
-
-            if self.profiles is not None:
-                for prof in self.profiles['loaded'].keys():
-                    if self.profiles['loaded'][prof].typename == typename:
-                        scnodes = \
-                        self.profiles['loaded'][prof].get_schemacomponents()
-                        if scnodes is not None:
-                            map(node.append, scnodes)
-        return node
+        """ Handle DescribeRecord request """
+        return self.iface.describerecord()
 
     def getdomain(self):
-        ''' Handle GetDomain request '''
-        if ('parametername' not in self.kvp and
-            'propertyname' not in self.kvp):
-            return self.exceptionreport('MissingParameterValue',
-            'parametername', 'Missing value. \
-            One of propertyname or parametername must be specified')
-
-        node = etree.Element(util.nspath_eval('csw:GetDomainResponse',
-        self.context.namespaces), nsmap=self.context.namespaces)
-
-        node.attrib[util.nspath_eval('xsi:schemaLocation',
-        self.context.namespaces)] = '%s %s/csw/2.0.2/CSW-discovery.xsd' % \
-        (self.context.namespaces['csw'],
-        self.config.get('server', 'ogc_schemas_base'))
-
-        if 'parametername' in self.kvp:
-            for pname in self.kvp['parametername'].split(','):
-                LOGGER.debug('Parsing parametername %s.' % pname)
-                domainvalue = etree.SubElement(node,
-                util.nspath_eval('csw:DomainValues', self.context.namespaces),
-                type='csw:Record')
-                etree.SubElement(domainvalue,
-                util.nspath_eval('csw:ParameterName',
-                self.context.namespaces)).text = pname
-                try:
-                    operation, parameter = pname.split('.')
-                except:
-                    return node
-                if (operation in self.context.model['operations'].keys() and
-                    parameter in
-                    self.context.model['operations'][operation]['parameters'].keys()):
-                    listofvalues = etree.SubElement(domainvalue,
-                    util.nspath_eval('csw:ListOfValues', self.context.namespaces))
-                    for val in \
-                    self.context.model['operations'][operation]\
-                    ['parameters'][parameter]['values']:
-                        etree.SubElement(listofvalues,
-                        util.nspath_eval('csw:Value',
-                        self.context.namespaces)).text = val
-
-        if 'propertyname' in self.kvp:
-            for pname in self.kvp['propertyname'].split(','):
-                LOGGER.debug('Parsing propertyname %s.' % pname)
-
-                if pname.find('/') == 0:  # it's an XPath
-                    pname2 = pname
-                else:  # it's a core queryable, map to internal typename model
-                    try:
-                        pname2 = self.repository.queryables['_all'][pname]['dbcol']
-                    except:
-                        pname2 = pname
-
-                # decipher typename
-                dvtype = None
-                if self.profiles is not None:
-                    for prof in self.profiles['loaded'].keys():
-                        for prefix in self.profiles['loaded'][prof].prefixes:
-                            if pname2.find(prefix) != -1:
-                                dvtype = self.profiles['loaded'][prof].typename
-                                break
-                if not dvtype:
-                    dvtype = 'csw:Record'
-
-                domainvalue = etree.SubElement(node,
-                util.nspath_eval('csw:DomainValues', self.context.namespaces),
-                type=dvtype)
-                etree.SubElement(domainvalue,
-                util.nspath_eval('csw:PropertyName',
-                self.context.namespaces)).text = pname
-
-                try:
-                    LOGGER.debug(
-                    'Querying repository property %s, typename %s, \
-                    domainquerytype %s.' % \
-                    (pname2, dvtype, self.domainquerytype))
-
-                    count = False
-
-                    if (self.config.has_option('server', 'domaincounts') and
-                        self.config.get('server', 'domaincounts') == 'true'):
-                        count = True
-
-                    results = self.repository.query_domain(
-                    pname2, dvtype, self.domainquerytype, count)
-
-                    LOGGER.debug('Results: %s' % str(len(results)))
-
-                    if self.domainquerytype == 'range':
-                        rangeofvalues = etree.SubElement(domainvalue,
-                        util.nspath_eval('csw:RangeOfValues',
-                        self.context.namespaces))
-
-                        etree.SubElement(rangeofvalues,
-                        util.nspath_eval('csw:MinValue',
-                        self.context.namespaces)).text = results[0][0]
-
-                        etree.SubElement(rangeofvalues,
-                        util.nspath_eval('csw:MaxValue',
-                        self.context.namespaces)).text = results[0][1]
-                    else:
-                        listofvalues = etree.SubElement(domainvalue,
-                        util.nspath_eval('csw:ListOfValues',
-                        self.context.namespaces))
-                        for result in results:
-                            LOGGER.debug(str(result))
-                            if (result is not None and
-                                result[0] is not None):  # drop null values
-                                if count:  # show counts
-                                    val = '%s (%s)' % (result[0], result[1])
-                                else:
-                                    val = result[0]
-                                etree.SubElement(listofvalues,
-                                util.nspath_eval('csw:Value',
-                                self.context.namespaces)).text = val
-                except Exception as err:
-                    LOGGER.debug('No results for propertyname %s: %s.' %
-                    (pname2, str(err)))
-        return node
+        """ Handle GetDomain request """
+        return self.iface.getdomain()
 
     def getrecords(self):
-        ''' Handle GetRecords request '''
-
-        timestamp = util.get_today_and_now()
-
-        if ('elementsetname' not in self.kvp and
-            'elementname' not in self.kvp):
-            # mutually exclusive required
-            return self.exceptionreport('MissingParameterValue',
-            'elementsetname',
-            'Missing one of ElementSetName or ElementName parameter(s)')
-
-        if 'outputschema' not in self.kvp:
-            self.kvp['outputschema'] = self.context.namespaces['csw']
-
-        if (self.kvp['outputschema'] not in self.context.model['operations']
-            ['GetRecords']['parameters']['outputSchema']['values']):
-            return self.exceptionreport('InvalidParameterValue',
-            'outputschema', 'Invalid outputSchema parameter value: %s' %
-            self.kvp['outputschema'])
-
-        if 'outputformat' not in self.kvp:
-            self.kvp['outputformat'] = 'application/xml'
-
-        if (self.kvp['outputformat'] not in self.context.model['operations']
-            ['GetRecords']['parameters']['outputFormat']['values']):
-            return self.exceptionreport('InvalidParameterValue',
-            'outputformat', 'Invalid outputFormat parameter value: %s' %
-            self.kvp['outputformat'])
-
-        if 'resulttype' not in self.kvp:
-            self.kvp['resulttype'] = 'hits'
-
-        if self.kvp['resulttype'] is not None:
-            if (self.kvp['resulttype'] not in self.context.model['operations']
-            ['GetRecords']['parameters']['resultType']['values']):
-                return self.exceptionreport('InvalidParameterValue',
-                'resulttype', 'Invalid resultType parameter value: %s' %
-                self.kvp['resulttype'])
-
-        if (('elementname' not in self.kvp or
-             len(self.kvp['elementname']) == 0) and
-             self.kvp['elementsetname'] not in
-             self.context.model['operations']['GetRecords']['parameters']
-             ['ElementSetName']['values']):
-            return self.exceptionreport('InvalidParameterValue',
-            'elementsetname', 'Invalid ElementSetName parameter value: %s' %
-            self.kvp['elementsetname'])
-
-        if ('elementname' in self.kvp and
-            self.requesttype == 'GET'):  # passed via GET
-            self.kvp['elementname'] = self.kvp['elementname'].split(',')
-            self.kvp['elementsetname'] = 'summary'
-
-        if 'typenames' not in self.kvp:
-            return self.exceptionreport('MissingParameterValue',
-            'typenames', 'Missing typenames parameter')
-
-        if ('typenames' in self.kvp and
-            self.requesttype == 'GET'):  # passed via GET
-            self.kvp['typenames'] = self.kvp['typenames'].split(',')
-
-        if 'typenames' in self.kvp:
-            for tname in self.kvp['typenames']:
-                if (tname not in self.context.model['operations']['GetRecords']
-                    ['parameters']['typeNames']['values']):
-                    return self.exceptionreport('InvalidParameterValue',
-                    'typenames', 'Invalid typeNames parameter value: %s' %
-                    tname)
-
-        # check elementname's
-        if 'elementname' in self.kvp:
-            for ename in self.kvp['elementname']:
-                enamelist = self.repository.queryables['_all'].keys()
-                if ename not in enamelist:
-                    return self.exceptionreport('InvalidParameterValue',
-                    'elementname', 'Invalid ElementName parameter value: %s' %
-                    ename)
-
-        if self.kvp['resulttype'] == 'validate':
-            return self._write_acknowledgement()
-
-        maxrecords_cfg = -1  # not set in config server.maxrecords
-
-        if self.config.has_option('server', 'maxrecords'):
-            maxrecords_cfg = int(self.config.get('server', 'maxrecords'))
-
-        if 'maxrecords' not in self.kvp:  # not specified by client
-            if maxrecords_cfg > -1:  # specified in config
-                self.kvp['maxrecords'] = maxrecords_cfg
-            else:  # spec default
-                self.kvp['maxrecords'] = 10
-        else:  # specified by client
-            if maxrecords_cfg > -1:  # set in config
-                if int(self.kvp['maxrecords']) > maxrecords_cfg:
-                    self.kvp['maxrecords'] = maxrecords_cfg
-
-        if any(x in ['bbox', 'q', 'time'] for x in self.kvp):
-            LOGGER.debug('OpenSearch Geo/Time parameters detected.')
-            self.kvp['constraintlanguage'] = 'FILTER'
-            tmp_filter = opensearch.kvp2filterxml(self.kvp, self.context)
-            if tmp_filter is not "":
-                self.kvp['constraint'] = tmp_filter
-                LOGGER.debug('OpenSearch Geo/Time parameters to Filter: %s.' % self.kvp['constraint'])
-
-        if self.requesttype == 'GET':
-            if 'constraint' in self.kvp:
-                # GET request
-                LOGGER.debug('csw:Constraint passed over HTTP GET.')
-                if 'constraintlanguage' not in self.kvp:
-                    return self.exceptionreport('MissingParameterValue',
-                    'constraintlanguage',
-                    'constraintlanguage required when constraint specified')
-                if (self.kvp['constraintlanguage'] not in
-                self.context.model['operations']['GetRecords']['parameters']
-                ['CONSTRAINTLANGUAGE']['values']):
-                    return self.exceptionreport('InvalidParameterValue',
-                    'constraintlanguage', 'Invalid constraintlanguage: %s'
-                    % self.kvp['constraintlanguage'])
-                if self.kvp['constraintlanguage'] == 'CQL_TEXT':
-                    tmp = self.kvp['constraint']
-                    self.kvp['constraint'] = {}
-                    self.kvp['constraint']['type'] = 'cql'
-                    self.kvp['constraint']['where'] = \
-                    self._cql_update_queryables_mappings(tmp,
-                    self.repository.queryables['_all'])
-                    self.kvp['constraint']['values'] = {}
-                elif self.kvp['constraintlanguage'] == 'FILTER':
-                    # validate filter XML
-                    try:
-                        schema = os.path.join(self.config.get('server', 'home'),
-                        'schemas', 'ogc', 'filter', '1.1.0', 'filter.xsd')
-                        LOGGER.debug('Validating Filter %s.' %
-                        self.kvp['constraint'])
-                        schema = etree.XMLSchema(file=schema)
-                        parser = etree.XMLParser(schema=schema, resolve_entities=False)
-                        doc = etree.fromstring(self.kvp['constraint'], parser)
-                        LOGGER.debug('Filter is valid XML.')
-                        self.kvp['constraint'] = {}
-                        self.kvp['constraint']['type'] = 'filter'
-                        self.kvp['constraint']['where'], self.kvp['constraint']['values'] = \
-                        fes.parse(doc,
-                        self.repository.queryables['_all'],
-                        self.repository.dbtype,
-                        self.context.namespaces, self.orm, self.language['text'], self.repository.fts)
-                    except Exception as err:
-                        errortext = \
-                        'Exception: document not valid.\nError: %s.' % str(err)
-
-                        LOGGER.debug(errortext)
-                        return self.exceptionreport('InvalidParameterValue',
-                        'constraint', 'Invalid Filter query: %s' % errortext)
-            else:
-                self.kvp['constraint'] = {}
-
-        if 'sortby' not in self.kvp:
-            self.kvp['sortby'] = None
-        elif 'sortby' in self.kvp and self.requesttype == 'GET':
-            LOGGER.debug('Sorted query specified.')
-            tmp = self.kvp['sortby']
-            self.kvp['sortby'] = {}
-
-            try:
-                name, order = tmp.rsplit(':', 1)
-            except:
-                return self.exceptionreport('InvalidParameterValue',
-                'sortby', 'Invalid SortBy value: must be in the format\
-                propertyname:A or propertyname:D')
-
-            try:
-                self.kvp['sortby']['propertyname'] = \
-                self.repository.queryables['_all'][name]['dbcol']
-                if name.find('BoundingBox') != -1 or name.find('Envelope') != -1:
-                    # it's a spatial sort
-                    self.kvp['sortby']['spatial'] = True
-            except Exception as err:
-                return self.exceptionreport('InvalidParameterValue',
-                'sortby', 'Invalid SortBy propertyname: %s' % name)
-
-            if order not in ['A', 'D']:
-                return self.exceptionreport('InvalidParameterValue',
-                'sortby', 'Invalid SortBy value: sort order must be "A" or "D"')
-
-            if order == 'D':
-                self.kvp['sortby']['order'] = 'DESC'
-            else:
-                self.kvp['sortby']['order'] = 'ASC'
-
-        if 'startposition' not in self.kvp:
-            self.kvp['startposition'] = 1
-
-        # query repository
-        LOGGER.debug('Querying repository with constraint: %s,\
-        sortby: %s, typenames: %s, maxrecords: %s, startposition: %s.' %
-        (self.kvp['constraint'], self.kvp['sortby'], self.kvp['typenames'],
-        self.kvp['maxrecords'], self.kvp['startposition']))
-
-        try:
-            matched, results = self.repository.query(
-            constraint=self.kvp['constraint'],
-            sortby=self.kvp['sortby'], typenames=self.kvp['typenames'],
-            maxrecords=self.kvp['maxrecords'],
-            startposition=int(self.kvp['startposition'])-1)
-        except Exception as err:
-            return self.exceptionreport('InvalidParameterValue', 'constraint',
-            'Invalid query: %s' % err)
-
-        dsresults = []
-
-        if (self.config.has_option('server', 'federatedcatalogues') and
-            'distributedsearch' in self.kvp and
-            self.kvp['distributedsearch'] and self.kvp['hopcount'] > 0):
-            # do distributed search
-
-            LOGGER.debug('DistributedSearch specified (hopCount: %s).' %
-            self.kvp['hopcount'])
-
-            from owslib.csw import CatalogueServiceWeb
-            from owslib.ows import ExceptionReport
-            for fedcat in \
-            self.config.get('server', 'federatedcatalogues').split(','):
-                LOGGER.debug('Performing distributed search on federated \
-                catalogue: %s.' % fedcat)
-                remotecsw = CatalogueServiceWeb(fedcat, skip_caps=True)
-                try:
-                    remotecsw.getrecords2(xml=self.request,
-                                          esn=self.kvp['elementsetname'],
-                                          outputschema=self.kvp['outputschema'])
-                    if hasattr(remotecsw, 'results'):
-                        LOGGER.debug(
-                        'Distributed search results from catalogue \
-                        %s: %s.' % (fedcat, remotecsw.results))
-
-                        remotecsw_matches = int(remotecsw.results['matches'])
-                        plural = 's' if remotecsw_matches != 1 else ''
-                        if remotecsw_matches > 0:
-                            matched = str(int(matched) + remotecsw_matches)
-                            dsresults.append(etree.Comment(
-                            ' %d result%s from %s ' %
-                            (remotecsw_matches, plural, fedcat)))
-
-                            dsresults.append(remotecsw.records)
-                except ExceptionReport as err:
-                    error_string = 'remote CSW %s returned exception: ' % fedcat
-                    dsresults.append(etree.Comment(
-                    ' %s\n\n%s ' % (error_string, err)))
-                    LOGGER.debug(str(err))
-                except Exception as err:
-                    error_string = 'remote CSW %s returned error: ' % fedcat
-                    dsresults.append(etree.Comment(
-                    ' %s\n\n%s ' % (error_string, err)))
-                    LOGGER.debug(str(err))
-
-        if int(matched) == 0:
-            returned = nextrecord = '0'
-        else:
-            if int(matched) < int(self.kvp['maxrecords']):
-                returned = matched
-                nextrecord = '0'
-            else:
-                returned = str(self.kvp['maxrecords'])
-                if int(self.kvp['startposition']) + int(self.kvp['maxrecords']) >= int(matched):
-                    nextrecord = '0'
-                else:
-                    nextrecord = str(int(self.kvp['startposition']) + \
-                    int(self.kvp['maxrecords']))
-
-        LOGGER.debug('Results: matched: %s, returned: %s, next: %s.' % \
-        (matched, returned, nextrecord))
-
-        node = etree.Element(util.nspath_eval('csw:GetRecordsResponse',
-        self.context.namespaces),
-        nsmap=self.context.namespaces, version='2.0.2')
-
-        node.attrib[util.nspath_eval('xsi:schemaLocation',
-        self.context.namespaces)] = \
-        '%s %s/csw/2.0.2/CSW-discovery.xsd' % \
-        (self.context.namespaces['csw'], self.config.get('server', 'ogc_schemas_base'))
-
-        if 'requestid' in self.kvp and self.kvp['requestid'] is not None:
-            etree.SubElement(node, util.nspath_eval('csw:RequestId',
-            self.context.namespaces)).text = self.kvp['requestid']
-
-        etree.SubElement(node, util.nspath_eval('csw:SearchStatus',
-        self.context.namespaces), timestamp=timestamp)
-
-        if 'where' not in self.kvp['constraint'] and \
-        self.kvp['resulttype'] is None:
-            returned = '0'
-
-        searchresults = etree.SubElement(node,
-        util.nspath_eval('csw:SearchResults', self.context.namespaces),
-        numberOfRecordsMatched=matched, numberOfRecordsReturned=returned,
-        nextRecord=nextrecord, recordSchema=self.kvp['outputschema'])
-
-        if self.kvp['elementsetname'] is not None:
-            searchresults.attrib['elementSet'] = self.kvp['elementsetname']
-
-        if 'where' not in self.kvp['constraint'] \
-        and self.kvp['resulttype'] is None:
-            LOGGER.debug('Empty result set returned.')
-            return node
-
-        if self.kvp['resulttype'] == 'hits':
-            return node
-
-
-        if results is not None:
-            if len(results) < self.kvp['maxrecords']:
-                max1 = len(results)
-            else:
-                max1 = int(self.kvp['startposition']) + (int(self.kvp['maxrecords'])-1)
-            LOGGER.debug('Presenting records %s - %s.' %
-            (self.kvp['startposition'], max1))
-
-            for res in results:
-                try:
-                    if (self.kvp['outputschema'] ==
-                        'http://www.opengis.net/cat/csw/2.0.2' and
-                        'csw:Record' in self.kvp['typenames']):
-                        # serialize csw:Record inline
-                        searchresults.append(self._write_record(
-                        res, self.repository.queryables['_all']))
-                    elif (self.kvp['outputschema'] ==
-                        'http://www.opengis.net/cat/csw/2.0.2' and
-                        'csw:Record' not in self.kvp['typenames']):
-                        # serialize into csw:Record model
-
-                        for prof in self.profiles['loaded']:
-                            # find source typename
-                            if self.profiles['loaded'][prof].typename in \
-                            self.kvp['typenames']:
-                                typename = self.profiles['loaded'][prof].typename
-                                break
-
-                        util.transform_mappings(self.repository.queryables['_all'],
-                        self.context.model['typenames'][typename]\
-                        ['mappings']['csw:Record'], reverse=True)
-
-                        searchresults.append(self._write_record(
-                        res, self.repository.queryables['_all']))
-                    elif self.kvp['outputschema'] in self.outputschemas.keys():  # use outputschema serializer
-                        searchresults.append(self.outputschemas[self.kvp['outputschema']].write_record(res, self.kvp['elementsetname'], self.context, self.config.get('server', 'url')))
-                    else:  # use profile serializer
-                        searchresults.append(
-                        self.profiles['loaded'][self.kvp['outputschema']].\
-                        write_record(res, self.kvp['elementsetname'],
-                        self.kvp['outputschema'],
-                        self.repository.queryables['_all']))
-                except Exception as err:
-                    self.response = self.exceptionreport(
-                    'NoApplicableCode', 'service',
-                    'Record serialization failed: %s' % str(err))
-                    return self.response
-
-        if len(dsresults) > 0:  # return DistributedSearch results
-            for resultset in dsresults:
-                if isinstance(resultset, etree._Comment):
-                    searchresults.append(resultset)
-                for rec in resultset:
-                    searchresults.append(etree.fromstring(resultset[rec].xml, self.context.parser))
-
-        if 'responsehandler' in self.kvp:  # process the handler
-            self._process_responsehandler(etree.tostring(node,
-            pretty_print=self.pretty_print))
-        else:
-            return node
+        """ Handle GetRecords request """
+        return self.iface.getrecords()
 
     def getrecordbyid(self, raw=False):
-        ''' Handle GetRecordById request '''
-
-        if 'id' not in self.kvp:
-            return self.exceptionreport('MissingParameterValue', 'id',
-            'Missing id parameter')
-        if len(self.kvp['id']) < 1:
-            return self.exceptionreport('InvalidParameterValue', 'id',
-            'Invalid id parameter')
-        if 'outputschema' not in self.kvp:
-            self.kvp['outputschema'] = self.context.namespaces['csw']
-
-        if self.requesttype == 'GET':
-            self.kvp['id'] = self.kvp['id'].split(',')
-
-        if ('outputformat' in self.kvp and
-            self.kvp['outputformat'] not in
-            self.context.model['operations']['GetRecordById']['parameters']
-            ['outputFormat']['values']):
-            return self.exceptionreport('InvalidParameterValue',
-            'outputformat', 'Invalid outputformat parameter %s' %
-            self.kvp['outputformat'])
-
-        if ('outputschema' in self.kvp and self.kvp['outputschema'] not in
-            self.context.model['operations']['GetRecordById']['parameters']
-            ['outputSchema']['values']):
-            return self.exceptionreport('InvalidParameterValue',
-            'outputschema', 'Invalid outputschema parameter %s' %
-            self.kvp['outputschema'])
-
-        if 'elementsetname' not in self.kvp:
-            self.kvp['elementsetname'] = 'summary'
-        else:
-            if (self.kvp['elementsetname'] not in
-                self.context.model['operations']['GetRecordById']['parameters']
-                ['ElementSetName']['values']):
-                return self.exceptionreport('InvalidParameterValue',
-                'elementsetname', 'Invalid elementsetname parameter %s' %
-                self.kvp['elementsetname'])
-
-        node = etree.Element(util.nspath_eval('csw:GetRecordByIdResponse',
-        self.context.namespaces), nsmap=self.context.namespaces)
-
-        node.attrib[util.nspath_eval('xsi:schemaLocation',
-        self.context.namespaces)] = '%s %s/csw/2.0.2/CSW-discovery.xsd' % \
-        (self.context.namespaces['csw'], self.config.get('server', 'ogc_schemas_base'))
-
-        # query repository
-        LOGGER.debug('Querying repository with ids: %s.' % self.kvp['id'][0])
-        results = self.repository.query_ids(self.kvp['id'])
-
-        if raw:  # GetRepositoryItem request
-            LOGGER.debug('GetRepositoryItem request.')
-            if len(results) > 0:
-                return etree.fromstring(util.getqattr(results[0],
-                self.context.md_core_model['mappings']['pycsw:XML']), self.context.parser)
-
-        for result in results:
-            if (util.getqattr(result,
-            self.context.md_core_model['mappings']['pycsw:Typename']) == 'csw:Record'
-            and self.kvp['outputschema'] ==
-            'http://www.opengis.net/cat/csw/2.0.2'):
-                # serialize record inline
-                node.append(self._write_record(
-                result, self.repository.queryables['_all']))
-            elif (self.kvp['outputschema'] ==
-                'http://www.opengis.net/cat/csw/2.0.2'):
-                # serialize into csw:Record model
-                typename = None
-
-                for prof in self.profiles['loaded']:  # find source typename
-                    if self.profiles['loaded'][prof].typename in \
-                    [util.getqattr(result, self.context.md_core_model['mappings']['pycsw:Typename'])]:
-                        typename = self.profiles['loaded'][prof].typename
-                        break
-
-                if typename is not None:
-                    util.transform_mappings(self.repository.queryables['_all'],
-                    self.context.model['typenames'][typename]\
-                    ['mappings']['csw:Record'], reverse=True)
-
-                node.append(self._write_record(
-                result, self.repository.queryables['_all']))
-            elif self.kvp['outputschema'] in self.outputschemas.keys():  # use outputschema serializer
-                node.append(self.outputschemas[self.kvp['outputschema']].write_record(result, self.kvp['elementsetname'], self.context, self.config.get('server', 'url')))
-            else:  # it's a profile output
-                node.append(
-                self.profiles['loaded'][self.kvp['outputschema']].write_record(
-                result, self.kvp['elementsetname'],
-                self.kvp['outputschema'], self.repository.queryables['_all']))
-
-        if raw and len(results) == 0:
-            return None
-
-        return node
+        """ Handle GetRecordById request """
+        return self.iface.getrecordbyid(raw)
 
     def getrepositoryitem(self):
-        ''' Handle GetRepositoryItem request '''
-
-        # similar to GetRecordById without csw:* wrapping
-        node = self.getrecordbyid(raw=True)
-        if node is None:
-            return self.exceptionreport('NotFound', 'id',
-            'No repository item found for \'%s\'' % self.kvp['id'])
-        else:
-            return node
+        """ Handle GetRepositoryItem request """
+        return self.iface.getrepositoryitem()
 
     def transaction(self):
-        ''' Handle Transaction request '''
-
-        try:
-            self._test_manager()
-        except Exception as err:
-            return self.exceptionreport('NoApplicableCode', 'transaction',
-            str(err))
-
-        inserted = 0
-        updated = 0
-        deleted = 0
-
-        insertresults = []
-
-        LOGGER.debug('Transaction list: %s' % self.kvp['transactions'])
-
-        for ttype in self.kvp['transactions']:
-            if ttype['type'] == 'insert':
-                try:
-                    record = metadata.parse_record(self.context,
-                    ttype['xml'], self.repository)[0]
-                except Exception as err:
-                    return self.exceptionreport('NoApplicableCode', 'insert',
-                    'Transaction (insert) failed: record parsing failed: %s' \
-                    % str(err))
-
-                LOGGER.debug('Transaction operation: %s' % record)
-
-                if not hasattr(record,
-                self.context.md_core_model['mappings']['pycsw:Identifier']):
-                    return self.exceptionreport('NoApplicableCode',
-                    'insert', 'Record requires an identifier')
-
-                # insert new record
-                try:
-                    self.repository.insert(record, 'local',
-                    util.get_today_and_now())
-
-                    inserted += 1
-                    insertresults.append(
-                    {'identifier': getattr(record,
-                    self.context.md_core_model['mappings']['pycsw:Identifier']),
-                    'title': getattr(record,
-                    self.context.md_core_model['mappings']['pycsw:Title'])})
-                except Exception as err:
-                    return self.exceptionreport('NoApplicableCode',
-                    'insert', 'Transaction (insert) failed: %s.' % str(err))
-
-            elif ttype['type'] == 'update':
-                if 'constraint' not in ttype:
-                    # update full existing resource in repository
-                    try:
-                        record = metadata.parse_record(self.context,
-                        ttype['xml'], self.repository)[0]
-                        identifier = getattr(record,
-                        self.context.md_core_model['mappings']['pycsw:Identifier'])
-                    except Exception as err:
-                        return self.exceptionreport('NoApplicableCode', 'insert',
-                        'Transaction (update) failed: record parsing failed: %s' \
-                        % str(err))
-
-                    # query repository to see if record already exists
-                    LOGGER.debug('checking if record exists (%s)' % \
-                    identifier)
-
-                    results = self.repository.query_ids(ids=[identifier])
-
-                    if len(results) == 0:
-                        LOGGER.debug('id %s does not exist in repository' % \
-                        identifier)
-                    else:  # existing record, it's an update
-                        try:
-                            self.repository.update(record)
-                            updated += 1
-                        except Exception as err:
-                            return self.exceptionreport('NoApplicableCode',
-                            'update',
-                            'Transaction (update) failed: %s.' % str(err))
-                else:  # update by record property and constraint
-                    # get / set XPath for property names
-                    for rp in ttype['recordproperty']:
-                        if rp['name'] not in self.repository.queryables['_all']:
-                            # is it an XPath?
-                            if rp['name'].find('/') != -1:
-                                # scan outputschemas; if match, bind
-                                for osch in self.outputschemas.values():
-                                    for key, value in osch.XPATH_MAPPINGS.iteritems():
-                                        if value == rp['name']:  # match
-                                            rp['rp'] = {'xpath': value, 'name': key}
-                                            rp['rp']['dbcol'] = self.repository.queryables['_all'][key]
-                                            break
-                            else:
-                                return self.exceptionreport('NoApplicableCode',
-                                       'update', 'Transaction (update) failed: invalid property2: %s.' % str(rp['name']))
-                        else:
-                            rp['rp']= \
-                            self.repository.queryables['_all'][rp['name']]
-
-                    LOGGER.debug('Record Properties: %s.' %
-                    ttype['recordproperty'])
-                    try:
-                        updated += self.repository.update(record=None,
-                        recprops=ttype['recordproperty'],
-                        constraint=ttype['constraint'])
-                    except Exception as err:
-                        return self.exceptionreport('NoApplicableCode',
-                        'update',
-                        'Transaction (update) failed: %s.' % str(err))
-
-            elif ttype['type'] == 'delete':
-                deleted += self.repository.delete(ttype['constraint'])
-
-        node = etree.Element(util.nspath_eval('csw:TransactionResponse',
-        self.context.namespaces), nsmap=self.context.namespaces, version='2.0.2')
-
-        node.attrib[util.nspath_eval('xsi:schemaLocation',
-        self.context.namespaces)] = '%s %s/csw/2.0.2/CSW-publication.xsd' % \
-        (self.context.namespaces['csw'], self.config.get('server', 'ogc_schemas_base'))
-
-        node.append(
-        self._write_transactionsummary(
-        inserted=inserted, updated=updated, deleted=deleted))
-
-        if (len(insertresults) > 0 and self.kvp['verboseresponse']):
-            # show insert result identifiers
-            node.append(self._write_verboseresponse(insertresults))
-
-        return node
+        """ Handle Transaction request """
+        return self.iface.transaction()
 
     def harvest(self):
-        ''' Handle Harvest request '''
-
-        service_identifier = None
-        old_identifier = None
-        deleted = []
-
-        try:
-            self._test_manager()
-        except Exception as err:
-            return self.exceptionreport('NoApplicableCode', 'harvest', str(err))
-
-        if self.requesttype == 'GET':
-            if 'resourcetype' not in self.kvp:
-                return self.exceptionreport('MissingParameterValue',
-                'resourcetype', 'Missing resourcetype parameter')
-            if 'source' not in self.kvp:
-                return self.exceptionreport('MissingParameterValue',
-                'source', 'Missing source parameter')
-
-        # validate resourcetype
-        if (self.kvp['resourcetype'] not in
-            self.context.model['operations']['Harvest']['parameters']['ResourceType']
-            ['values']):
-            return self.exceptionreport('InvalidParameterValue',
-            'resourcetype', 'Invalid resource type parameter: %s.\
-            Allowable resourcetype values: %s' % (self.kvp['resourcetype'],
-            ','.join(self.context.model['operations']['Harvest']['parameters']
-            ['ResourceType']['values'])))
-
-        if (self.kvp['resourcetype'].find('opengis.net') == -1 and
-            self.kvp['resourcetype'].find('urn:geoss:waf') == -1):
-            # fetch content-based resource
-            LOGGER.debug('Fetching resource %s' % self.kvp['source'])
-            try:
-                content = util.http_request('GET', self.kvp['source'])
-            except Exception as err:
-                errortext = 'Error fetching resource %s.\nError: %s.' % \
-                (self.kvp['source'], str(err))
-                LOGGER.debug(errortext)
-                return self.exceptionreport('InvalidParameterValue', 'source',
-                errortext)
-        else:  # it's a service URL
-            content = self.kvp['source']
-            # query repository to see if service already exists
-            LOGGER.debug('checking if service exists (%s)' % content)
-            results = self.repository.query_source(content)
-
-            if len(results) > 0:  # exists, keep identifier for update
-                LOGGER.debug('Service already exists, keeping identifier and results')
-                service_identifier = results[0].identifier
-                service_results = results
-                LOGGER.debug('Identifier is %s' % service_identifier)
-            #    return self.exceptionreport('NoApplicableCode', 'source',
-            #    'Insert failed: service %s already in repository' % content)
-
-        # parse resource into record
-        try:
-            records_parsed = metadata.parse_record(self.context,
-            content, self.repository, self.kvp['resourcetype'],
-            pagesize=self.csw_harvest_pagesize)
-        except Exception as err:
-            LOGGER.exception(err)
-            return self.exceptionreport('NoApplicableCode', 'source',
-            'Harvest failed: record parsing failed: %s' % str(err))
-
-        inserted = 0
-        updated = 0
-        ir = []
-
-        LOGGER.debug('Total Records parsed: %d' % len(records_parsed))
-        for record in records_parsed:
-            if self.kvp['resourcetype'] == 'urn:geoss:waf':
-                src = record.source
-            else:
-                src = self.kvp['source']
-
-            setattr(record, self.context.md_core_model['mappings']['pycsw:Source'],
-                    src)
-
-            setattr(record, self.context.md_core_model['mappings']['pycsw:InsertDate'],
-            util.get_today_and_now())
-
-            identifier = getattr(record,
-            self.context.md_core_model['mappings']['pycsw:Identifier'])
-            source = getattr(record,
-            self.context.md_core_model['mappings']['pycsw:Source'])
-            insert_date = getattr(record,
-            self.context.md_core_model['mappings']['pycsw:InsertDate'])
-            title = getattr(record,
-            self.context.md_core_model['mappings']['pycsw:Title'])
-
-            if record.type == 'service' and service_identifier is not None:  # service endpoint
-                LOGGER.debug('Replacing service identifier from %s to %s' % (record.identifier, service_identifier))
-                old_identifier = record.identifier
-                identifier = record.identifier = service_identifier
-            if (record.type != 'service' and service_identifier is not None
-                and old_identifier is not None):  # service resource
-                if record.identifier.find(old_identifier) != -1:
-                    new_identifier = record.identifier.replace(old_identifier, service_identifier)
-                    LOGGER.debug('Replacing service resource identifier from %s to %s' % (record.identifier, new_identifier))
-                    identifier = record.identifier = new_identifier
-
-            ir.append({'identifier': identifier, 'title': title})
-
-            # query repository to see if record already exists
-            LOGGER.debug('checking if record exists (%s)' % identifier)
-            results = self.repository.query_ids(ids=[identifier])
-
-            if len(results) == 0:  # check for service identifier
-                LOGGER.debug('checking if service id exists (%s)' % service_identifier)
-                results = self.repository.query_ids(ids=[service_identifier])
-
-            LOGGER.debug(str(results))
-
-            if len(results) == 0:  # new record, it's a new insert
-                inserted += 1
-                try:
-                    self.repository.insert(record, source, insert_date)
-                except Exception as err:
-                    return self.exceptionreport('NoApplicableCode',
-                    'source', 'Harvest (insert) failed: %s.' % str(err))
-            else:  # existing record, it's an update
-                if source != results[0].source:
-                    # same identifier, but different source
-                    return self.exceptionreport('NoApplicableCode',
-                    'source', 'Insert failed: identifier %s in repository\
-                    has source %s.' % (identifier, source))
-
-                try:
-                    self.repository.update(record)
-                except Exception as err:
-                    return self.exceptionreport('NoApplicableCode',
-                    'source', 'Harvest (update) failed: %s.' % str(err))
-                updated += 1
-
-        node = etree.Element(util.nspath_eval('csw:HarvestResponse',
-        self.context.namespaces), nsmap=self.context.namespaces)
-
-        node.attrib[util.nspath_eval('xsi:schemaLocation',
-        self.context.namespaces)] = \
-        '%s %s/csw/2.0.2/CSW-publication.xsd' % (self.context.namespaces['csw'],
-        self.config.get('server', 'ogc_schemas_base'))
-
-        node2 = etree.SubElement(node,
-        util.nspath_eval('csw:TransactionResponse',
-        self.context.namespaces), version='2.0.2')
-
-        if service_identifier is not None:
-            fresh_records = [str(i['identifier']) for i in ir]
-            existing_records = [str(i.identifier) for i in service_results]
-
-            deleted = set(existing_records) - set(fresh_records)
-            LOGGER.debug('Records to delete: %s' % str(deleted))
-
-            for to_delete in deleted:
-                delete_constraint = {
-                    'type': 'filter',
-                    'values': [to_delete],
-                    'where': 'identifier = :pvalue0'
-                }
-                self.repository.delete(delete_constraint)
-
-        node2.append(
-        self._write_transactionsummary(inserted=inserted, updated=updated,
-                                       deleted=len(deleted)))
-
-        if inserted > 0:
-            # show insert result identifiers
-            node2.append(self._write_verboseresponse(ir))
-
-        if 'responsehandler' in self.kvp:  # process the handler
-            self._process_responsehandler(etree.tostring(node,
-            pretty_print=self.pretty_print))
-        else:
-            return node
-
-    def parse_postdata(self, postdata):
-        ''' Parse POST XML '''
-
-        request = {}
-        try:
-            LOGGER.debug('Parsing %s.' % postdata)
-            doc = etree.fromstring(postdata, self.context.parser)
-        except Exception as err:
-            errortext = \
-            'Exception: document not well-formed.\nError: %s.' % str(err)
-
-            LOGGER.debug(errortext)
-            return errortext
-
-        # if this is a SOAP request, get to SOAP-ENV:Body/csw:*
-        if (doc.tag == util.nspath_eval('soapenv:Envelope',
-            self.context.namespaces)):
-
-            LOGGER.debug('SOAP request specified.')
-            self.soap = True
-
-            doc = doc.find(
-            util.nspath_eval('soapenv:Body',
-            self.context.namespaces)).xpath('child::*')[0]
-
-        if (doc.tag in [util.nspath_eval('csw:Transaction',
-            self.context.namespaces), util.nspath_eval('csw:Harvest',
-            self.context.namespaces)]):
-            schema = os.path.join(self.config.get('server', 'home'),
-            'schemas', 'ogc', 'csw', '2.0.2', 'CSW-publication.xsd')
-        else:
-            schema = os.path.join(self.config.get('server', 'home'),
-            'schemas', 'ogc', 'csw', '2.0.2', 'CSW-discovery.xsd')
-
-        try:
-            # it is virtually impossible to validate a csw:Transaction
-            # csw:Insert|csw:Update (with single child) XML document.
-            # Only validate non csw:Transaction XML
-
-            if doc.find('.//%s' % util.nspath_eval('csw:Insert',
-            self.context.namespaces)) is None and \
-            len(doc.xpath('//csw:Update/child::*',
-            namespaces=self.context.namespaces)) == 0:
-
-                LOGGER.debug('Validating %s.' % postdata)
-                schema = etree.XMLSchema(file=schema)
-                parser = etree.XMLParser(schema=schema, resolve_entities=False)
-                if hasattr(self, 'soap') and self.soap:
-                # validate the body of the SOAP request
-                    doc = etree.fromstring(etree.tostring(doc), parser)
-                else:  # validate the request normally
-                    doc = etree.fromstring(postdata, parser)
-                LOGGER.debug('Request is valid XML.')
-            else:  # parse Transaction without validation
-                doc = etree.fromstring(postdata, self.context.parser)
-        except Exception as err:
-            errortext = \
-            'Exception: the document is not valid.\nError: %s' % str(err)
-            LOGGER.debug(errortext)
-            return errortext
-
-        request['request'] = util.xmltag_split(doc.tag)
-        LOGGER.debug('Request operation %s specified.' % request['request'])
-        tmp = doc.find('.').attrib.get('service')
-        if tmp is not None:
-            request['service'] = tmp
-
-        tmp = doc.find('.').attrib.get('version')
-        if tmp is not None:
-            request['version'] = tmp
-
-        tmp = doc.find('.//%s' % util.nspath_eval('ows:Version',
-        self.context.namespaces))
-
-        if tmp is not None:
-            request['version'] = tmp.text
-
-        tmp = doc.find('.').attrib.get('updateSequence')
-        if tmp is not None:
-            request['updatesequence'] = tmp
-
-        # GetCapabilities
-        if request['request'] == 'GetCapabilities':
-            tmp = doc.find(util.nspath_eval('ows:Sections',
-                  self.context.namespaces))
-            if tmp is not None:
-                request['sections'] = ','.join([section.text for section in \
-                doc.findall(util.nspath_eval('ows:Sections/ows:Section',
-                self.context.namespaces))])
-
-        # DescribeRecord
-        if request['request'] == 'DescribeRecord':
-            request['typename'] = [typename.text for typename in \
-            doc.findall(util.nspath_eval('csw:TypeName',
-            self.context.namespaces))]
-
-            tmp = doc.find('.').attrib.get('schemaLanguage')
-            if tmp is not None:
-                request['schemalanguage'] = tmp
-
-            tmp = doc.find('.').attrib.get('outputFormat')
-            if tmp is not None:
-                request['outputformat'] = tmp
-
-        # GetDomain
-        if request['request'] == 'GetDomain':
-            tmp = doc.find(util.nspath_eval('csw:ParameterName',
-                  self.context.namespaces))
-            if tmp is not None:
-                request['parametername'] = tmp.text
-
-            tmp = doc.find(util.nspath_eval('csw:PropertyName',
-                  self.context.namespaces))
-            if tmp is not None:
-                request['propertyname'] = tmp.text
-
-        # GetRecords
-        if request['request'] == 'GetRecords':
-            tmp = doc.find('.').attrib.get('outputSchema')
-            request['outputschema'] = tmp if tmp is not None \
-            else self.context.namespaces['csw']
-
-            tmp = doc.find('.').attrib.get('resultType')
-            request['resulttype'] = tmp if tmp is not None else None
-
-            tmp = doc.find('.').attrib.get('outputFormat')
-            request['outputformat'] = tmp if tmp is not None \
-            else 'application/xml'
-
-            tmp = doc.find('.').attrib.get('startPosition')
-            request['startposition'] = tmp if tmp is not None else 1
-
-            tmp = doc.find('.').attrib.get('requestId')
-            request['requestid'] = tmp if tmp is not None else None
-
-            tmp = doc.find('.').attrib.get('maxRecords')
-            if tmp is not None:
-                request['maxrecords'] = tmp
-
-            tmp = doc.find(util.nspath_eval('csw:DistributedSearch',
-                  self.context.namespaces))
-            if tmp is not None:
-                request['distributedsearch'] = True
-                hopcount = tmp.attrib.get('hopCount')
-                request['hopcount'] = int(hopcount)-1 if hopcount is not None \
-                else 1
-            else:
-                request['distributedsearch'] = False
-
-            tmp = doc.find(util.nspath_eval('csw:ResponseHandler',
-                  self.context.namespaces))
-            if tmp is not None:
-                request['responsehandler'] = tmp.text
-
-            tmp = doc.find(util.nspath_eval('csw:Query/csw:ElementSetName',
-                  self.context.namespaces))
-            request['elementsetname'] = tmp.text if tmp is not None else None
-
-            tmp = doc.find(util.nspath_eval(
-            'csw:Query', self.context.namespaces)).attrib.get('typeNames')
-            request['typenames'] = tmp.split() if tmp is not None \
-            else 'csw:Record'
-
-            request['elementname'] = [elname.text for elname in \
-            doc.findall(util.nspath_eval('csw:Query/csw:ElementName',
-            self.context.namespaces))]
-
-            request['constraint'] = {}
-            tmp = doc.find(util.nspath_eval('csw:Query/csw:Constraint',
-            self.context.namespaces))
-
-            if tmp is not None:
-                request['constraint'] = self._parse_constraint(tmp)
-                if isinstance(request['constraint'], str):  # parse error
-                    return 'Invalid Constraint: %s' % request['constraint']
-            else:
-                LOGGER.debug('No csw:Constraint (ogc:Filter or csw:CqlText) \
-                specified.')
-
-            tmp = doc.find(util.nspath_eval('csw:Query/ogc:SortBy',
-                  self.context.namespaces))
-            if tmp is not None:
-                LOGGER.debug('Sorted query specified.')
-                request['sortby'] = {}
-
-
-                try:
-                    elname = tmp.find(util.nspath_eval(
-                    'ogc:SortProperty/ogc:PropertyName',
-                    self.context.namespaces)).text
-
-                    request['sortby']['propertyname'] = \
-                    self.repository.queryables['_all'][elname]['dbcol']
-
-                    if (elname.find('BoundingBox') != -1 or
-                        elname.find('Envelope') != -1):
-                        # it's a spatial sort
-                        request['sortby']['spatial'] = True
-                except Exception as err:
-                    errortext = \
-                    'Invalid ogc:SortProperty/ogc:PropertyName: %s' % str(err)
-                    LOGGER.debug(errortext)
-                    return errortext
-
-                tmp2 =  tmp.find(util.nspath_eval(
-                'ogc:SortProperty/ogc:SortOrder', self.context.namespaces))
-                request['sortby']['order'] = tmp2.text if tmp2 is not None \
-                else 'ASC'
-            else:
-                request['sortby'] = None
-
-        # GetRecordById
-        if request['request'] == 'GetRecordById':
-            request['id'] = [id1.text for id1 in \
-            doc.findall(util.nspath_eval('csw:Id', self.context.namespaces))]
-
-            tmp = doc.find(util.nspath_eval('csw:ElementSetName',
-                  self.context.namespaces))
-            request['elementsetname'] = tmp.text if tmp is not None \
-            else 'summary'
-
-            tmp = doc.find('.').attrib.get('outputSchema')
-            request['outputschema'] = tmp if tmp is not None \
-            else self.context.namespaces['csw']
-
-            tmp = doc.find('.').attrib.get('outputFormat')
-            if tmp is not None:
-                request['outputformat'] = tmp
-
-        # Transaction
-        if request['request'] == 'Transaction':
-            request['verboseresponse'] = True
-            tmp = doc.find('.').attrib.get('verboseResponse')
-            if tmp is not None:
-                if tmp in ['false', '0']:
-                    request['verboseresponse'] = False
-
-            tmp = doc.find('.').attrib.get('requestId')
-            request['requestid'] = tmp if tmp is not None else None
-
-            request['transactions'] = []
-
-            for ttype in \
-            doc.xpath('//csw:Insert', namespaces=self.context.namespaces):
-                tname = ttype.attrib.get('typeName')
-
-                for mdrec in ttype.xpath('child::*'):
-                    xml = mdrec
-                    request['transactions'].append(
-                    {'type': 'insert', 'typename': tname, 'xml': xml})
-
-            for ttype in \
-            doc.xpath('//csw:Update', namespaces=self.context.namespaces):
-                child = ttype.xpath('child::*')
-                update = {'type': 'update'}
-
-                if len(child) == 1:  # it's a wholesale update
-                    update['xml'] = child[0]
-                else:  # it's a RecordProperty with Constraint Update
-                    update['recordproperty'] = []
-
-                    for recprop in ttype.findall(
-                    util.nspath_eval('csw:RecordProperty',
-                        self.context.namespaces)):
-                        rpname = recprop.find(util.nspath_eval('csw:Name',
-                        self.context.namespaces)).text
-                        rpvalue = recprop.find(
-                        util.nspath_eval('csw:Value',
-                        self.context.namespaces)).text
-
-                        update['recordproperty'].append(
-                        {'name': rpname, 'value': rpvalue})
-
-                    update['constraint'] = self._parse_constraint(
-                    ttype.find(util.nspath_eval('csw:Constraint',
-                    self.context.namespaces)))
-
-                request['transactions'].append(update)
-
-            for ttype in \
-            doc.xpath('//csw:Delete', namespaces=self.context.namespaces):
-                tname = ttype.attrib.get('typeName')
-                constraint = self._parse_constraint(
-                ttype.find(util.nspath_eval('csw:Constraint',
-                self.context.namespaces)))
-
-                if isinstance(constraint, str):  # parse error
-                    return 'Invalid Constraint: %s' % constraint
-
-                request['transactions'].append(
-                {'type': 'delete', 'typename': tname, 'constraint': constraint})
-
-        # Harvest
-        if request['request'] == 'Harvest':
-            request['source'] = doc.find(util.nspath_eval('csw:Source',
-            self.context.namespaces)).text
-
-            request['resourcetype'] = \
-            doc.find(util.nspath_eval('csw:ResourceType',
-            self.context.namespaces)).text
-
-            tmp = doc.find(util.nspath_eval('csw:ResourceFormat',
-                  self.context.namespaces))
-            if tmp is not None:
-                request['resourceformat'] = tmp.text
-            else:
-                request['resourceformat'] = 'application/xml'
-
-            tmp = doc.find(util.nspath_eval('csw:HarvestInterval',
-                  self.context.namespaces))
-            if tmp is not None:
-                request['harvestinterval'] = tmp.text
-
-            tmp = doc.find(util.nspath_eval('csw:ResponseHandler',
-                  self.context.namespaces))
-            if tmp is not None:
-                request['responsehandler'] = tmp.text
-        return request
-
-    def _write_record(self, recobj, queryables):
-        ''' Generate csw:Record '''
-        if self.kvp['elementsetname'] == 'brief':
-            elname = 'BriefRecord'
-        elif self.kvp['elementsetname'] == 'summary':
-            elname = 'SummaryRecord'
-        else:
-            elname = 'Record'
-
-        record = etree.Element(util.nspath_eval('csw:%s' % elname,
-                 self.context.namespaces))
-
-        if ('elementname' in self.kvp and
-            len(self.kvp['elementname']) > 0):
-            for elemname in self.kvp['elementname']:
-                if (elemname.find('BoundingBox') != -1 or
-                    elemname.find('Envelope') != -1):
-                    bboxel = write_boundingbox(util.getqattr(recobj,
-                    self.context.md_core_model['mappings']['pycsw:BoundingBox']),
-                    self.context.namespaces)
-                    if bboxel is not None:
-                        record.append(bboxel)
-                else:
-                    value = util.getqattr(recobj, queryables[elemname]['dbcol'])
-                    if value:
-                        etree.SubElement(record,
-                        util.nspath_eval(elemname,
-                        self.context.namespaces)).text = value
-        elif 'elementsetname' in self.kvp:
-            if (self.kvp['elementsetname'] == 'full' and
-            util.getqattr(recobj, self.context.md_core_model['mappings']\
-            ['pycsw:Typename']) == 'csw:Record' and
-            util.getqattr(recobj, self.context.md_core_model['mappings']\
-            ['pycsw:Schema']) == 'http://www.opengis.net/cat/csw/2.0.2' and
-            util.getqattr(recobj, self.context.md_core_model['mappings']\
-            ['pycsw:Type']) != 'service'):
-                # dump record as is and exit
-                return etree.fromstring(util.getqattr(recobj,
-                self.context.md_core_model['mappings']['pycsw:XML']), self.context.parser)
-
-            etree.SubElement(record,
-            util.nspath_eval('dc:identifier', self.context.namespaces)).text = \
-            util.getqattr(recobj,
-            self.context.md_core_model['mappings']['pycsw:Identifier'])
-
-            for i in ['dc:title', 'dc:type']:
-                val = util.getqattr(recobj, queryables[i]['dbcol'])
-                if not val:
-                    val = ''
-                etree.SubElement(record, util.nspath_eval(i,
-                self.context.namespaces)).text = val
-
-            if self.kvp['elementsetname'] in ['summary', 'full']:
-                # add summary elements
-                keywords = util.getqattr(recobj, queryables['dc:subject']['dbcol'])
-                if keywords is not None:
-                    for keyword in keywords.split(','):
-                        etree.SubElement(record,
-                        util.nspath_eval('dc:subject',
-                        self.context.namespaces)).text = keyword
-
-                val = util.getqattr(recobj, queryables['dc:format']['dbcol'])
-                if val:
-                    etree.SubElement(record,
-                    util.nspath_eval('dc:format',
-                    self.context.namespaces)).text = val
-
-                # links
-                rlinks = util.getqattr(recobj,
-                self.context.md_core_model['mappings']['pycsw:Links'])
-
-                if rlinks:
-                    links = rlinks.split('^')
-                    for link in links:
-                        linkset = link.split(',')
-                        etree.SubElement(record,
-                        util.nspath_eval('dct:references',
-                        self.context.namespaces),
-                        scheme=linkset[2]).text = linkset[-1]
-
-                for i in ['dc:relation', 'dct:modified', 'dct:abstract']:
-                    val = util.getqattr(recobj, queryables[i]['dbcol'])
-                    if val is not None:
-                        etree.SubElement(record,
-                        util.nspath_eval(i, self.context.namespaces)).text = val
-
-            if self.kvp['elementsetname'] == 'full':  # add full elements
-                for i in ['dc:date', 'dc:creator', \
-                'dc:publisher', 'dc:contributor', 'dc:source', \
-                'dc:language', 'dc:rights']:
-                    val = util.getqattr(recobj, queryables[i]['dbcol'])
-                    if val:
-                        etree.SubElement(record,
-                        util.nspath_eval(i, self.context.namespaces)).text = val
-
-            # always write out ows:BoundingBox
-            bboxel = write_boundingbox(getattr(recobj,
-            self.context.md_core_model['mappings']['pycsw:BoundingBox']),
-            self.context.namespaces)
-
-            if bboxel is not None:
-                record.append(bboxel)
-        return record
+        """ Handle Harvest request """
+        return self.iface.harvest()
 
     def _write_response(self):
-        ''' Generate response '''
+        """ Generate response """
         # set HTTP response headers and XML declaration
 
-        xmldecl=''
-        appinfo=''
+        xmldecl = ''
+        appinfo = ''
 
         LOGGER.debug('Writing response.')
 
         if hasattr(self, 'soap') and self.soap:
             self._gen_soap_wrapper()
 
+        if etree.__version__ >= '3.5.0':  # remove superfluous namespaces
+            etree.cleanup_namespaces(self.response,
+                                     keep_ns_prefixes=self.context.keep_ns_prefixes)
+
+        response = etree.tostring(self.response,
+                                  pretty_print=self.pretty_print,
+                                  encoding='unicode')
+
         if (isinstance(self.kvp, dict) and 'outputformat' in self.kvp and
-            self.kvp['outputformat'] == 'application/json'):
+                self.kvp['outputformat'] == 'application/json'):
             self.contenttype = self.kvp['outputformat']
-            from pycsw.formats import fmt_json
-            response = fmt_json.exml2json(self.response,
-            self.context.namespaces, self.pretty_print)
+            from pycsw.core.formats import fmt_json
+            response = fmt_json.xml2json(response,
+                                         self.context.namespaces,
+                                         self.pretty_print)
         else:  # it's XML
-            self.contenttype = self.mimetype
-            response = etree.tostring(self.response,
-            pretty_print=self.pretty_print, encoding='unicode')
-            xmldecl = '<?xml version="1.0" encoding="%s" standalone="no"?>\n' \
-            % self.encoding
+            if 'outputformat' in self.kvp:
+                self.contenttype = self.kvp['outputformat']
+            else:
+                self.contenttype = self.mimetype
+
+            xmldecl = ('<?xml version="1.0" encoding="%s" standalone="no"?>'
+                       '\n' % self.encoding)
             appinfo = '<!-- pycsw %s -->\n' % self.context.version
 
+        if isinstance(self.contenttype, bytes):
+            self.contenttype = self.contenttype.decode()
+
         s = (u'%s%s%s' % (xmldecl, appinfo, response)).encode(self.encoding)
+        LOGGER.debug('Response code: %s',
+                     self.context.response_codes[self.status])
         LOGGER.debug('Response:\n%s', s)
-        return s
-
+        return [self.context.response_codes[self.status], s]
 
     def _gen_soap_wrapper(self):
-        ''' Generate SOAP wrapper '''
+        """ Generate SOAP wrapper """
         LOGGER.debug('Writing SOAP wrapper.')
-        node = etree.Element(util.nspath_eval('soapenv:Envelope',
-        self.context.namespaces), nsmap=self.context.namespaces)
-
-        node.attrib[util.nspath_eval('xsi:schemaLocation',
-        self.context.namespaces)] = '%s %s' % \
-        (self.context.namespaces['soapenv'], self.context.namespaces['soapenv'])
-
-        node2 = etree.SubElement(node, util.nspath_eval('soapenv:Body',
-        self.context.namespaces))
-
-        if hasattr(self, 'exception') and self.exception:
-            node3 = etree.SubElement(node2, util.nspath_eval('soapenv:Fault',
-                    self.context.namespaces))
-            node4 = etree.SubElement(node3, util.nspath_eval('soapenv:Code',
-                    self.context.namespaces))
-
-            etree.SubElement(node4, util.nspath_eval('soapenv:Value',
-            self.context.namespaces)).text = 'soap:Server'
-
-            node4 = etree.SubElement(node3, util.nspath_eval('soapenv:Reason',
-                    self.context.namespaces))
-
-            etree.SubElement(node4, util.nspath_eval('soapenv:Text',
-            self.context.namespaces)).text = 'A server exception was encountered.'
-
-            node4 = etree.SubElement(node3, util.nspath_eval('soapenv:Detail',
-                    self.context.namespaces))
+        node = etree.Element(
+            util.nspath_eval('soapenv:Envelope', self.context.namespaces),
+            nsmap=self.context.namespaces
+        )
+
+        schema_location_ns = util.nspath_eval('xsi:schemaLocation',
+                                              self.context.namespaces)
+        node.attrib[schema_location_ns] = '%s %s' % (
+            self.context.namespaces['soapenv'],
+            self.context.namespaces['soapenv']
+        )
+
+        node2 = etree.SubElement(
+            node, util.nspath_eval('soapenv:Body', self.context.namespaces))
+
+        if self.exception:
+            node3 = etree.SubElement(
+                node2,
+                util.nspath_eval('soapenv:Fault', self.context.namespaces)
+            )
+            node4 = etree.SubElement(
+                node3,
+                util.nspath_eval('soapenv:Code', self.context.namespaces)
+            )
+
+            etree.SubElement(
+                node4,
+                util.nspath_eval('soapenv:Value', self.context.namespaces)
+            ).text = 'soap:Server'
+
+            node4 = etree.SubElement(
+                node3,
+                util.nspath_eval('soapenv:Reason', self.context.namespaces)
+            )
+
+            etree.SubElement(
+                node4,
+                util.nspath_eval('soapenv:Text', self.context.namespaces)
+            ).text = 'A server exception was encountered.'
+
+            node4 = etree.SubElement(
+                node3,
+                util.nspath_eval('soapenv:Detail', self.context.namespaces)
+            )
             node4.append(self.response)
         else:
             node2.append(self.response)
@@ -2424,57 +760,56 @@ class Csw(object):
         self.response = node
 
     def _gen_manager(self):
-        ''' Update self.context.model with CSW-T advertising '''
+        """ Update self.context.model with CSW-T advertising """
         if (self.config.has_option('manager', 'transactions') and
-            self.config.get('manager', 'transactions') == 'true'):
-            self.context.model['operations']['Transaction'] = \
-            {'methods': {'get': False, 'post': True}, 'parameters': {}}
-
-            self.context.model['operations']['Harvest'] = \
-            {'methods': {'get': False, 'post': True}, 'parameters': \
-            {'ResourceType': {'values': \
-            ['http://www.opengis.net/cat/csw/2.0.2',
-             'http://www.opengis.net/wms',
-             'http://www.opengis.net/wfs',
-             'http://www.opengis.net/wcs',
-             'http://www.opengis.net/wps/1.0.0',
-             'http://www.opengis.net/sos/1.0',
-             'http://www.opengis.net/sos/2.0',
-             'http://www.isotc211.org/2005/gmi',
-             'urn:geoss:waf',
-            ]}}}
+                self.config.get('manager', 'transactions') == 'true'):
+
+            self.manager = True
+
+            self.context.model['operations_order'].append('Transaction')
+
+            self.context.model['operations']['Transaction'] = {
+                'methods': {'get': False, 'post': True},
+                'parameters': {}
+            }
+
+            schema_values = [
+                'http://www.opengis.net/cat/csw/2.0.2',
+                'http://www.opengis.net/cat/csw/3.0',
+                'http://www.opengis.net/wms',
+                'http://www.opengis.net/wmts/1.0',
+                'http://www.opengis.net/wfs',
+                'http://www.opengis.net/wcs',
+                'http://www.opengis.net/wps/1.0.0',
+                'http://www.opengis.net/sos/1.0',
+                'http://www.opengis.net/sos/2.0',
+                'http://www.isotc211.org/2005/gmi',
+                'urn:geoss:waf',
+            ]
+
+            self.context.model['operations_order'].append('Harvest')
+
+            self.context.model['operations']['Harvest'] = {
+                'methods': {'get': False, 'post': True},
+                'parameters': {
+                    'ResourceType': {'values': schema_values}
+                }
+            }
+
+            self.context.model['operations']['Transaction'] = {
+                'methods': {'get': False, 'post': True},
+                'parameters': {
+                    'TransactionSchemas': {'values': sorted(schema_values)}
+                }
+            }
 
             self.csw_harvest_pagesize = 10
             if self.config.has_option('manager', 'csw_harvest_pagesize'):
-                self.csw_harvest_pagesize = int(self.config.get('manager',
-                'csw_harvest_pagesize'))
-
-    def _parse_constraint(self, element):
-        ''' Parse csw:Constraint '''
-
-        query = {}
-
-        tmp = element.find(util.nspath_eval('ogc:Filter', self.context.namespaces))
-        if tmp is not None:
-            LOGGER.debug('Filter constraint specified.')
-            try:
-                query['type'] = 'filter'
-                query['where'], query['values'] = fes.parse(tmp,
-                self.repository.queryables['_all'], self.repository.dbtype,
-                self.context.namespaces, self.orm, self.language['text'], self.repository.fts)
-            except Exception as err:
-                return 'Invalid Filter request: %s' % err
-        tmp = element.find(util.nspath_eval('csw:CqlText', self.context.namespaces))
-        if tmp is not None:
-            LOGGER.debug('CQL specified: %s.' % tmp.text)
-            query['type'] = 'cql'
-            query['where'] = self._cql_update_queryables_mappings(tmp.text,
-            self.repository.queryables['_all'])
-            query['values'] = {}
-        return query
+                self.csw_harvest_pagesize = int(
+                    self.config.get('manager', 'csw_harvest_pagesize'))
 
     def _test_manager(self):
-        ''' Verify that transactions are allowed '''
+        """ Verify that transactions are allowed """
 
         if self.config.get('manager', 'transactions') != 'true':
             raise RuntimeError('CSW-T interface is disabled')
@@ -2482,16 +817,16 @@ class Csw(object):
         ipaddress = self.environ['REMOTE_ADDR']
 
         if not self.config.has_option('manager', 'allowed_ips') or \
-        (self.config.has_option('manager', 'allowed_ips') and not 
+        (self.config.has_option('manager', 'allowed_ips') and not
          util.ipaddress_in_whitelist(ipaddress,
                         self.config.get('manager', 'allowed_ips').split(','))):
             raise RuntimeError(
             'CSW-T operations not allowed for this IP address: %s' % ipaddress)
 
     def _cql_update_queryables_mappings(self, cql, mappings):
-        ''' Transform CQL query's properties to underlying DB columns '''
+        """ Transform CQL query's properties to underlying DB columns """
         LOGGER.debug('Raw CQL text = %s.' % cql)
-        LOGGER.debug(str(mappings.keys()))
+        LOGGER.debug(str(list(mappings.keys())))
         if cql is not None:
             for key in mappings.keys():
                 try:
@@ -2501,61 +836,14 @@ class Csw(object):
             LOGGER.debug('Interpolated CQL text = %s.' % cql)
             return cql
 
-    def _write_transactionsummary(self, inserted=0, updated=0, deleted=0):
-        ''' Write csw:TransactionSummary construct '''
-        node = etree.Element(util.nspath_eval('csw:TransactionSummary',
-               self.context.namespaces))
-
-        if 'requestid' in self.kvp and self.kvp['requestid'] is not None:
-            node.attrib['requestId'] = self.kvp['requestid']
-
-        etree.SubElement(node, util.nspath_eval('csw:totalInserted',
-        self.context.namespaces)).text = str(inserted)
-
-        etree.SubElement(node, util.nspath_eval('csw:totalUpdated',
-        self.context.namespaces)).text = str(updated)
-
-        etree.SubElement(node, util.nspath_eval('csw:totalDeleted',
-        self.context.namespaces)).text = str(deleted)
-
-        return node
-
-    def _write_acknowledgement(self, root=True):
-        ''' Generate csw:Acknowledgement '''
-        node = etree.Element(util.nspath_eval('csw:Acknowledgement',
-               self.context.namespaces),
-        nsmap = self.context.namespaces, timeStamp=util.get_today_and_now())
-
-        if root:
-            node.attrib[util.nspath_eval('xsi:schemaLocation',
-            self.context.namespaces)] = \
-            '%s %s/csw/2.0.2/CSW-discovery.xsd' % (self.context.namespaces['csw'], \
-            self.config.get('server', 'ogc_schemas_base'))
-
-        node1 = etree.SubElement(node, util.nspath_eval('csw:EchoedRequest',
-                self.context.namespaces))
-        if self.requesttype == 'POST':
-            node1.append(etree.fromstring(self.request, self.context.parser))
-        else:  # GET
-            node2 = etree.SubElement(node1, util.nspath_eval('ows:Get',
-                    self.context.namespaces))
-
-            node2.text = self.request
-
-        if self.async:
-            etree.SubElement(node, util.nspath_eval('csw:RequestId',
-            self.context.namespaces)).text = self.kvp['requestid']
-
-        return node
-
     def _process_responsehandler(self, xml):
-        ''' Process response handler '''
+        """ Process response handler """
 
         if self.kvp['responsehandler'] is not None:
             LOGGER.debug('Processing responsehandler %s.' %
-            self.kvp['responsehandler'])
+                         self.kvp['responsehandler'])
 
-            uprh = urlparse.urlparse(self.kvp['responsehandler'])
+            uprh = urlparse(self.kvp['responsehandler'])
 
             if uprh.scheme == 'mailto':  # email
                 import smtplib
@@ -2566,15 +854,16 @@ class Csw(object):
                 if self.config.has_option('server', 'smtp_host'):
                     smtp_host = self.config.get('server', 'smtp_host')
 
-                body = 'Subject: pycsw %s results\n\n%s' % \
-                (self.kvp['request'], xml)
+                body = ('Subject: pycsw %s results\n\n%s' %
+                        (self.kvp['request'], xml))
 
                 try:
                     LOGGER.debug('Sending email.')
                     msg = smtplib.SMTP(smtp_host)
                     msg.sendmail(
-                    self.config.get('metadata:main', 'contact_email'),
-                    uprh.path, body)
+                        self.config.get('metadata:main', 'contact_email'),
+                        uprh.path, body
+                    )
                     msg.quit()
                     LOGGER.debug('Email sent successfully.')
                 except Exception as err:
@@ -2596,47 +885,21 @@ class Csw(object):
                 except Exception as err:
                     LOGGER.debug('Error processing FTP: %s.' % str(err))
 
-    def _write_verboseresponse(self, insertresults):
-        ''' show insert result identifiers '''
-        insertresult = etree.Element(util.nspath_eval('csw:InsertResult',
-        self.context.namespaces))
-        for ir in insertresults:
-            briefrec = etree.SubElement(insertresult,
-                       util.nspath_eval('csw:BriefRecord',
-                       self.context.namespaces))
+    @staticmethod
+    def normalize_kvp(kvp):
+        """Normalize Key Value Pairs.
 
-            etree.SubElement(briefrec,
-            util.nspath_eval('dc:identifier',
-            self.context.namespaces)).text = ir['identifier']
+        This method will transform all keys to lowercase and leave values
+        unchanged, as specified in the CSW standard (see for example note
+        C on Table 62 - KVP Encoding for DescribeRecord operation request
+        of the CSW standard version 2.0.2)
 
-            etree.SubElement(briefrec,
-            util.nspath_eval('dc:title',
-            self.context.namespaces)).text = ir['title']
+        :arg kvp: a mapping with Key Value Pairs
+        :type kvp: dict
+        :returns: A new dictionary with normalized parameters
+        """
 
-        return insertresult
-
-def write_boundingbox(bbox, nsmap):
-    ''' Generate ows:BoundingBox '''
-
-    if bbox is not None:
-        try:
-            bbox2 = util.wkt2geom(bbox)
-        except:
-            return None
-
-        if len(bbox2) == 4:
-            boundingbox = etree.Element(util.nspath_eval('ows:BoundingBox',
-            nsmap), crs='urn:x-ogc:def:crs:EPSG:6.11:4326',
-            dimensions='2')
-
-            etree.SubElement(boundingbox, util.nspath_eval('ows:LowerCorner',
-            nsmap)).text = '%s %s' % (bbox2[1], bbox2[0])
-
-            etree.SubElement(boundingbox, util.nspath_eval('ows:UpperCorner',
-            nsmap)).text = '%s %s' % (bbox2[3], bbox2[2])
-
-            return boundingbox
-        else:
-            return None
-    else:
-        return None
+        result = dict()
+        for name, value in kvp.items():
+            result[name.lower()] = value
+        return result
diff --git a/pycsw/sru.py b/pycsw/sru.py
index d7788e6..6240f49 100644
--- a/pycsw/sru.py
+++ b/pycsw/sru.py
@@ -1,9 +1,9 @@
-# -*- coding: iso-8859-15 -*-
+# -*- coding: utf-8 -*-
 # =================================================================
 #
 # Authors: Tom Kralidis <tomkralidis at gmail.com>
 #
-# Copyright (c) 2011 Tom Kralidis
+# Copyright (c) 2015 Tom Kralidis
 #
 # Permission is hereby granted, free of charge, to any person
 # obtaining a copy of this software and associated documentation
@@ -28,8 +28,9 @@
 #
 # =================================================================
 
-from lxml import etree
-from pycsw import fes, util
+from pycsw.core import util
+from pycsw.core.etree import etree
+from pycsw.ogc.fes import fes1
 
 
 class Sru(object):
@@ -103,8 +104,8 @@ class Sru(object):
 
                 if 'query' in kvpin:
                     pname_in_query = False
-                    for coops in fes.MODEL['ComparisonOperators'].keys():
-                        if kvpin['query'].find(fes.MODEL['ComparisonOperators'][coops]['opvalue']) != -1:
+                    for coops in fes1.MODEL['ComparisonOperators'].keys():
+                        if kvpin['query'].find(fes1.MODEL['ComparisonOperators'][coops]['opvalue']) != -1:
                             pname_in_query = True
                             break
 
@@ -144,13 +145,13 @@ class Sru(object):
 
             databaseinfo = etree.SubElement(explain, util.nspath_eval('zr:databaseInfo', self.namespaces))
 
-            etree.SubElement(databaseinfo, util.nspath_eval('zr:title', self.namespaces), lang='en', primary='true').text = element.xpath('//ows:Title', namespaces=self.context.namespaces)[0].text
-            etree.SubElement(databaseinfo, util.nspath_eval('zr:description', self.namespaces), lang='en', primary='true').text = element.xpath('//ows:Abstract', namespaces=self.context.namespaces)[0].text
+            etree.SubElement(databaseinfo, util.nspath_eval('zr:title', self.namespaces), lang='en', primary='true').text = element.xpath('//ows:Title|//ows20:Title', namespaces=self.context.namespaces)[0].text
+            etree.SubElement(databaseinfo, util.nspath_eval('zr:description', self.namespaces), lang='en', primary='true').text = element.xpath('//ows:Abstract|//ows20:Abstract', namespaces=self.context.namespaces)[0].text
 
             indexinfo = etree.SubElement(explain, util.nspath_eval('zr:indexInfo', self.namespaces))
             etree.SubElement(indexinfo, util.nspath_eval('zr:set', self.namespaces), name='dc', identifier='info:srw/cql-context-set/1/dc-v1.1')
 
-            for key, value in self.mappings['csw:Record']['index'].iteritems():
+            for key, value in sorted(self.mappings['csw:Record']['index'].items()):
                 zrindex = etree.SubElement(indexinfo, util.nspath_eval('zr:index', self.namespaces), id=value)
                 etree.SubElement(zrindex, util.nspath_eval('zr:title', self.namespaces)).text = key
                 zrmap = etree.SubElement(zrindex, util.nspath_eval('zr:map', self.namespaces))
@@ -207,9 +208,9 @@ class Sru(object):
             'info:srw/diagnostic/1/7'
 
         etree.SubElement(diagnostic, util.nspath_eval('zd:message', self.namespaces)).text = \
-            element.find(util.nspath_eval('ows:Exception/ows:ExceptionText', self.context.namespaces)).text
+            element.xpath('//ows:Exception/ows:ExceptionText|//ows20:Exception/ows20:ExceptionText', namespaces=self.context.namespaces)[0].text
 
         etree.SubElement(diagnostic, util.nspath_eval('zd:details', self.namespaces)).text = \
-            element.find(util.nspath_eval('ows:Exception', self.context.namespaces)).attrib.get('exceptionCode')
+            element.xpath('//ows:Exception|//ows20:Exception', namespaces=self.context.namespaces)[0].attrib.get('exceptionCode')
 
         return node
diff --git a/csw.wsgi b/pycsw/wsgi.py
similarity index 84%
rename from csw.wsgi
rename to pycsw/wsgi.py
index ca9ac1f..65eea14 100644
--- a/csw.wsgi
+++ b/pycsw/wsgi.py
@@ -1,9 +1,9 @@
-# -*- coding: iso-8859-15 -*-
+# -*- coding: utf-8 -*-
 # =================================================================
 #
 # Authors: Adam Hinz <hinz.adam at gmail.com>
 #
-# Copyright (c) 2012 Adam Hinz
+# Copyright (c) 2015 Adam Hinz
 #
 # Permission is hereby granted, free of charge, to any person
 # obtaining a copy of this software and associated documentation
@@ -36,7 +36,7 @@
 # WSGIDaemonProcess host1 home=/var/www/pycsw processes=2
 # WSGIProcessGroup host1
 #
-# WSGIScriptAlias /pycsw-wsgi /var/www/pycsw/csw.wsgi
+# WSGIScriptAlias /pycsw-wsgi /var/www/pycsw/wsgi.py
 #
 # <Directory /var/www/pycsw>
 #  Order deny,allow
@@ -45,23 +45,24 @@
 #
 # or invoke this script from the command line:
 #
-# $ python ./csw.wsgi
+# $ python ./pycsw/wsgi.py
 #
 # which will publish pycsw to:
 #
 # http://localhost:8000/
 #
 
-from StringIO import StringIO
 import os
 import sys
-
-app_path = os.path.dirname(__file__)
-sys.path.append(app_path)
+import six
+from six.moves.urllib.parse import unquote
 
 from pycsw import server
 
 
+PYCSW_ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
+
+
 def application(env, start_response):
     """WSGI wrapper"""
     config = 'default.cfg'
@@ -72,15 +73,15 @@ def application(env, start_response):
     if env['QUERY_STRING'].lower().find('config') != -1:
         for kvp in env['QUERY_STRING'].split('&'):
             if kvp.lower().find('config') != -1:
-                config = kvp.split('=')[1]
+                config = unquote(kvp.split('=')[1])
 
     if not os.path.isabs(config):
-        config = os.path.join(app_path, config)
+        config = os.path.join(PYCSW_ROOT, config)
 
     if 'HTTP_HOST' in env and ':' in env['HTTP_HOST']:
         env['HTTP_HOST'] = env['HTTP_HOST'].split(':')[0]
 
-    env['local.app_root'] = app_path
+    env['local.app_root'] = PYCSW_ROOT
 
     csw = server.Csw(config, env)
 
@@ -97,14 +98,14 @@ def application(env, start_response):
     else:
         gzip_compresslevel = 0
 
-    contents = csw.dispatch_wsgi()
+    status, contents = csw.dispatch_wsgi()
 
     headers = {}
 
     if gzip and gzip_compresslevel > 0:
         import gzip
 
-        buf = StringIO()
+        buf = six.BytesIO()
         gzipfile = gzip.GzipFile(mode='wb', fileobj=buf,
                                  compresslevel=gzip_compresslevel)
         gzipfile.write(contents)
@@ -115,10 +116,8 @@ def application(env, start_response):
         headers['Content-Encoding'] = 'gzip'
 
     headers['Content-Length'] = str(len(contents))
-    headers['Content-Type'] = csw.contenttype
-
-    status = '200 OK'
-    start_response(status, headers.items())
+    headers['Content-Type'] = str(csw.contenttype)
+    start_response(status, list(headers.items()))
 
     return [contents]
 
@@ -128,5 +127,5 @@ if __name__ == '__main__':  # run inline using WSGI reference implementation
     if len(sys.argv) > 1:
         port = int(sys.argv[1])
     httpd = make_server('', port, application)
-    print "Serving on port %d..." % port
+    print('Serving on port %d...' % port)
     httpd.serve_forever()
diff --git a/requirements-pg.txt b/requirements-pg.txt
new file mode 100644
index 0000000..658130b
--- /dev/null
+++ b/requirements-pg.txt
@@ -0,0 +1 @@
+psycopg2
diff --git a/requirements-standalone.txt b/requirements-standalone.txt
index 716454a..5a2221a 100644
--- a/requirements-standalone.txt
+++ b/requirements-standalone.txt
@@ -1,2 +1 @@
-psycopg2
-SQLAlchemy>=0.6
+SQLAlchemy
diff --git a/requirements.txt b/requirements.txt
index e117383..612db02 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,5 +1,7 @@
-geolinks==0.0.1
-lxml==3.3.5
-OWSLib<0.9.0
+geolinks==0.2.0
+lxml>=3.3.5
+OWSLib==0.10.3
 pyproj==1.9.3
 Shapely==1.3.1
+six==1.10.0
+xmltodict==0.9.2
diff --git a/setup.py b/setup.py
index cc49aa9..c2a1326 100644
--- a/setup.py
+++ b/setup.py
@@ -1,9 +1,9 @@
-# -*- coding: iso-8859-15 -*-
+# -*- coding: utf-8 -*-
 # =================================================================
 #
 # Authors: Tom Kralidis <tomkralidis at gmail.com>
 #
-# Copyright (c) 2012 Tom Kralidis
+# Copyright (c) 2016 Tom Kralidis
 #
 # Permission is hereby granted, free of charge, to any person
 # obtaining a copy of this software and associated documentation
@@ -79,7 +79,9 @@ def get_package_data(location='.', forced_dir=None):
         for root, dirs, files in os.walk(filepath):
             if len(files) > 0:
                 # find all the XML Schema documents
-                xsds = filter(lambda x: x.find('.xsd') != -1, files)
+                xsds = [x for x in files if x.find('.xsd') != -1]
+                catalog_xml = [x for x in files if x.find('catalog.xml') != -1]
+                xsds.extend(catalog_xml)
                 if len(xsds) > 0:
                     if ploc not in package_data:  # set key
                         package_data[ploc] = []
@@ -98,7 +100,7 @@ if (os.path.exists('MANIFEST')):
     os.unlink('MANIFEST')
 
 # set setup.packages
-PACKAGES = find_packages('.').keys()
+PACKAGES = list(find_packages('.').keys())
 
 # get package_data.keys()
 PACKAGE_DATA_XSD = find_packages_xsd('pycsw')
@@ -115,19 +117,23 @@ PACKAGE_DATA = get_package_data(PACKAGE_DATA_XSD)
 PACKAGE_DATA.update(get_package_data([ROOT_PACKAGE], 'schemas'))
 
 # set the dependencies
-# GeoNode and OpenDataCatalog do not require SQLAlchemy
-INSTALL_REQUIRES = [line.strip() for line in open('requirements.txt')]
+# GeoNode, HHypermap and OpenDataCatalog do not require SQLAlchemy
+with open('requirements.txt') as f:
+    INSTALL_REQUIRES = f.read().splitlines()
 
 KEYWORDS = ('pycsw csw catalogue catalog metadata discovery search'
             ' ogc iso fgdc dif ebrim inspire')
 
 DESCRIPTION = 'pycsw is an OGC CSW server implementation written in Python'
 
+with open('README.txt') as f:
+    LONG_DESCRIPTION = f.read()
+
 setup(
     name='pycsw',
     version=pycsw.__version__,
     description=DESCRIPTION,
-    long_description=open('README.txt').read(),
+    long_description=LONG_DESCRIPTION,
     license='MIT',
     platforms='all',
     keywords=KEYWORDS,
diff --git a/tests/expected/suites_apiso-inspire_get_GetCapabilities-lang.xml b/tests/expected/suites_apiso-inspire_get_GetCapabilities-lang.xml
index 645e362..6ecec21 100644
--- a/tests/expected/suites_apiso-inspire_get_GetCapabilities-lang.xml
+++ b/tests/expected/suites_apiso-inspire_get_GetCapabilities-lang.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<csw:Capabilities xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:inspire_common="http://inspire.ec.europa.eu/schemas/common/1.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dct="http://purl.org/dc/terms/" xmlns:ows="http://www.opengis.net/ows" xmlns:apiso="http://www.opengis.net/cat/csw/apiso/1.0" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns: [...]
+<csw:Capabilities xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:inspire_common="http://inspire.ec.europa.eu/schemas/common/1.0" xmlns:inspire_ds="http://inspire.ec.europa.eu/schemas/inspire_ds/1.0" xmlns:ogc="http://www.opengis.net/ogc" xmlns:ows="http://www.opengis.net/ows" xmlns:xlink="http://www.w3.org/1999/xlink [...]
   <ows:ServiceIdentification>
     <ows:Title>pycsw Geospatial Catalogue</ows:Title>
     <ows:Abstract>pycsw is an OGC CSW server implementation written in Python</ows:Abstract>
@@ -11,6 +11,7 @@
     </ows:Keywords>
     <ows:ServiceType codeSpace="OGC">CSW</ows:ServiceType>
     <ows:ServiceTypeVersion>2.0.2</ows:ServiceTypeVersion>
+    <ows:ServiceTypeVersion>3.0.0</ows:ServiceTypeVersion>
     <ows:Fees>None</ows:Fees>
     <ows:AccessConstraints>None</ows:AccessConstraints>
   </ows:ServiceIdentification>
@@ -49,19 +50,12 @@
         </ows:HTTP>
       </ows:DCP>
       <ows:Parameter name="sections">
+        <ows:Value>Filter_Capabilities</ows:Value>
+        <ows:Value>OperationsMetadata</ows:Value>
         <ows:Value>ServiceIdentification</ows:Value>
         <ows:Value>ServiceProvider</ows:Value>
-        <ows:Value>OperationsMetadata</ows:Value>
-        <ows:Value>Filter_Capabilities</ows:Value>
       </ows:Parameter>
     </ows:Operation>
-    <ows:Operation name="GetRepositoryItem">
-      <ows:DCP>
-        <ows:HTTP>
-          <ows:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/apiso-inspire/default.cfg"/>
-        </ows:HTTP>
-      </ows:DCP>
-    </ows:Operation>
     <ows:Operation name="DescribeRecord">
       <ows:DCP>
         <ows:HTTP>
@@ -69,14 +63,14 @@
           <ows:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/apiso-inspire/default.cfg"/>
         </ows:HTTP>
       </ows:DCP>
-      <ows:Parameter name="schemaLanguage">
-        <ows:Value>http://www.w3.org/XML/Schema</ows:Value>
-        <ows:Value>http://www.w3.org/TR/xmlschema-1/</ows:Value>
-        <ows:Value>http://www.w3.org/2001/XMLSchema</ows:Value>
-      </ows:Parameter>
       <ows:Parameter name="outputFormat">
-        <ows:Value>application/xml</ows:Value>
         <ows:Value>application/json</ows:Value>
+        <ows:Value>application/xml</ows:Value>
+      </ows:Parameter>
+      <ows:Parameter name="schemaLanguage">
+        <ows:Value>http://www.w3.org/2001/XMLSchema</ows:Value>
+        <ows:Value>http://www.w3.org/TR/xmlschema-1/</ows:Value>
+        <ows:Value>http://www.w3.org/XML/Schema</ows:Value>
       </ows:Parameter>
       <ows:Parameter name="typeName">
         <ows:Value>csw:Record</ows:Value>
@@ -91,66 +85,48 @@
         </ows:HTTP>
       </ows:DCP>
       <ows:Parameter name="ParameterName">
+        <ows:Value>DescribeRecord.outputFormat</ows:Value>
+        <ows:Value>DescribeRecord.schemaLanguage</ows:Value>
+        <ows:Value>DescribeRecord.typeName</ows:Value>
+        <ows:Value>GetCapabilities.sections</ows:Value>
+        <ows:Value>GetRecordById.ElementSetName</ows:Value>
+        <ows:Value>GetRecordById.outputFormat</ows:Value>
+        <ows:Value>GetRecordById.outputSchema</ows:Value>
+        <ows:Value>GetRecords.CONSTRAINTLANGUAGE</ows:Value>
+        <ows:Value>GetRecords.ElementSetName</ows:Value>
         <ows:Value>GetRecords.outputFormat</ows:Value>
         <ows:Value>GetRecords.outputSchema</ows:Value>
-        <ows:Value>GetRecords.CONSTRAINTLANGUAGE</ows:Value>
         <ows:Value>GetRecords.resultType</ows:Value>
         <ows:Value>GetRecords.typeNames</ows:Value>
-        <ows:Value>GetRecords.ElementSetName</ows:Value>
-        <ows:Value>GetCapabilities.sections</ows:Value>
-        <ows:Value>GetRecordById.outputFormat</ows:Value>
-        <ows:Value>GetRecordById.outputSchema</ows:Value>
-        <ows:Value>GetRecordById.ElementSetName</ows:Value>
-        <ows:Value>DescribeRecord.schemaLanguage</ows:Value>
-        <ows:Value>DescribeRecord.outputFormat</ows:Value>
-        <ows:Value>DescribeRecord.typeName</ows:Value>
       </ows:Parameter>
     </ows:Operation>
-    <ows:Operation name="GetRecordById">
+    <ows:Operation name="GetRecords">
       <ows:DCP>
         <ows:HTTP>
           <ows:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/apiso-inspire/default.cfg"/>
           <ows:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/apiso-inspire/default.cfg"/>
         </ows:HTTP>
       </ows:DCP>
-      <ows:Parameter name="outputFormat">
-        <ows:Value>application/xml</ows:Value>
-        <ows:Value>application/json</ows:Value>
-      </ows:Parameter>
-      <ows:Parameter name="outputSchema">
-        <ows:Value>http://www.opengis.net/cat/csw/2.0.2</ows:Value>
-        <ows:Value>http://www.isotc211.org/2005/gmd</ows:Value>
-        <ows:Value>http://www.w3.org/2005/Atom</ows:Value>
-        <ows:Value>http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/</ows:Value>
-        <ows:Value>http://www.opengis.net/cat/csw/csdgm</ows:Value>
+      <ows:Parameter name="CONSTRAINTLANGUAGE">
+        <ows:Value>CQL_TEXT</ows:Value>
+        <ows:Value>FILTER</ows:Value>
       </ows:Parameter>
       <ows:Parameter name="ElementSetName">
         <ows:Value>brief</ows:Value>
-        <ows:Value>summary</ows:Value>
         <ows:Value>full</ows:Value>
+        <ows:Value>summary</ows:Value>
       </ows:Parameter>
-    </ows:Operation>
-    <ows:Operation name="GetRecords">
-      <ows:DCP>
-        <ows:HTTP>
-          <ows:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/apiso-inspire/default.cfg"/>
-          <ows:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/apiso-inspire/default.cfg"/>
-        </ows:HTTP>
-      </ows:DCP>
       <ows:Parameter name="outputFormat">
-        <ows:Value>application/xml</ows:Value>
         <ows:Value>application/json</ows:Value>
+        <ows:Value>application/xml</ows:Value>
       </ows:Parameter>
       <ows:Parameter name="outputSchema">
-        <ows:Value>http://www.opengis.net/cat/csw/2.0.2</ows:Value>
-        <ows:Value>http://www.isotc211.org/2005/gmd</ows:Value>
-        <ows:Value>http://www.w3.org/2005/Atom</ows:Value>
         <ows:Value>http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/</ows:Value>
+        <ows:Value>http://www.interlis.ch/INTERLIS2.3</ows:Value>
+        <ows:Value>http://www.isotc211.org/2005/gmd</ows:Value>
+        <ows:Value>http://www.opengis.net/cat/csw/2.0.2</ows:Value>
         <ows:Value>http://www.opengis.net/cat/csw/csdgm</ows:Value>
-      </ows:Parameter>
-      <ows:Parameter name="CONSTRAINTLANGUAGE">
-        <ows:Value>FILTER</ows:Value>
-        <ows:Value>CQL_TEXT</ows:Value>
+        <ows:Value>http://www.w3.org/2005/Atom</ows:Value>
       </ows:Parameter>
       <ows:Parameter name="resultType">
         <ows:Value>hits</ows:Value>
@@ -161,91 +137,119 @@
         <ows:Value>csw:Record</ows:Value>
         <ows:Value>gmd:MD_Metadata</ows:Value>
       </ows:Parameter>
-      <ows:Parameter name="ElementSetName">
-        <ows:Value>brief</ows:Value>
-        <ows:Value>summary</ows:Value>
-        <ows:Value>full</ows:Value>
-      </ows:Parameter>
-      <ows:Constraint name="SupportedISOQueryables">
-        <ows:Value>apiso:DistanceValue</ows:Value>
-        <ows:Value>apiso:Abstract</ows:Value>
-        <ows:Value>apiso:RevisionDate</ows:Value>
-        <ows:Value>apiso:Subject</ows:Value>
-        <ows:Value>apiso:KeywordType</ows:Value>
-        <ows:Value>apiso:Title</ows:Value>
-        <ows:Value>apiso:CRS</ows:Value>
-        <ows:Value>apiso:PublicationDate</ows:Value>
-        <ows:Value>apiso:Type</ows:Value>
-        <ows:Value>apiso:AlternateTitle</ows:Value>
-        <ows:Value>apiso:BoundingBox</ows:Value>
-        <ows:Value>apiso:AnyText</ows:Value>
-        <ows:Value>apiso:ParentIdentifier</ows:Value>
-        <ows:Value>apiso:Modified</ows:Value>
-        <ows:Value>apiso:Operation</ows:Value>
-        <ows:Value>apiso:Format</ows:Value>
-        <ows:Value>apiso:TempExtent_end</ows:Value>
-        <ows:Value>apiso:DistanceUOM</ows:Value>
-        <ows:Value>apiso:OrganisationName</ows:Value>
-        <ows:Value>apiso:ServiceType</ows:Value>
-        <ows:Value>apiso:TempExtent_begin</ows:Value>
-        <ows:Value>apiso:ResourceLanguage</ows:Value>
-        <ows:Value>apiso:ServiceTypeVersion</ows:Value>
-        <ows:Value>apiso:OperatesOn</ows:Value>
-        <ows:Value>apiso:Denominator</ows:Value>
-        <ows:Value>apiso:HasSecurityConstraints</ows:Value>
-        <ows:Value>apiso:OperatesOnIdentifier</ows:Value>
-        <ows:Value>apiso:GeographicDescriptionCode</ows:Value>
-        <ows:Value>apiso:Language</ows:Value>
-        <ows:Value>apiso:Identifier</ows:Value>
-        <ows:Value>apiso:OperatesOnName</ows:Value>
-        <ows:Value>apiso:TopicCategory</ows:Value>
-        <ows:Value>apiso:CreationDate</ows:Value>
-        <ows:Value>apiso:CouplingType</ows:Value>
-      </ows:Constraint>
       <ows:Constraint name="AdditionalQueryables">
-        <ows:Value>apiso:Lineage</ows:Value>
+        <ows:Value>apiso:AccessConstraints</ows:Value>
         <ows:Value>apiso:Classification</ows:Value>
+        <ows:Value>apiso:ConditionApplyingToAccessAndUse</ows:Value>
+        <ows:Value>apiso:Contributor</ows:Value>
         <ows:Value>apiso:Creator</ows:Value>
-        <ows:Value>apiso:Relation</ows:Value>
+        <ows:Value>apiso:Degree</ows:Value>
+        <ows:Value>apiso:Lineage</ows:Value>
         <ows:Value>apiso:OtherConstraints</ows:Value>
-        <ows:Value>apiso:SpecificationTitle</ows:Value>
+        <ows:Value>apiso:Publisher</ows:Value>
+        <ows:Value>apiso:Relation</ows:Value>
         <ows:Value>apiso:ResponsiblePartyRole</ows:Value>
-        <ows:Value>apiso:SpecificationDateType</ows:Value>
-        <ows:Value>apiso:Degree</ows:Value>
-        <ows:Value>apiso:Contributor</ows:Value>
-        <ows:Value>apiso:ConditionApplyingToAccessAndUse</ows:Value>
         <ows:Value>apiso:SpecificationDate</ows:Value>
-        <ows:Value>apiso:AccessConstraints</ows:Value>
-        <ows:Value>apiso:Publisher</ows:Value>
+        <ows:Value>apiso:SpecificationDateType</ows:Value>
+        <ows:Value>apiso:SpecificationTitle</ows:Value>
       </ows:Constraint>
       <ows:Constraint name="SupportedDublinCoreQueryables">
+        <ows:Value>csw:AnyText</ows:Value>
         <ows:Value>dc:contributor</ows:Value>
-        <ows:Value>dc:source</ows:Value>
-        <ows:Value>dc:language</ows:Value>
-        <ows:Value>dc:title</ows:Value>
-        <ows:Value>dc:subject</ows:Value>
         <ows:Value>dc:creator</ows:Value>
-        <ows:Value>dc:type</ows:Value>
-        <ows:Value>ows:BoundingBox</ows:Value>
-        <ows:Value>dct:modified</ows:Value>
-        <ows:Value>dct:abstract</ows:Value>
-        <ows:Value>dc:relation</ows:Value>
         <ows:Value>dc:date</ows:Value>
+        <ows:Value>dc:format</ows:Value>
         <ows:Value>dc:identifier</ows:Value>
+        <ows:Value>dc:language</ows:Value>
         <ows:Value>dc:publisher</ows:Value>
-        <ows:Value>dc:format</ows:Value>
-        <ows:Value>csw:AnyText</ows:Value>
+        <ows:Value>dc:relation</ows:Value>
         <ows:Value>dc:rights</ows:Value>
+        <ows:Value>dc:source</ows:Value>
+        <ows:Value>dc:subject</ows:Value>
+        <ows:Value>dc:title</ows:Value>
+        <ows:Value>dc:type</ows:Value>
+        <ows:Value>dct:abstract</ows:Value>
+        <ows:Value>dct:modified</ows:Value>
+        <ows:Value>ows:BoundingBox</ows:Value>
+      </ows:Constraint>
+      <ows:Constraint name="SupportedISOQueryables">
+        <ows:Value>apiso:Abstract</ows:Value>
+        <ows:Value>apiso:AlternateTitle</ows:Value>
+        <ows:Value>apiso:AnyText</ows:Value>
+        <ows:Value>apiso:BoundingBox</ows:Value>
+        <ows:Value>apiso:CRS</ows:Value>
+        <ows:Value>apiso:CouplingType</ows:Value>
+        <ows:Value>apiso:CreationDate</ows:Value>
+        <ows:Value>apiso:Denominator</ows:Value>
+        <ows:Value>apiso:DistanceUOM</ows:Value>
+        <ows:Value>apiso:DistanceValue</ows:Value>
+        <ows:Value>apiso:Format</ows:Value>
+        <ows:Value>apiso:GeographicDescriptionCode</ows:Value>
+        <ows:Value>apiso:HasSecurityConstraints</ows:Value>
+        <ows:Value>apiso:Identifier</ows:Value>
+        <ows:Value>apiso:KeywordType</ows:Value>
+        <ows:Value>apiso:Language</ows:Value>
+        <ows:Value>apiso:Modified</ows:Value>
+        <ows:Value>apiso:OperatesOn</ows:Value>
+        <ows:Value>apiso:OperatesOnIdentifier</ows:Value>
+        <ows:Value>apiso:OperatesOnName</ows:Value>
+        <ows:Value>apiso:Operation</ows:Value>
+        <ows:Value>apiso:OrganisationName</ows:Value>
+        <ows:Value>apiso:ParentIdentifier</ows:Value>
+        <ows:Value>apiso:PublicationDate</ows:Value>
+        <ows:Value>apiso:ResourceLanguage</ows:Value>
+        <ows:Value>apiso:RevisionDate</ows:Value>
+        <ows:Value>apiso:ServiceType</ows:Value>
+        <ows:Value>apiso:ServiceTypeVersion</ows:Value>
+        <ows:Value>apiso:Subject</ows:Value>
+        <ows:Value>apiso:TempExtent_begin</ows:Value>
+        <ows:Value>apiso:TempExtent_end</ows:Value>
+        <ows:Value>apiso:Title</ows:Value>
+        <ows:Value>apiso:TopicCategory</ows:Value>
+        <ows:Value>apiso:Type</ows:Value>
       </ows:Constraint>
     </ows:Operation>
-    <ows:Parameter name="version">
-      <ows:Value>2.0.2</ows:Value>
-    </ows:Parameter>
+    <ows:Operation name="GetRecordById">
+      <ows:DCP>
+        <ows:HTTP>
+          <ows:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/apiso-inspire/default.cfg"/>
+          <ows:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/apiso-inspire/default.cfg"/>
+        </ows:HTTP>
+      </ows:DCP>
+      <ows:Parameter name="ElementSetName">
+        <ows:Value>brief</ows:Value>
+        <ows:Value>full</ows:Value>
+        <ows:Value>summary</ows:Value>
+      </ows:Parameter>
+      <ows:Parameter name="outputFormat">
+        <ows:Value>application/json</ows:Value>
+        <ows:Value>application/xml</ows:Value>
+      </ows:Parameter>
+      <ows:Parameter name="outputSchema">
+        <ows:Value>http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/</ows:Value>
+        <ows:Value>http://www.interlis.ch/INTERLIS2.3</ows:Value>
+        <ows:Value>http://www.isotc211.org/2005/gmd</ows:Value>
+        <ows:Value>http://www.opengis.net/cat/csw/2.0.2</ows:Value>
+        <ows:Value>http://www.opengis.net/cat/csw/csdgm</ows:Value>
+        <ows:Value>http://www.w3.org/2005/Atom</ows:Value>
+      </ows:Parameter>
+    </ows:Operation>
+    <ows:Operation name="GetRepositoryItem">
+      <ows:DCP>
+        <ows:HTTP>
+          <ows:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/apiso-inspire/default.cfg"/>
+        </ows:HTTP>
+      </ows:DCP>
+    </ows:Operation>
     <ows:Parameter name="service">
       <ows:Value>CSW</ows:Value>
     </ows:Parameter>
-    <ows:Constraint name="XPathQueryables">
-      <ows:Value>allowed</ows:Value>
+    <ows:Parameter name="version">
+      <ows:Value>2.0.2</ows:Value>
+      <ows:Value>3.0.0</ows:Value>
+    </ows:Parameter>
+    <ows:Constraint name="FederatedCatalogues">
+      <ows:Value>http://geo.data.gov/geoportal/csw/discovery</ows:Value>
     </ows:Constraint>
     <ows:Constraint name="MaxRecordDefault">
       <ows:Value>10</ows:Value>
@@ -254,8 +258,8 @@
       <ows:Value>XML</ows:Value>
       <ows:Value>SOAP</ows:Value>
     </ows:Constraint>
-    <ows:Constraint name="FederatedCatalogues">
-      <ows:Value>http://geo.data.gov/geoportal/csw/discovery</ows:Value>
+    <ows:Constraint name="XPathQueryables">
+      <ows:Value>allowed</ows:Value>
     </ows:Constraint>
     <inspire_ds:ExtendedCapabilities xsi:schemaLocation="http://inspire.ec.europa.eu/schemas/inspire_ds/1.0 http://inspire.ec.europa.eu/schemas/inspire_ds/1.0/inspire_ds.xsd">
       <inspire_common:ResourceLocator>
@@ -342,11 +346,11 @@
       <ogc:ComparisonOperators>
         <ogc:ComparisonOperator>Between</ogc:ComparisonOperator>
         <ogc:ComparisonOperator>EqualTo</ogc:ComparisonOperator>
-        <ogc:ComparisonOperator>LessThanEqualTo</ogc:ComparisonOperator>
         <ogc:ComparisonOperator>GreaterThan</ogc:ComparisonOperator>
-        <ogc:ComparisonOperator>Like</ogc:ComparisonOperator>
-        <ogc:ComparisonOperator>LessThan</ogc:ComparisonOperator>
         <ogc:ComparisonOperator>GreaterThanEqualTo</ogc:ComparisonOperator>
+        <ogc:ComparisonOperator>LessThan</ogc:ComparisonOperator>
+        <ogc:ComparisonOperator>LessThanEqualTo</ogc:ComparisonOperator>
+        <ogc:ComparisonOperator>Like</ogc:ComparisonOperator>
         <ogc:ComparisonOperator>NotEqualTo</ogc:ComparisonOperator>
         <ogc:ComparisonOperator>NullCheck</ogc:ComparisonOperator>
       </ogc:ComparisonOperators>
diff --git a/tests/expected/suites_apiso-inspire_get_GetCapabilities.xml b/tests/expected/suites_apiso-inspire_get_GetCapabilities.xml
index 645e362..6ecec21 100644
--- a/tests/expected/suites_apiso-inspire_get_GetCapabilities.xml
+++ b/tests/expected/suites_apiso-inspire_get_GetCapabilities.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<csw:Capabilities xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:inspire_common="http://inspire.ec.europa.eu/schemas/common/1.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dct="http://purl.org/dc/terms/" xmlns:ows="http://www.opengis.net/ows" xmlns:apiso="http://www.opengis.net/cat/csw/apiso/1.0" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns: [...]
+<csw:Capabilities xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:inspire_common="http://inspire.ec.europa.eu/schemas/common/1.0" xmlns:inspire_ds="http://inspire.ec.europa.eu/schemas/inspire_ds/1.0" xmlns:ogc="http://www.opengis.net/ogc" xmlns:ows="http://www.opengis.net/ows" xmlns:xlink="http://www.w3.org/1999/xlink [...]
   <ows:ServiceIdentification>
     <ows:Title>pycsw Geospatial Catalogue</ows:Title>
     <ows:Abstract>pycsw is an OGC CSW server implementation written in Python</ows:Abstract>
@@ -11,6 +11,7 @@
     </ows:Keywords>
     <ows:ServiceType codeSpace="OGC">CSW</ows:ServiceType>
     <ows:ServiceTypeVersion>2.0.2</ows:ServiceTypeVersion>
+    <ows:ServiceTypeVersion>3.0.0</ows:ServiceTypeVersion>
     <ows:Fees>None</ows:Fees>
     <ows:AccessConstraints>None</ows:AccessConstraints>
   </ows:ServiceIdentification>
@@ -49,19 +50,12 @@
         </ows:HTTP>
       </ows:DCP>
       <ows:Parameter name="sections">
+        <ows:Value>Filter_Capabilities</ows:Value>
+        <ows:Value>OperationsMetadata</ows:Value>
         <ows:Value>ServiceIdentification</ows:Value>
         <ows:Value>ServiceProvider</ows:Value>
-        <ows:Value>OperationsMetadata</ows:Value>
-        <ows:Value>Filter_Capabilities</ows:Value>
       </ows:Parameter>
     </ows:Operation>
-    <ows:Operation name="GetRepositoryItem">
-      <ows:DCP>
-        <ows:HTTP>
-          <ows:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/apiso-inspire/default.cfg"/>
-        </ows:HTTP>
-      </ows:DCP>
-    </ows:Operation>
     <ows:Operation name="DescribeRecord">
       <ows:DCP>
         <ows:HTTP>
@@ -69,14 +63,14 @@
           <ows:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/apiso-inspire/default.cfg"/>
         </ows:HTTP>
       </ows:DCP>
-      <ows:Parameter name="schemaLanguage">
-        <ows:Value>http://www.w3.org/XML/Schema</ows:Value>
-        <ows:Value>http://www.w3.org/TR/xmlschema-1/</ows:Value>
-        <ows:Value>http://www.w3.org/2001/XMLSchema</ows:Value>
-      </ows:Parameter>
       <ows:Parameter name="outputFormat">
-        <ows:Value>application/xml</ows:Value>
         <ows:Value>application/json</ows:Value>
+        <ows:Value>application/xml</ows:Value>
+      </ows:Parameter>
+      <ows:Parameter name="schemaLanguage">
+        <ows:Value>http://www.w3.org/2001/XMLSchema</ows:Value>
+        <ows:Value>http://www.w3.org/TR/xmlschema-1/</ows:Value>
+        <ows:Value>http://www.w3.org/XML/Schema</ows:Value>
       </ows:Parameter>
       <ows:Parameter name="typeName">
         <ows:Value>csw:Record</ows:Value>
@@ -91,66 +85,48 @@
         </ows:HTTP>
       </ows:DCP>
       <ows:Parameter name="ParameterName">
+        <ows:Value>DescribeRecord.outputFormat</ows:Value>
+        <ows:Value>DescribeRecord.schemaLanguage</ows:Value>
+        <ows:Value>DescribeRecord.typeName</ows:Value>
+        <ows:Value>GetCapabilities.sections</ows:Value>
+        <ows:Value>GetRecordById.ElementSetName</ows:Value>
+        <ows:Value>GetRecordById.outputFormat</ows:Value>
+        <ows:Value>GetRecordById.outputSchema</ows:Value>
+        <ows:Value>GetRecords.CONSTRAINTLANGUAGE</ows:Value>
+        <ows:Value>GetRecords.ElementSetName</ows:Value>
         <ows:Value>GetRecords.outputFormat</ows:Value>
         <ows:Value>GetRecords.outputSchema</ows:Value>
-        <ows:Value>GetRecords.CONSTRAINTLANGUAGE</ows:Value>
         <ows:Value>GetRecords.resultType</ows:Value>
         <ows:Value>GetRecords.typeNames</ows:Value>
-        <ows:Value>GetRecords.ElementSetName</ows:Value>
-        <ows:Value>GetCapabilities.sections</ows:Value>
-        <ows:Value>GetRecordById.outputFormat</ows:Value>
-        <ows:Value>GetRecordById.outputSchema</ows:Value>
-        <ows:Value>GetRecordById.ElementSetName</ows:Value>
-        <ows:Value>DescribeRecord.schemaLanguage</ows:Value>
-        <ows:Value>DescribeRecord.outputFormat</ows:Value>
-        <ows:Value>DescribeRecord.typeName</ows:Value>
       </ows:Parameter>
     </ows:Operation>
-    <ows:Operation name="GetRecordById">
+    <ows:Operation name="GetRecords">
       <ows:DCP>
         <ows:HTTP>
           <ows:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/apiso-inspire/default.cfg"/>
           <ows:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/apiso-inspire/default.cfg"/>
         </ows:HTTP>
       </ows:DCP>
-      <ows:Parameter name="outputFormat">
-        <ows:Value>application/xml</ows:Value>
-        <ows:Value>application/json</ows:Value>
-      </ows:Parameter>
-      <ows:Parameter name="outputSchema">
-        <ows:Value>http://www.opengis.net/cat/csw/2.0.2</ows:Value>
-        <ows:Value>http://www.isotc211.org/2005/gmd</ows:Value>
-        <ows:Value>http://www.w3.org/2005/Atom</ows:Value>
-        <ows:Value>http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/</ows:Value>
-        <ows:Value>http://www.opengis.net/cat/csw/csdgm</ows:Value>
+      <ows:Parameter name="CONSTRAINTLANGUAGE">
+        <ows:Value>CQL_TEXT</ows:Value>
+        <ows:Value>FILTER</ows:Value>
       </ows:Parameter>
       <ows:Parameter name="ElementSetName">
         <ows:Value>brief</ows:Value>
-        <ows:Value>summary</ows:Value>
         <ows:Value>full</ows:Value>
+        <ows:Value>summary</ows:Value>
       </ows:Parameter>
-    </ows:Operation>
-    <ows:Operation name="GetRecords">
-      <ows:DCP>
-        <ows:HTTP>
-          <ows:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/apiso-inspire/default.cfg"/>
-          <ows:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/apiso-inspire/default.cfg"/>
-        </ows:HTTP>
-      </ows:DCP>
       <ows:Parameter name="outputFormat">
-        <ows:Value>application/xml</ows:Value>
         <ows:Value>application/json</ows:Value>
+        <ows:Value>application/xml</ows:Value>
       </ows:Parameter>
       <ows:Parameter name="outputSchema">
-        <ows:Value>http://www.opengis.net/cat/csw/2.0.2</ows:Value>
-        <ows:Value>http://www.isotc211.org/2005/gmd</ows:Value>
-        <ows:Value>http://www.w3.org/2005/Atom</ows:Value>
         <ows:Value>http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/</ows:Value>
+        <ows:Value>http://www.interlis.ch/INTERLIS2.3</ows:Value>
+        <ows:Value>http://www.isotc211.org/2005/gmd</ows:Value>
+        <ows:Value>http://www.opengis.net/cat/csw/2.0.2</ows:Value>
         <ows:Value>http://www.opengis.net/cat/csw/csdgm</ows:Value>
-      </ows:Parameter>
-      <ows:Parameter name="CONSTRAINTLANGUAGE">
-        <ows:Value>FILTER</ows:Value>
-        <ows:Value>CQL_TEXT</ows:Value>
+        <ows:Value>http://www.w3.org/2005/Atom</ows:Value>
       </ows:Parameter>
       <ows:Parameter name="resultType">
         <ows:Value>hits</ows:Value>
@@ -161,91 +137,119 @@
         <ows:Value>csw:Record</ows:Value>
         <ows:Value>gmd:MD_Metadata</ows:Value>
       </ows:Parameter>
-      <ows:Parameter name="ElementSetName">
-        <ows:Value>brief</ows:Value>
-        <ows:Value>summary</ows:Value>
-        <ows:Value>full</ows:Value>
-      </ows:Parameter>
-      <ows:Constraint name="SupportedISOQueryables">
-        <ows:Value>apiso:DistanceValue</ows:Value>
-        <ows:Value>apiso:Abstract</ows:Value>
-        <ows:Value>apiso:RevisionDate</ows:Value>
-        <ows:Value>apiso:Subject</ows:Value>
-        <ows:Value>apiso:KeywordType</ows:Value>
-        <ows:Value>apiso:Title</ows:Value>
-        <ows:Value>apiso:CRS</ows:Value>
-        <ows:Value>apiso:PublicationDate</ows:Value>
-        <ows:Value>apiso:Type</ows:Value>
-        <ows:Value>apiso:AlternateTitle</ows:Value>
-        <ows:Value>apiso:BoundingBox</ows:Value>
-        <ows:Value>apiso:AnyText</ows:Value>
-        <ows:Value>apiso:ParentIdentifier</ows:Value>
-        <ows:Value>apiso:Modified</ows:Value>
-        <ows:Value>apiso:Operation</ows:Value>
-        <ows:Value>apiso:Format</ows:Value>
-        <ows:Value>apiso:TempExtent_end</ows:Value>
-        <ows:Value>apiso:DistanceUOM</ows:Value>
-        <ows:Value>apiso:OrganisationName</ows:Value>
-        <ows:Value>apiso:ServiceType</ows:Value>
-        <ows:Value>apiso:TempExtent_begin</ows:Value>
-        <ows:Value>apiso:ResourceLanguage</ows:Value>
-        <ows:Value>apiso:ServiceTypeVersion</ows:Value>
-        <ows:Value>apiso:OperatesOn</ows:Value>
-        <ows:Value>apiso:Denominator</ows:Value>
-        <ows:Value>apiso:HasSecurityConstraints</ows:Value>
-        <ows:Value>apiso:OperatesOnIdentifier</ows:Value>
-        <ows:Value>apiso:GeographicDescriptionCode</ows:Value>
-        <ows:Value>apiso:Language</ows:Value>
-        <ows:Value>apiso:Identifier</ows:Value>
-        <ows:Value>apiso:OperatesOnName</ows:Value>
-        <ows:Value>apiso:TopicCategory</ows:Value>
-        <ows:Value>apiso:CreationDate</ows:Value>
-        <ows:Value>apiso:CouplingType</ows:Value>
-      </ows:Constraint>
       <ows:Constraint name="AdditionalQueryables">
-        <ows:Value>apiso:Lineage</ows:Value>
+        <ows:Value>apiso:AccessConstraints</ows:Value>
         <ows:Value>apiso:Classification</ows:Value>
+        <ows:Value>apiso:ConditionApplyingToAccessAndUse</ows:Value>
+        <ows:Value>apiso:Contributor</ows:Value>
         <ows:Value>apiso:Creator</ows:Value>
-        <ows:Value>apiso:Relation</ows:Value>
+        <ows:Value>apiso:Degree</ows:Value>
+        <ows:Value>apiso:Lineage</ows:Value>
         <ows:Value>apiso:OtherConstraints</ows:Value>
-        <ows:Value>apiso:SpecificationTitle</ows:Value>
+        <ows:Value>apiso:Publisher</ows:Value>
+        <ows:Value>apiso:Relation</ows:Value>
         <ows:Value>apiso:ResponsiblePartyRole</ows:Value>
-        <ows:Value>apiso:SpecificationDateType</ows:Value>
-        <ows:Value>apiso:Degree</ows:Value>
-        <ows:Value>apiso:Contributor</ows:Value>
-        <ows:Value>apiso:ConditionApplyingToAccessAndUse</ows:Value>
         <ows:Value>apiso:SpecificationDate</ows:Value>
-        <ows:Value>apiso:AccessConstraints</ows:Value>
-        <ows:Value>apiso:Publisher</ows:Value>
+        <ows:Value>apiso:SpecificationDateType</ows:Value>
+        <ows:Value>apiso:SpecificationTitle</ows:Value>
       </ows:Constraint>
       <ows:Constraint name="SupportedDublinCoreQueryables">
+        <ows:Value>csw:AnyText</ows:Value>
         <ows:Value>dc:contributor</ows:Value>
-        <ows:Value>dc:source</ows:Value>
-        <ows:Value>dc:language</ows:Value>
-        <ows:Value>dc:title</ows:Value>
-        <ows:Value>dc:subject</ows:Value>
         <ows:Value>dc:creator</ows:Value>
-        <ows:Value>dc:type</ows:Value>
-        <ows:Value>ows:BoundingBox</ows:Value>
-        <ows:Value>dct:modified</ows:Value>
-        <ows:Value>dct:abstract</ows:Value>
-        <ows:Value>dc:relation</ows:Value>
         <ows:Value>dc:date</ows:Value>
+        <ows:Value>dc:format</ows:Value>
         <ows:Value>dc:identifier</ows:Value>
+        <ows:Value>dc:language</ows:Value>
         <ows:Value>dc:publisher</ows:Value>
-        <ows:Value>dc:format</ows:Value>
-        <ows:Value>csw:AnyText</ows:Value>
+        <ows:Value>dc:relation</ows:Value>
         <ows:Value>dc:rights</ows:Value>
+        <ows:Value>dc:source</ows:Value>
+        <ows:Value>dc:subject</ows:Value>
+        <ows:Value>dc:title</ows:Value>
+        <ows:Value>dc:type</ows:Value>
+        <ows:Value>dct:abstract</ows:Value>
+        <ows:Value>dct:modified</ows:Value>
+        <ows:Value>ows:BoundingBox</ows:Value>
+      </ows:Constraint>
+      <ows:Constraint name="SupportedISOQueryables">
+        <ows:Value>apiso:Abstract</ows:Value>
+        <ows:Value>apiso:AlternateTitle</ows:Value>
+        <ows:Value>apiso:AnyText</ows:Value>
+        <ows:Value>apiso:BoundingBox</ows:Value>
+        <ows:Value>apiso:CRS</ows:Value>
+        <ows:Value>apiso:CouplingType</ows:Value>
+        <ows:Value>apiso:CreationDate</ows:Value>
+        <ows:Value>apiso:Denominator</ows:Value>
+        <ows:Value>apiso:DistanceUOM</ows:Value>
+        <ows:Value>apiso:DistanceValue</ows:Value>
+        <ows:Value>apiso:Format</ows:Value>
+        <ows:Value>apiso:GeographicDescriptionCode</ows:Value>
+        <ows:Value>apiso:HasSecurityConstraints</ows:Value>
+        <ows:Value>apiso:Identifier</ows:Value>
+        <ows:Value>apiso:KeywordType</ows:Value>
+        <ows:Value>apiso:Language</ows:Value>
+        <ows:Value>apiso:Modified</ows:Value>
+        <ows:Value>apiso:OperatesOn</ows:Value>
+        <ows:Value>apiso:OperatesOnIdentifier</ows:Value>
+        <ows:Value>apiso:OperatesOnName</ows:Value>
+        <ows:Value>apiso:Operation</ows:Value>
+        <ows:Value>apiso:OrganisationName</ows:Value>
+        <ows:Value>apiso:ParentIdentifier</ows:Value>
+        <ows:Value>apiso:PublicationDate</ows:Value>
+        <ows:Value>apiso:ResourceLanguage</ows:Value>
+        <ows:Value>apiso:RevisionDate</ows:Value>
+        <ows:Value>apiso:ServiceType</ows:Value>
+        <ows:Value>apiso:ServiceTypeVersion</ows:Value>
+        <ows:Value>apiso:Subject</ows:Value>
+        <ows:Value>apiso:TempExtent_begin</ows:Value>
+        <ows:Value>apiso:TempExtent_end</ows:Value>
+        <ows:Value>apiso:Title</ows:Value>
+        <ows:Value>apiso:TopicCategory</ows:Value>
+        <ows:Value>apiso:Type</ows:Value>
       </ows:Constraint>
     </ows:Operation>
-    <ows:Parameter name="version">
-      <ows:Value>2.0.2</ows:Value>
-    </ows:Parameter>
+    <ows:Operation name="GetRecordById">
+      <ows:DCP>
+        <ows:HTTP>
+          <ows:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/apiso-inspire/default.cfg"/>
+          <ows:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/apiso-inspire/default.cfg"/>
+        </ows:HTTP>
+      </ows:DCP>
+      <ows:Parameter name="ElementSetName">
+        <ows:Value>brief</ows:Value>
+        <ows:Value>full</ows:Value>
+        <ows:Value>summary</ows:Value>
+      </ows:Parameter>
+      <ows:Parameter name="outputFormat">
+        <ows:Value>application/json</ows:Value>
+        <ows:Value>application/xml</ows:Value>
+      </ows:Parameter>
+      <ows:Parameter name="outputSchema">
+        <ows:Value>http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/</ows:Value>
+        <ows:Value>http://www.interlis.ch/INTERLIS2.3</ows:Value>
+        <ows:Value>http://www.isotc211.org/2005/gmd</ows:Value>
+        <ows:Value>http://www.opengis.net/cat/csw/2.0.2</ows:Value>
+        <ows:Value>http://www.opengis.net/cat/csw/csdgm</ows:Value>
+        <ows:Value>http://www.w3.org/2005/Atom</ows:Value>
+      </ows:Parameter>
+    </ows:Operation>
+    <ows:Operation name="GetRepositoryItem">
+      <ows:DCP>
+        <ows:HTTP>
+          <ows:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/apiso-inspire/default.cfg"/>
+        </ows:HTTP>
+      </ows:DCP>
+    </ows:Operation>
     <ows:Parameter name="service">
       <ows:Value>CSW</ows:Value>
     </ows:Parameter>
-    <ows:Constraint name="XPathQueryables">
-      <ows:Value>allowed</ows:Value>
+    <ows:Parameter name="version">
+      <ows:Value>2.0.2</ows:Value>
+      <ows:Value>3.0.0</ows:Value>
+    </ows:Parameter>
+    <ows:Constraint name="FederatedCatalogues">
+      <ows:Value>http://geo.data.gov/geoportal/csw/discovery</ows:Value>
     </ows:Constraint>
     <ows:Constraint name="MaxRecordDefault">
       <ows:Value>10</ows:Value>
@@ -254,8 +258,8 @@
       <ows:Value>XML</ows:Value>
       <ows:Value>SOAP</ows:Value>
     </ows:Constraint>
-    <ows:Constraint name="FederatedCatalogues">
-      <ows:Value>http://geo.data.gov/geoportal/csw/discovery</ows:Value>
+    <ows:Constraint name="XPathQueryables">
+      <ows:Value>allowed</ows:Value>
     </ows:Constraint>
     <inspire_ds:ExtendedCapabilities xsi:schemaLocation="http://inspire.ec.europa.eu/schemas/inspire_ds/1.0 http://inspire.ec.europa.eu/schemas/inspire_ds/1.0/inspire_ds.xsd">
       <inspire_common:ResourceLocator>
@@ -342,11 +346,11 @@
       <ogc:ComparisonOperators>
         <ogc:ComparisonOperator>Between</ogc:ComparisonOperator>
         <ogc:ComparisonOperator>EqualTo</ogc:ComparisonOperator>
-        <ogc:ComparisonOperator>LessThanEqualTo</ogc:ComparisonOperator>
         <ogc:ComparisonOperator>GreaterThan</ogc:ComparisonOperator>
-        <ogc:ComparisonOperator>Like</ogc:ComparisonOperator>
-        <ogc:ComparisonOperator>LessThan</ogc:ComparisonOperator>
         <ogc:ComparisonOperator>GreaterThanEqualTo</ogc:ComparisonOperator>
+        <ogc:ComparisonOperator>LessThan</ogc:ComparisonOperator>
+        <ogc:ComparisonOperator>LessThanEqualTo</ogc:ComparisonOperator>
+        <ogc:ComparisonOperator>Like</ogc:ComparisonOperator>
         <ogc:ComparisonOperator>NotEqualTo</ogc:ComparisonOperator>
         <ogc:ComparisonOperator>NullCheck</ogc:ComparisonOperator>
       </ogc:ComparisonOperators>
diff --git a/tests/expected/suites_apiso_post_DescribeRecord.xml b/tests/expected/suites_apiso_post_DescribeRecord.xml
index 74f2d33..bda19c0 100644
--- a/tests/expected/suites_apiso_post_DescribeRecord.xml
+++ b/tests/expected/suites_apiso_post_DescribeRecord.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<csw:DescribeRecordResponse xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:inspire_common="http://inspire.ec.europa.eu/schemas/common/1.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dct="http://purl.org/dc/terms/" xmlns:ows="http://www.opengis.net/ows" xmlns:apiso="http://www.opengis.net/cat/csw/apiso/1.0" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xlink="http://www.w3.org/1999/xli [...]
+<csw:DescribeRecordResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/cat/csw/2.0.2 http://schemas.opengis.net/csw/2.0.2/CSW-discovery.xsd">
   <csw:SchemaComponent parentSchema="gmd.xsd" schemaLanguage="XMLSCHEMA" targetNamespace="http://www.isotc211.org/2005/gmd">
     <xs:schema targetNamespace="http://www.isotc211.org/2005/gmd" elementFormDefault="qualified" version="0.1">
 	<!-- ================================= Annotation ================================ -->
diff --git a/tests/expected/suites_apiso_post_GetCapabilities.xml b/tests/expected/suites_apiso_post_GetCapabilities.xml
index 13d520c..00656b2 100644
--- a/tests/expected/suites_apiso_post_GetCapabilities.xml
+++ b/tests/expected/suites_apiso_post_GetCapabilities.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<csw:Capabilities xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:inspire_common="http://inspire.ec.europa.eu/schemas/common/1.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dct="http://purl.org/dc/terms/" xmlns:ows="http://www.opengis.net/ows" xmlns:apiso="http://www.opengis.net/cat/csw/apiso/1.0" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns: [...]
+<csw:Capabilities xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ogc="http://www.opengis.net/ogc" xmlns:ows="http://www.opengis.net/ows" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" updateSequence="PYCSW_UPDATESEQUENCE" ve [...]
   <ows:ServiceIdentification>
     <ows:Title>pycsw Geospatial Catalogue</ows:Title>
     <ows:Abstract>pycsw is an OGC CSW server implementation written in Python</ows:Abstract>
@@ -11,6 +11,7 @@
     </ows:Keywords>
     <ows:ServiceType codeSpace="OGC">CSW</ows:ServiceType>
     <ows:ServiceTypeVersion>2.0.2</ows:ServiceTypeVersion>
+    <ows:ServiceTypeVersion>3.0.0</ows:ServiceTypeVersion>
     <ows:Fees>None</ows:Fees>
     <ows:AccessConstraints>None</ows:AccessConstraints>
   </ows:ServiceIdentification>
@@ -49,19 +50,12 @@
         </ows:HTTP>
       </ows:DCP>
       <ows:Parameter name="sections">
+        <ows:Value>Filter_Capabilities</ows:Value>
+        <ows:Value>OperationsMetadata</ows:Value>
         <ows:Value>ServiceIdentification</ows:Value>
         <ows:Value>ServiceProvider</ows:Value>
-        <ows:Value>OperationsMetadata</ows:Value>
-        <ows:Value>Filter_Capabilities</ows:Value>
       </ows:Parameter>
     </ows:Operation>
-    <ows:Operation name="GetRepositoryItem">
-      <ows:DCP>
-        <ows:HTTP>
-          <ows:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/apiso/default.cfg"/>
-        </ows:HTTP>
-      </ows:DCP>
-    </ows:Operation>
     <ows:Operation name="DescribeRecord">
       <ows:DCP>
         <ows:HTTP>
@@ -69,14 +63,14 @@
           <ows:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/apiso/default.cfg"/>
         </ows:HTTP>
       </ows:DCP>
-      <ows:Parameter name="schemaLanguage">
-        <ows:Value>http://www.w3.org/XML/Schema</ows:Value>
-        <ows:Value>http://www.w3.org/TR/xmlschema-1/</ows:Value>
-        <ows:Value>http://www.w3.org/2001/XMLSchema</ows:Value>
-      </ows:Parameter>
       <ows:Parameter name="outputFormat">
-        <ows:Value>application/xml</ows:Value>
         <ows:Value>application/json</ows:Value>
+        <ows:Value>application/xml</ows:Value>
+      </ows:Parameter>
+      <ows:Parameter name="schemaLanguage">
+        <ows:Value>http://www.w3.org/2001/XMLSchema</ows:Value>
+        <ows:Value>http://www.w3.org/TR/xmlschema-1/</ows:Value>
+        <ows:Value>http://www.w3.org/XML/Schema</ows:Value>
       </ows:Parameter>
       <ows:Parameter name="typeName">
         <ows:Value>csw:Record</ows:Value>
@@ -91,66 +85,48 @@
         </ows:HTTP>
       </ows:DCP>
       <ows:Parameter name="ParameterName">
+        <ows:Value>DescribeRecord.outputFormat</ows:Value>
+        <ows:Value>DescribeRecord.schemaLanguage</ows:Value>
+        <ows:Value>DescribeRecord.typeName</ows:Value>
+        <ows:Value>GetCapabilities.sections</ows:Value>
+        <ows:Value>GetRecordById.ElementSetName</ows:Value>
+        <ows:Value>GetRecordById.outputFormat</ows:Value>
+        <ows:Value>GetRecordById.outputSchema</ows:Value>
+        <ows:Value>GetRecords.CONSTRAINTLANGUAGE</ows:Value>
+        <ows:Value>GetRecords.ElementSetName</ows:Value>
         <ows:Value>GetRecords.outputFormat</ows:Value>
         <ows:Value>GetRecords.outputSchema</ows:Value>
-        <ows:Value>GetRecords.CONSTRAINTLANGUAGE</ows:Value>
         <ows:Value>GetRecords.resultType</ows:Value>
         <ows:Value>GetRecords.typeNames</ows:Value>
-        <ows:Value>GetRecords.ElementSetName</ows:Value>
-        <ows:Value>GetCapabilities.sections</ows:Value>
-        <ows:Value>GetRecordById.outputFormat</ows:Value>
-        <ows:Value>GetRecordById.outputSchema</ows:Value>
-        <ows:Value>GetRecordById.ElementSetName</ows:Value>
-        <ows:Value>DescribeRecord.schemaLanguage</ows:Value>
-        <ows:Value>DescribeRecord.outputFormat</ows:Value>
-        <ows:Value>DescribeRecord.typeName</ows:Value>
       </ows:Parameter>
     </ows:Operation>
-    <ows:Operation name="GetRecordById">
+    <ows:Operation name="GetRecords">
       <ows:DCP>
         <ows:HTTP>
           <ows:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/apiso/default.cfg"/>
           <ows:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/apiso/default.cfg"/>
         </ows:HTTP>
       </ows:DCP>
-      <ows:Parameter name="outputFormat">
-        <ows:Value>application/xml</ows:Value>
-        <ows:Value>application/json</ows:Value>
-      </ows:Parameter>
-      <ows:Parameter name="outputSchema">
-        <ows:Value>http://www.opengis.net/cat/csw/2.0.2</ows:Value>
-        <ows:Value>http://www.isotc211.org/2005/gmd</ows:Value>
-        <ows:Value>http://www.w3.org/2005/Atom</ows:Value>
-        <ows:Value>http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/</ows:Value>
-        <ows:Value>http://www.opengis.net/cat/csw/csdgm</ows:Value>
+      <ows:Parameter name="CONSTRAINTLANGUAGE">
+        <ows:Value>CQL_TEXT</ows:Value>
+        <ows:Value>FILTER</ows:Value>
       </ows:Parameter>
       <ows:Parameter name="ElementSetName">
         <ows:Value>brief</ows:Value>
-        <ows:Value>summary</ows:Value>
         <ows:Value>full</ows:Value>
+        <ows:Value>summary</ows:Value>
       </ows:Parameter>
-    </ows:Operation>
-    <ows:Operation name="GetRecords">
-      <ows:DCP>
-        <ows:HTTP>
-          <ows:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/apiso/default.cfg"/>
-          <ows:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/apiso/default.cfg"/>
-        </ows:HTTP>
-      </ows:DCP>
       <ows:Parameter name="outputFormat">
-        <ows:Value>application/xml</ows:Value>
         <ows:Value>application/json</ows:Value>
+        <ows:Value>application/xml</ows:Value>
       </ows:Parameter>
       <ows:Parameter name="outputSchema">
-        <ows:Value>http://www.opengis.net/cat/csw/2.0.2</ows:Value>
-        <ows:Value>http://www.isotc211.org/2005/gmd</ows:Value>
-        <ows:Value>http://www.w3.org/2005/Atom</ows:Value>
         <ows:Value>http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/</ows:Value>
+        <ows:Value>http://www.interlis.ch/INTERLIS2.3</ows:Value>
+        <ows:Value>http://www.isotc211.org/2005/gmd</ows:Value>
+        <ows:Value>http://www.opengis.net/cat/csw/2.0.2</ows:Value>
         <ows:Value>http://www.opengis.net/cat/csw/csdgm</ows:Value>
-      </ows:Parameter>
-      <ows:Parameter name="CONSTRAINTLANGUAGE">
-        <ows:Value>FILTER</ows:Value>
-        <ows:Value>CQL_TEXT</ows:Value>
+        <ows:Value>http://www.w3.org/2005/Atom</ows:Value>
       </ows:Parameter>
       <ows:Parameter name="resultType">
         <ows:Value>hits</ows:Value>
@@ -161,91 +137,119 @@
         <ows:Value>csw:Record</ows:Value>
         <ows:Value>gmd:MD_Metadata</ows:Value>
       </ows:Parameter>
-      <ows:Parameter name="ElementSetName">
-        <ows:Value>brief</ows:Value>
-        <ows:Value>summary</ows:Value>
-        <ows:Value>full</ows:Value>
-      </ows:Parameter>
-      <ows:Constraint name="SupportedISOQueryables">
-        <ows:Value>apiso:DistanceValue</ows:Value>
-        <ows:Value>apiso:Abstract</ows:Value>
-        <ows:Value>apiso:RevisionDate</ows:Value>
-        <ows:Value>apiso:Subject</ows:Value>
-        <ows:Value>apiso:KeywordType</ows:Value>
-        <ows:Value>apiso:Title</ows:Value>
-        <ows:Value>apiso:CRS</ows:Value>
-        <ows:Value>apiso:PublicationDate</ows:Value>
-        <ows:Value>apiso:Type</ows:Value>
-        <ows:Value>apiso:AlternateTitle</ows:Value>
-        <ows:Value>apiso:BoundingBox</ows:Value>
-        <ows:Value>apiso:AnyText</ows:Value>
-        <ows:Value>apiso:ParentIdentifier</ows:Value>
-        <ows:Value>apiso:Modified</ows:Value>
-        <ows:Value>apiso:Operation</ows:Value>
-        <ows:Value>apiso:Format</ows:Value>
-        <ows:Value>apiso:TempExtent_end</ows:Value>
-        <ows:Value>apiso:DistanceUOM</ows:Value>
-        <ows:Value>apiso:OrganisationName</ows:Value>
-        <ows:Value>apiso:ServiceType</ows:Value>
-        <ows:Value>apiso:TempExtent_begin</ows:Value>
-        <ows:Value>apiso:ResourceLanguage</ows:Value>
-        <ows:Value>apiso:ServiceTypeVersion</ows:Value>
-        <ows:Value>apiso:OperatesOn</ows:Value>
-        <ows:Value>apiso:Denominator</ows:Value>
-        <ows:Value>apiso:HasSecurityConstraints</ows:Value>
-        <ows:Value>apiso:OperatesOnIdentifier</ows:Value>
-        <ows:Value>apiso:GeographicDescriptionCode</ows:Value>
-        <ows:Value>apiso:Language</ows:Value>
-        <ows:Value>apiso:Identifier</ows:Value>
-        <ows:Value>apiso:OperatesOnName</ows:Value>
-        <ows:Value>apiso:TopicCategory</ows:Value>
-        <ows:Value>apiso:CreationDate</ows:Value>
-        <ows:Value>apiso:CouplingType</ows:Value>
-      </ows:Constraint>
       <ows:Constraint name="AdditionalQueryables">
-        <ows:Value>apiso:Lineage</ows:Value>
+        <ows:Value>apiso:AccessConstraints</ows:Value>
         <ows:Value>apiso:Classification</ows:Value>
+        <ows:Value>apiso:ConditionApplyingToAccessAndUse</ows:Value>
+        <ows:Value>apiso:Contributor</ows:Value>
         <ows:Value>apiso:Creator</ows:Value>
-        <ows:Value>apiso:Relation</ows:Value>
+        <ows:Value>apiso:Degree</ows:Value>
+        <ows:Value>apiso:Lineage</ows:Value>
         <ows:Value>apiso:OtherConstraints</ows:Value>
-        <ows:Value>apiso:SpecificationTitle</ows:Value>
+        <ows:Value>apiso:Publisher</ows:Value>
+        <ows:Value>apiso:Relation</ows:Value>
         <ows:Value>apiso:ResponsiblePartyRole</ows:Value>
-        <ows:Value>apiso:SpecificationDateType</ows:Value>
-        <ows:Value>apiso:Degree</ows:Value>
-        <ows:Value>apiso:Contributor</ows:Value>
-        <ows:Value>apiso:ConditionApplyingToAccessAndUse</ows:Value>
         <ows:Value>apiso:SpecificationDate</ows:Value>
-        <ows:Value>apiso:AccessConstraints</ows:Value>
-        <ows:Value>apiso:Publisher</ows:Value>
+        <ows:Value>apiso:SpecificationDateType</ows:Value>
+        <ows:Value>apiso:SpecificationTitle</ows:Value>
       </ows:Constraint>
       <ows:Constraint name="SupportedDublinCoreQueryables">
+        <ows:Value>csw:AnyText</ows:Value>
         <ows:Value>dc:contributor</ows:Value>
-        <ows:Value>dc:source</ows:Value>
-        <ows:Value>dc:language</ows:Value>
-        <ows:Value>dc:title</ows:Value>
-        <ows:Value>dc:subject</ows:Value>
         <ows:Value>dc:creator</ows:Value>
-        <ows:Value>dc:type</ows:Value>
-        <ows:Value>ows:BoundingBox</ows:Value>
-        <ows:Value>dct:modified</ows:Value>
-        <ows:Value>dct:abstract</ows:Value>
-        <ows:Value>dc:relation</ows:Value>
         <ows:Value>dc:date</ows:Value>
+        <ows:Value>dc:format</ows:Value>
         <ows:Value>dc:identifier</ows:Value>
+        <ows:Value>dc:language</ows:Value>
         <ows:Value>dc:publisher</ows:Value>
-        <ows:Value>dc:format</ows:Value>
-        <ows:Value>csw:AnyText</ows:Value>
+        <ows:Value>dc:relation</ows:Value>
         <ows:Value>dc:rights</ows:Value>
+        <ows:Value>dc:source</ows:Value>
+        <ows:Value>dc:subject</ows:Value>
+        <ows:Value>dc:title</ows:Value>
+        <ows:Value>dc:type</ows:Value>
+        <ows:Value>dct:abstract</ows:Value>
+        <ows:Value>dct:modified</ows:Value>
+        <ows:Value>ows:BoundingBox</ows:Value>
+      </ows:Constraint>
+      <ows:Constraint name="SupportedISOQueryables">
+        <ows:Value>apiso:Abstract</ows:Value>
+        <ows:Value>apiso:AlternateTitle</ows:Value>
+        <ows:Value>apiso:AnyText</ows:Value>
+        <ows:Value>apiso:BoundingBox</ows:Value>
+        <ows:Value>apiso:CRS</ows:Value>
+        <ows:Value>apiso:CouplingType</ows:Value>
+        <ows:Value>apiso:CreationDate</ows:Value>
+        <ows:Value>apiso:Denominator</ows:Value>
+        <ows:Value>apiso:DistanceUOM</ows:Value>
+        <ows:Value>apiso:DistanceValue</ows:Value>
+        <ows:Value>apiso:Format</ows:Value>
+        <ows:Value>apiso:GeographicDescriptionCode</ows:Value>
+        <ows:Value>apiso:HasSecurityConstraints</ows:Value>
+        <ows:Value>apiso:Identifier</ows:Value>
+        <ows:Value>apiso:KeywordType</ows:Value>
+        <ows:Value>apiso:Language</ows:Value>
+        <ows:Value>apiso:Modified</ows:Value>
+        <ows:Value>apiso:OperatesOn</ows:Value>
+        <ows:Value>apiso:OperatesOnIdentifier</ows:Value>
+        <ows:Value>apiso:OperatesOnName</ows:Value>
+        <ows:Value>apiso:Operation</ows:Value>
+        <ows:Value>apiso:OrganisationName</ows:Value>
+        <ows:Value>apiso:ParentIdentifier</ows:Value>
+        <ows:Value>apiso:PublicationDate</ows:Value>
+        <ows:Value>apiso:ResourceLanguage</ows:Value>
+        <ows:Value>apiso:RevisionDate</ows:Value>
+        <ows:Value>apiso:ServiceType</ows:Value>
+        <ows:Value>apiso:ServiceTypeVersion</ows:Value>
+        <ows:Value>apiso:Subject</ows:Value>
+        <ows:Value>apiso:TempExtent_begin</ows:Value>
+        <ows:Value>apiso:TempExtent_end</ows:Value>
+        <ows:Value>apiso:Title</ows:Value>
+        <ows:Value>apiso:TopicCategory</ows:Value>
+        <ows:Value>apiso:Type</ows:Value>
       </ows:Constraint>
     </ows:Operation>
-    <ows:Parameter name="version">
-      <ows:Value>2.0.2</ows:Value>
-    </ows:Parameter>
+    <ows:Operation name="GetRecordById">
+      <ows:DCP>
+        <ows:HTTP>
+          <ows:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/apiso/default.cfg"/>
+          <ows:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/apiso/default.cfg"/>
+        </ows:HTTP>
+      </ows:DCP>
+      <ows:Parameter name="ElementSetName">
+        <ows:Value>brief</ows:Value>
+        <ows:Value>full</ows:Value>
+        <ows:Value>summary</ows:Value>
+      </ows:Parameter>
+      <ows:Parameter name="outputFormat">
+        <ows:Value>application/json</ows:Value>
+        <ows:Value>application/xml</ows:Value>
+      </ows:Parameter>
+      <ows:Parameter name="outputSchema">
+        <ows:Value>http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/</ows:Value>
+        <ows:Value>http://www.interlis.ch/INTERLIS2.3</ows:Value>
+        <ows:Value>http://www.isotc211.org/2005/gmd</ows:Value>
+        <ows:Value>http://www.opengis.net/cat/csw/2.0.2</ows:Value>
+        <ows:Value>http://www.opengis.net/cat/csw/csdgm</ows:Value>
+        <ows:Value>http://www.w3.org/2005/Atom</ows:Value>
+      </ows:Parameter>
+    </ows:Operation>
+    <ows:Operation name="GetRepositoryItem">
+      <ows:DCP>
+        <ows:HTTP>
+          <ows:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/apiso/default.cfg"/>
+        </ows:HTTP>
+      </ows:DCP>
+    </ows:Operation>
     <ows:Parameter name="service">
       <ows:Value>CSW</ows:Value>
     </ows:Parameter>
-    <ows:Constraint name="XPathQueryables">
-      <ows:Value>allowed</ows:Value>
+    <ows:Parameter name="version">
+      <ows:Value>2.0.2</ows:Value>
+      <ows:Value>3.0.0</ows:Value>
+    </ows:Parameter>
+    <ows:Constraint name="FederatedCatalogues">
+      <ows:Value>http://geo.data.gov/geoportal/csw/discovery</ows:Value>
     </ows:Constraint>
     <ows:Constraint name="MaxRecordDefault">
       <ows:Value>10</ows:Value>
@@ -254,8 +258,8 @@
       <ows:Value>XML</ows:Value>
       <ows:Value>SOAP</ows:Value>
     </ows:Constraint>
-    <ows:Constraint name="FederatedCatalogues">
-      <ows:Value>http://geo.data.gov/geoportal/csw/discovery</ows:Value>
+    <ows:Constraint name="XPathQueryables">
+      <ows:Value>allowed</ows:Value>
     </ows:Constraint>
   </ows:OperationsMetadata>
   <ogc:Filter_Capabilities>
@@ -285,11 +289,11 @@
       <ogc:ComparisonOperators>
         <ogc:ComparisonOperator>Between</ogc:ComparisonOperator>
         <ogc:ComparisonOperator>EqualTo</ogc:ComparisonOperator>
-        <ogc:ComparisonOperator>LessThanEqualTo</ogc:ComparisonOperator>
         <ogc:ComparisonOperator>GreaterThan</ogc:ComparisonOperator>
-        <ogc:ComparisonOperator>Like</ogc:ComparisonOperator>
-        <ogc:ComparisonOperator>LessThan</ogc:ComparisonOperator>
         <ogc:ComparisonOperator>GreaterThanEqualTo</ogc:ComparisonOperator>
+        <ogc:ComparisonOperator>LessThan</ogc:ComparisonOperator>
+        <ogc:ComparisonOperator>LessThanEqualTo</ogc:ComparisonOperator>
+        <ogc:ComparisonOperator>Like</ogc:ComparisonOperator>
         <ogc:ComparisonOperator>NotEqualTo</ogc:ComparisonOperator>
         <ogc:ComparisonOperator>NullCheck</ogc:ComparisonOperator>
       </ogc:ComparisonOperators>
diff --git a/tests/expected/suites_apiso_post_GetDomain-property.xml b/tests/expected/suites_apiso_post_GetDomain-property.xml
index 43be0d0..17c50d7 100644
--- a/tests/expected/suites_apiso_post_GetDomain-property.xml
+++ b/tests/expected/suites_apiso_post_GetDomain-property.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<csw:GetDomainResponse xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:inspire_common="http://inspire.ec.europa.eu/schemas/common/1.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dct="http://purl.org/dc/terms/" xmlns:ows="http://www.opengis.net/ows" xmlns:apiso="http://www.opengis.net/cat/csw/apiso/1.0" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xlink="http://www.w3.org/1999/xlink" x [...]
+<csw:GetDomainResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/cat/csw/2.0.2 http://schemas.opengis.net/csw/2.0.2/CSW-discovery.xsd">
   <csw:DomainValues type="csw:Record">
     <csw:PropertyName>apiso:TopicCategory</csw:PropertyName>
     <csw:ListOfValues>
diff --git a/tests/expected/suites_apiso_post_GetRecordById-brief.xml b/tests/expected/suites_apiso_post_GetRecordById-brief.xml
index 9e345f9..ea58eb9 100644
--- a/tests/expected/suites_apiso_post_GetRecordById-brief.xml
+++ b/tests/expected/suites_apiso_post_GetRecordById-brief.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<csw:GetRecordByIdResponse xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:inspire_common="http://inspire.ec.europa.eu/schemas/common/1.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dct="http://purl.org/dc/terms/" xmlns:ows="http://www.opengis.net/ows" xmlns:apiso="http://www.opengis.net/cat/csw/apiso/1.0" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xlink="http://www.w3.org/1999/xlin [...]
+<csw:GetRecordByIdResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gco="http://www.isotc211.org/2005/gco" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/cat/csw/2.0.2 http://sche [...]
   <gmd:MD_Metadata xsi:schemaLocation="http://www.isotc211.org/2005/gmd http://schemas.opengis.net/csw/2.0.2/profiles/apiso/1.0.0/apiso.xsd">
     <gmd:fileIdentifier>
       <gco:CharacterString>de53e931-778a-4792-94ad-9fe507aca483</gco:CharacterString>
diff --git a/tests/expected/suites_apiso_post_GetRecordById-full-dc.xml b/tests/expected/suites_apiso_post_GetRecordById-full-dc.xml
index 6a2d5d5..155b349 100644
--- a/tests/expected/suites_apiso_post_GetRecordById-full-dc.xml
+++ b/tests/expected/suites_apiso_post_GetRecordById-full-dc.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<csw:GetRecordByIdResponse xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:inspire_common="http://inspire.ec.europa.eu/schemas/common/1.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dct="http://purl.org/dc/terms/" xmlns:ows="http://www.opengis.net/ows" xmlns:apiso="http://www.opengis.net/cat/csw/apiso/1.0" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xlink="http://www.w3.org/1999/xlin [...]
+<csw:GetRecordByIdResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/cat/csw/2.0.2 http://schemas.opengis.net/csw/2.0.2/CSW-discovery.xsd">
   <csw:Record>
     <dc:identifier>NS06agg</dc:identifier>
     <dc:title>PacIOOS Nearshore Sensor 06: Pohnpei, Micronesia</dc:title>
@@ -25,6 +25,7 @@
     <dc:subject>latitude</dc:subject>
     <dc:subject>longitude</dc:subject>
     <dc:subject>time</dc:subject>
+    <dc:subject scheme="http://www.isotc211.org/2005/resources/Codelist/gmxCodelists.xml#MD_TopicCategoryCode">climatologyMeteorologyAtmosphere</dc:subject>
     <dct:references scheme="None">http://oos.soest.hawaii.edu/thredds/idd/nss_pacioos.html?dataset=NS06agg</dct:references>
     <dct:references scheme="WWW:LINK">http://oos.soest.hawaii.edu/thredds/dodsC/pacioos/nss/ns06agg.html</dct:references>
     <dct:references scheme="None">http://pacioos.org/voyager/index.html?b=6.874279%2C158.077126%2C7.050468%2C158.369808&tz=pont&o=qual:2::p0NS06p1</dct:references>
diff --git a/tests/expected/suites_apiso_post_GetRecordById-full.xml b/tests/expected/suites_apiso_post_GetRecordById-full.xml
index c2444a0..6b88e5e 100644
--- a/tests/expected/suites_apiso_post_GetRecordById-full.xml
+++ b/tests/expected/suites_apiso_post_GetRecordById-full.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<csw:GetRecordByIdResponse xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:inspire_common="http://inspire.ec.europa.eu/schemas/common/1.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dct="http://purl.org/dc/terms/" xmlns:ows="http://www.opengis.net/ows" xmlns:apiso="http://www.opengis.net/cat/csw/apiso/1.0" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xlink="http://www.w3.org/1999/xlin [...]
+<csw:GetRecordByIdResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gco="http://www.isotc211.org/2005/gco" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/cat/csw/2.0.2 http://sche [...]
   <gmd:MD_Metadata xsi:schemaLocation="http://www.isotc211.org/2005/gmd http://schemas.opengis.net/iso/19139/20060504/gmd/gmd.xsd">
 	<gmd:fileIdentifier><gco:CharacterString>de53e931-778a-4792-94ad-9fe507aca483</gco:CharacterString></gmd:fileIdentifier>
 	<gmd:language><gmd:LanguageCode codeList="http://standards.iso.org/ittf/PubliclyAvailableStandards/ISO_19139_Schemas/resources/Codelist/ML_gmxCodelists.xml#LanguageCode" codeListValue="eng">eng</gmd:LanguageCode></gmd:language>
diff --git a/tests/expected/suites_apiso_post_GetRecordById-srv-brief.xml b/tests/expected/suites_apiso_post_GetRecordById-srv-brief.xml
index 775b618..896b014 100644
--- a/tests/expected/suites_apiso_post_GetRecordById-srv-brief.xml
+++ b/tests/expected/suites_apiso_post_GetRecordById-srv-brief.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<csw:GetRecordByIdResponse xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:inspire_common="http://inspire.ec.europa.eu/schemas/common/1.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dct="http://purl.org/dc/terms/" xmlns:ows="http://www.opengis.net/ows" xmlns:apiso="http://www.opengis.net/cat/csw/apiso/1.0" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xlink="http://www.w3.org/1999/xlin [...]
+<csw:GetRecordByIdResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gco="http://www.isotc211.org/2005/gco" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:srv="http://www.isotc211.org/2005/srv" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="htt [...]
   <gmd:MD_Metadata xsi:schemaLocation="http://www.isotc211.org/2005/gmd http://schemas.opengis.net/csw/2.0.2/profiles/apiso/1.0.0/apiso.xsd">
     <gmd:fileIdentifier>
       <gco:CharacterString>3e9a8c05</gco:CharacterString>
diff --git a/tests/expected/suites_apiso_post_GetRecords-all-csw-output.xml b/tests/expected/suites_apiso_post_GetRecords-all-csw-output.xml
index 9aea4a3..e428bac 100644
--- a/tests/expected/suites_apiso_post_GetRecords-all-csw-output.xml
+++ b/tests/expected/suites_apiso_post_GetRecords-all-csw-output.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<csw:GetRecordsResponse xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:inspire_common="http://inspire.ec.europa.eu/schemas/common/1.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dct="http://purl.org/dc/terms/" xmlns:ows="http://www.opengis.net/ows" xmlns:apiso="http://www.opengis.net/cat/csw/apiso/1.0" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xlink="http://www.w3.org/1999/xlink"  [...]
+<csw:GetRecordsResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gco="http://www.isotc211.org/2005/gco" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:srv="http://www.isotc211.org/2005/srv" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.0.2" xsi:schema [...]
   <csw:SearchStatus timestamp="PYCSW_TIMESTAMP"/>
   <csw:SearchResults nextRecord="6" numberOfRecordsMatched="17" numberOfRecordsReturned="5" recordSchema="http://www.isotc211.org/2005/gmd" elementSet="full">
     <gmd:MD_Metadata xsi:schemaLocation="http://www.isotc211.org/2005/srv http://schemas.opengis.net/iso/19139/20060504/srv/srv.xsd">
diff --git a/tests/expected/suites_apiso_post_GetRecords-all.xml b/tests/expected/suites_apiso_post_GetRecords-all.xml
index 9aea4a3..e428bac 100644
--- a/tests/expected/suites_apiso_post_GetRecords-all.xml
+++ b/tests/expected/suites_apiso_post_GetRecords-all.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<csw:GetRecordsResponse xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:inspire_common="http://inspire.ec.europa.eu/schemas/common/1.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dct="http://purl.org/dc/terms/" xmlns:ows="http://www.opengis.net/ows" xmlns:apiso="http://www.opengis.net/cat/csw/apiso/1.0" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xlink="http://www.w3.org/1999/xlink"  [...]
+<csw:GetRecordsResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gco="http://www.isotc211.org/2005/gco" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:srv="http://www.isotc211.org/2005/srv" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.0.2" xsi:schema [...]
   <csw:SearchStatus timestamp="PYCSW_TIMESTAMP"/>
   <csw:SearchResults nextRecord="6" numberOfRecordsMatched="17" numberOfRecordsReturned="5" recordSchema="http://www.isotc211.org/2005/gmd" elementSet="full">
     <gmd:MD_Metadata xsi:schemaLocation="http://www.isotc211.org/2005/srv http://schemas.opengis.net/iso/19139/20060504/srv/srv.xsd">
diff --git a/tests/expected/suites_apiso_post_GetRecords-cql-title.xml b/tests/expected/suites_apiso_post_GetRecords-cql-title.xml
index 2b6ebdf..86fd86c 100644
--- a/tests/expected/suites_apiso_post_GetRecords-cql-title.xml
+++ b/tests/expected/suites_apiso_post_GetRecords-cql-title.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<csw:GetRecordsResponse xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:inspire_common="http://inspire.ec.europa.eu/schemas/common/1.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dct="http://purl.org/dc/terms/" xmlns:ows="http://www.opengis.net/ows" xmlns:apiso="http://www.opengis.net/cat/csw/apiso/1.0" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xlink="http://www.w3.org/1999/xlink"  [...]
+<csw:GetRecordsResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gco="http://www.isotc211.org/2005/gco" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.0.2" xsi:schemaLocation="http://www.opengis.net/cat/csw/2.0. [...]
   <csw:SearchStatus timestamp="PYCSW_TIMESTAMP"/>
   <csw:SearchResults nextRecord="0" numberOfRecordsMatched="5" numberOfRecordsReturned="5" recordSchema="http://www.isotc211.org/2005/gmd" elementSet="brief">
     <gmd:MD_Metadata xsi:schemaLocation="http://www.isotc211.org/2005/gmd http://schemas.opengis.net/csw/2.0.2/profiles/apiso/1.0.0/apiso.xsd">
diff --git a/tests/expected/suites_apiso_post_GetRecords-elementname.xml b/tests/expected/suites_apiso_post_GetRecords-elementname.xml
index abb010f..9717597 100644
--- a/tests/expected/suites_apiso_post_GetRecords-elementname.xml
+++ b/tests/expected/suites_apiso_post_GetRecords-elementname.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<csw:GetRecordsResponse xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:inspire_common="http://inspire.ec.europa.eu/schemas/common/1.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dct="http://purl.org/dc/terms/" xmlns:ows="http://www.opengis.net/ows" xmlns:apiso="http://www.opengis.net/cat/csw/apiso/1.0" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xlink="http://www.w3.org/1999/xlink"  [...]
+<csw:GetRecordsResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gco="http://www.isotc211.org/2005/gco" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:srv="http://www.isotc211.org/2005/srv" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.0.2" xsi:schema [...]
   <csw:SearchStatus timestamp="PYCSW_TIMESTAMP"/>
   <csw:SearchResults nextRecord="6" numberOfRecordsMatched="17" numberOfRecordsReturned="5" recordSchema="http://www.isotc211.org/2005/gmd">
     <gmd:MD_Metadata xsi:schemaLocation="http://www.isotc211.org/2005/gmd http://schemas.opengis.net/csw/2.0.2/profiles/apiso/1.0.0/apiso.xsd">
diff --git a/tests/expected/suites_apiso_post_GetRecords-filter-and-nested-spatial-or-dateline.xml b/tests/expected/suites_apiso_post_GetRecords-filter-and-nested-spatial-or-dateline.xml
index 3f2b1f2..4fe3176 100644
--- a/tests/expected/suites_apiso_post_GetRecords-filter-and-nested-spatial-or-dateline.xml
+++ b/tests/expected/suites_apiso_post_GetRecords-filter-and-nested-spatial-or-dateline.xml
@@ -1,9 +1,9 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<csw:GetRecordsResponse xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:inspire_common="http://inspire.ec.europa.eu/schemas/common/1.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dct="http://purl.org/dc/terms/" xmlns:ows="http://www.opengis.net/ows" xmlns:apiso="http://www.opengis.net/cat/csw/apiso/1.0" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xlink="http://www.w3.org/1999/xlink"  [...]
+<csw:GetRecordsResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gco="http://www.isotc211.org/2005/gco" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:srv="http://www.isotc211.org/2005/srv" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XML [...]
   <csw:SearchStatus timestamp="PYCSW_TIMESTAMP"/>
   <csw:SearchResults nextRecord="0" numberOfRecordsMatched="1" numberOfRecordsReturned="1" recordSchema="http://www.isotc211.org/2005/gmd" elementSet="full">
-    <gmi:MI_Metadata xmlns:gml="http://www.opengis.net/gml/3.2" xmlns:gmi="http://www.isotc211.org/2005/gmi" xmlns:gmx="http://www.isotc211.org/2005/gmx" xmlns:gsr="http://www.isotc211.org/2005/gsr" xmlns:gss="http://www.isotc211.org/2005/gss" xmlns:gts="http://www.isotc211.org/2005/gts" xsi:schemaLocation="http://www.isotc211.org/2005/gmi http://www.ngdc.noaa.gov/metadata/published/xsd/schema.xsd">
+    <gmi:MI_Metadata xmlns:gml="http://www.opengis.net/gml/3.2" xmlns:gmi="http://www.isotc211.org/2005/gmi" xsi:schemaLocation="http://www.isotc211.org/2005/gmi http://www.ngdc.noaa.gov/metadata/published/xsd/schema.xsd">
    <gmd:fileIdentifier>
       <gco:CharacterString>NS06agg</gco:CharacterString>
    </gmd:fileIdentifier>
diff --git a/tests/expected/suites_apiso_post_GetRecords-filter-anytext.xml b/tests/expected/suites_apiso_post_GetRecords-filter-anytext.xml
index e301c72..96190ee 100644
--- a/tests/expected/suites_apiso_post_GetRecords-filter-anytext.xml
+++ b/tests/expected/suites_apiso_post_GetRecords-filter-anytext.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<csw:GetRecordsResponse xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:inspire_common="http://inspire.ec.europa.eu/schemas/common/1.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dct="http://purl.org/dc/terms/" xmlns:ows="http://www.opengis.net/ows" xmlns:apiso="http://www.opengis.net/cat/csw/apiso/1.0" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xlink="http://www.w3.org/1999/xlink"  [...]
+<csw:GetRecordsResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gco="http://www.isotc211.org/2005/gco" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.0.2" xsi:schemaLocation="http://www.opengis.net/cat/csw/2.0. [...]
   <csw:SearchStatus timestamp="PYCSW_TIMESTAMP"/>
   <csw:SearchResults nextRecord="0" numberOfRecordsMatched="5" numberOfRecordsReturned="5" recordSchema="http://www.isotc211.org/2005/gmd" elementSet="brief">
     <gmd:MD_Metadata xsi:schemaLocation="http://www.isotc211.org/2005/gmd http://schemas.opengis.net/csw/2.0.2/profiles/apiso/1.0.0/apiso.xsd">
diff --git a/tests/expected/suites_apiso_post_GetRecords-filter-bbox-csw-output.xml b/tests/expected/suites_apiso_post_GetRecords-filter-bbox-csw-output.xml
index 8b52e48..74ac35a 100644
--- a/tests/expected/suites_apiso_post_GetRecords-filter-bbox-csw-output.xml
+++ b/tests/expected/suites_apiso_post_GetRecords-filter-bbox-csw-output.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<csw:GetRecordsResponse xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:inspire_common="http://inspire.ec.europa.eu/schemas/common/1.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dct="http://purl.org/dc/terms/" xmlns:ows="http://www.opengis.net/ows" xmlns:apiso="http://www.opengis.net/cat/csw/apiso/1.0" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xlink="http://www.w3.org/1999/xlink"  [...]
+<csw:GetRecordsResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.0.2" xsi:schemaLocation="http://www.opengis.net/cat/csw/2.0.2 http://schemas.opengis.net/csw/2.0.2/CSW-di [...]
   <csw:SearchStatus timestamp="PYCSW_TIMESTAMP"/>
   <csw:SearchResults nextRecord="6" numberOfRecordsMatched="16" numberOfRecordsReturned="5" recordSchema="http://www.opengis.net/cat/csw/2.0.2" elementSet="brief">
     <csw:BriefRecord>
diff --git a/tests/expected/suites_apiso_post_GetRecords-filter-bbox.xml b/tests/expected/suites_apiso_post_GetRecords-filter-bbox.xml
index 1d06953..cd76cde 100644
--- a/tests/expected/suites_apiso_post_GetRecords-filter-bbox.xml
+++ b/tests/expected/suites_apiso_post_GetRecords-filter-bbox.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<csw:GetRecordsResponse xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:inspire_common="http://inspire.ec.europa.eu/schemas/common/1.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dct="http://purl.org/dc/terms/" xmlns:ows="http://www.opengis.net/ows" xmlns:apiso="http://www.opengis.net/cat/csw/apiso/1.0" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xlink="http://www.w3.org/1999/xlink"  [...]
+<csw:GetRecordsResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gco="http://www.isotc211.org/2005/gco" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:srv="http://www.isotc211.org/2005/srv" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.0.2" xsi:schema [...]
   <csw:SearchStatus timestamp="PYCSW_TIMESTAMP"/>
   <csw:SearchResults nextRecord="6" numberOfRecordsMatched="16" numberOfRecordsReturned="5" recordSchema="http://www.isotc211.org/2005/gmd" elementSet="brief">
     <gmd:MD_Metadata xsi:schemaLocation="http://www.isotc211.org/2005/gmd http://schemas.opengis.net/csw/2.0.2/profiles/apiso/1.0.0/apiso.xsd">
diff --git a/tests/expected/suites_apiso_post_GetRecords-filter-servicetype.xml b/tests/expected/suites_apiso_post_GetRecords-filter-servicetype.xml
index 13846fd..80fa7ec 100644
--- a/tests/expected/suites_apiso_post_GetRecords-filter-servicetype.xml
+++ b/tests/expected/suites_apiso_post_GetRecords-filter-servicetype.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<csw:GetRecordsResponse xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:inspire_common="http://inspire.ec.europa.eu/schemas/common/1.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dct="http://purl.org/dc/terms/" xmlns:ows="http://www.opengis.net/ows" xmlns:apiso="http://www.opengis.net/cat/csw/apiso/1.0" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xlink="http://www.w3.org/1999/xlink"  [...]
+<csw:GetRecordsResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gco="http://www.isotc211.org/2005/gco" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:srv="http://www.isotc211.org/2005/srv" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.0.2" xsi:schema [...]
   <csw:SearchStatus timestamp="PYCSW_TIMESTAMP"/>
   <csw:SearchResults nextRecord="0" numberOfRecordsMatched="1" numberOfRecordsReturned="1" recordSchema="http://www.isotc211.org/2005/gmd" elementSet="brief">
     <gmd:MD_Metadata xsi:schemaLocation="http://www.isotc211.org/2005/gmd http://schemas.opengis.net/csw/2.0.2/profiles/apiso/1.0.0/apiso.xsd">
diff --git a/tests/expected/suites_atom_get_opensearch-description.xml b/tests/expected/suites_atom_get_opensearch-description.xml
index a8c5b21..d9af174 100644
--- a/tests/expected/suites_atom_get_opensearch-description.xml
+++ b/tests/expected/suites_atom_get_opensearch-description.xml
@@ -1,13 +1,13 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<OpenSearchDescription xmlns="http://a9.com/-/spec/opensearch/1.1/">
-  <ShortName>pycsw Geospatial Catalogue</ShortName>
-  <LongName>pycsw Geospatial Catalogue</LongName>
-  <Description>pycsw is an OGC CSW server implementation written in Python</Description>
-  <Tags>catalogue discovery</Tags>
-  <Url type="application/atom+xml" method="get" template="http://localhost/pycsw/csw.py?config=tests/suites/atom/default.cfg?mode=opensearch&service=CSW&version=2.0.2&request=GetRecords&elementsetname=full&typenames=csw:Record&resulttype=results&q={searchTerms?}&bbox={geo:box?}&time={time:start?}/{time:end?}&startposition={startIndex?}&maxrecords={count?}"/>
-  <Image type="image/vnd.microsoft.icon" width="16" height="16">http://pycsw.org/img/favicon.ico</Image>
-  <Developer>Kralidis, Tom</Developer>
-  <Contact>tomkralidis at gmail.com</Contact>
-  <Attribution>pycsw</Attribution>
-</OpenSearchDescription>
+<os:OpenSearchDescription xmlns:os="http://a9.com/-/spec/opensearch/1.1/">
+  <os:ShortName>pycsw Geospatial Catalogue</os:ShortName>
+  <os:LongName>pycsw Geospatial Catalogue</os:LongName>
+  <os:Description>pycsw is an OGC CSW server implementation written in Python</os:Description>
+  <os:Tags>catalogue discovery</os:Tags>
+  <os:Url type="application/atom+xml" method="get" template="http://localhost/pycsw/csw.py?config=tests/suites/atom/default.cfg&mode=opensearch&service=CSW&version=2.0.2&request=GetRecords&elementsetname=full&typenames=csw:Record&resulttype=results&q={searchTerms?}&bbox={geo:box?}&time={time:start?}/{time:end?}&startposition={startIndex?}&maxrecords={count?}"/>
+  <os:Image type="image/vnd.microsoft.icon" width="16" height="16">http://pycsw.org/img/favicon.ico</os:Image>
+  <os:Developer>Kralidis, Tom</os:Developer>
+  <os:Context>tomkralidis at gmail.com</os:Context>
+  <os:Attribution>pycsw</os:Attribution>
+</os:OpenSearchDescription>
diff --git a/tests/expected/suites_atom_get_opensearch-ogc-bbox-and-time.xml b/tests/expected/suites_atom_get_opensearch-ogc-bbox-and-time.xml
index 1a0a8e9..1b8a63a 100644
--- a/tests/expected/suites_atom_get_opensearch-ogc-bbox-and-time.xml
+++ b/tests/expected/suites_atom_get_opensearch-ogc-bbox-and-time.xml
@@ -1,40 +1,38 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<atom:feed xmlns:os="http://a9.com/-/spec/opensearch/1.1/" xmlns:time="http://a9.com/-/opensearch/extensions/time/1.0/" xmlns:geo="http://a9.com/-/opensearch/extensions/geo/1.0/" xmlns:atom="http://www.w3.org/2005/Atom">
+<atom:feed xmlns:atom="http://www.w3.org/2005/Atom" xmlns:os="http://a9.com/-/spec/opensearch/1.1/">
   <atom:id>http://localhost/pycsw/csw.py?config=tests/suites/atom/default.cfg</atom:id>
   <atom:title>pycsw Geospatial Catalogue</atom:title>
   <os:totalResults>2</os:totalResults>
   <os:startIndex>1</os:startIndex>
   <os:itemsPerPage>2</os:itemsPerPage>
-  <atom:entry xmlns:georss="http://www.georss.org/georss" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:gml="http://www.opengis.net/gml" xsi:schemaLocation="http://www.w3.org/2005/Atom http://www.kbcafe.com/rss/atom.xsd.xml">
-    <atom:category>Hydrography-Oceanographic</atom:category>
+  <atom:entry xmlns:georss="http://www.georss.org/georss" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:gml="http://www.opengis.net/gml" xsi:schemaLocation="http://www.w3.org/2005/Atom http://www.kbcafe.com/rss/atom.xsd.xml">
+    <atom:category term="Hydrography-Oceanographic"/>
     <atom:id>urn:uuid:9a669547-b69b-469f-a11f-2d875366bbdc</atom:id>
+    <dc:identifier>urn:uuid:9a669547-b69b-469f-a11f-2d875366bbdc</dc:identifier>
     <atom:link href="http://localhost/pycsw/csw.py?config=tests/suites/atom/default.cfg?service=CSW&version=2.0.2&request=GetRepositoryItem&id=urn:uuid:9a669547-b69b-469f-a11f-2d875366bbdc"/>
     <atom:title>Ñunç elementum</atom:title>
+    <atom:updated>PYCSW_TIMESTAMP</atom:updated>
     <georss:where>
-      <gml:Polygon srsName="urn:x-ogc:def:crs:EPSG:6.11:4326">
-        <gml:exterior>
-          <gml:LinearRing>
-            <gml:posList>44.79 -6.17 51.13 -6.17 51.13 -2.23 44.79 -2.23 44.79 -6.17</gml:posList>
-          </gml:LinearRing>
-        </gml:exterior>
-      </gml:Polygon>
+      <gml:Envelope srsName="http://www.opengis.net/def/crs/EPSG/0/4326">
+        <gml:lowerCorner>44.79 -6.17</gml:lowerCorner>
+        <gml:upperCorner>51.13 -2.23</gml:upperCorner>
+      </gml:Envelope>
     </georss:where>
   </atom:entry>
-  <atom:entry xmlns:georss="http://www.georss.org/georss" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:gml="http://www.opengis.net/gml" xsi:schemaLocation="http://www.w3.org/2005/Atom http://www.kbcafe.com/rss/atom.xsd.xml">
-    <atom:category>Vegetation-Cropland</atom:category>
+  <atom:entry xmlns:georss="http://www.georss.org/georss" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:gml="http://www.opengis.net/gml" xsi:schemaLocation="http://www.w3.org/2005/Atom http://www.kbcafe.com/rss/atom.xsd.xml">
+    <atom:category term="Vegetation-Cropland"/>
     <atom:id>urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63</atom:id>
+    <dc:identifier>urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63</dc:identifier>
     <atom:link href="http://localhost/pycsw/csw.py?config=tests/suites/atom/default.cfg?service=CSW&version=2.0.2&request=GetRepositoryItem&id=urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63"/>
-    <atom:summary>Curabitur lacinia, ante non porta tempus, mi lorem feugiat odio, eget suscipit eros pede ac velit.</atom:summary>
     <atom:title>Mauris sed neque</atom:title>
+    <atom:updated>PYCSW_TIMESTAMP</atom:updated>
+    <atom:summary>Curabitur lacinia, ante non porta tempus, mi lorem feugiat odio, eget suscipit eros pede ac velit.</atom:summary>
     <georss:where>
-      <gml:Polygon srsName="urn:x-ogc:def:crs:EPSG:6.11:4326">
-        <gml:exterior>
-          <gml:LinearRing>
-            <gml:posList>47.59 -4.1 51.22 -4.1 51.22 0.89 47.59 0.89 47.59 -4.1</gml:posList>
-          </gml:LinearRing>
-        </gml:exterior>
-      </gml:Polygon>
+      <gml:Envelope srsName="http://www.opengis.net/def/crs/EPSG/0/4326">
+        <gml:lowerCorner>47.59 -4.1</gml:lowerCorner>
+        <gml:upperCorner>51.22 0.89</gml:upperCorner>
+      </gml:Envelope>
     </georss:where>
   </atom:entry>
 </atom:feed>
diff --git a/tests/expected/suites_atom_get_opensearch-ogc-bbox.xml b/tests/expected/suites_atom_get_opensearch-ogc-bbox.xml
index 6fdbc6f..cb6309a 100644
--- a/tests/expected/suites_atom_get_opensearch-ogc-bbox.xml
+++ b/tests/expected/suites_atom_get_opensearch-ogc-bbox.xml
@@ -1,54 +1,52 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<atom:feed xmlns:os="http://a9.com/-/spec/opensearch/1.1/" xmlns:time="http://a9.com/-/opensearch/extensions/time/1.0/" xmlns:geo="http://a9.com/-/opensearch/extensions/geo/1.0/" xmlns:atom="http://www.w3.org/2005/Atom">
+<atom:feed xmlns:atom="http://www.w3.org/2005/Atom" xmlns:os="http://a9.com/-/spec/opensearch/1.1/">
   <atom:id>http://localhost/pycsw/csw.py?config=tests/suites/atom/default.cfg</atom:id>
   <atom:title>pycsw Geospatial Catalogue</atom:title>
   <os:totalResults>3</os:totalResults>
   <os:startIndex>1</os:startIndex>
   <os:itemsPerPage>3</os:itemsPerPage>
-  <atom:entry xmlns:georss="http://www.georss.org/georss" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:gml="http://www.opengis.net/gml" xsi:schemaLocation="http://www.w3.org/2005/Atom http://www.kbcafe.com/rss/atom.xsd.xml">
+  <atom:entry xmlns:georss="http://www.georss.org/georss" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:gml="http://www.opengis.net/gml" xsi:schemaLocation="http://www.w3.org/2005/Atom http://www.kbcafe.com/rss/atom.xsd.xml">
     <atom:id>urn:uuid:1ef30a8b-876d-4828-9246-c37ab4510bbd</atom:id>
+    <dc:identifier>urn:uuid:1ef30a8b-876d-4828-9246-c37ab4510bbd</dc:identifier>
     <atom:link href="http://localhost/pycsw/csw.py?config=tests/suites/atom/default.cfg?service=CSW&version=2.0.2&request=GetRepositoryItem&id=urn:uuid:1ef30a8b-876d-4828-9246-c37ab4510bbd"/>
+    <atom:title/>
+    <atom:updated>PYCSW_TIMESTAMP</atom:updated>
     <atom:summary>Proin sit amet justo. In justo. Aenean adipiscing nulla id tellus.</atom:summary>
     <georss:where>
-      <gml:Polygon srsName="urn:x-ogc:def:crs:EPSG:6.11:4326">
-        <gml:exterior>
-          <gml:LinearRing>
-            <gml:posList>60.04 13.75 68.41 13.75 68.41 17.92 60.04 17.92 60.04 13.75</gml:posList>
-          </gml:LinearRing>
-        </gml:exterior>
-      </gml:Polygon>
+      <gml:Envelope srsName="http://www.opengis.net/def/crs/EPSG/0/4326">
+        <gml:lowerCorner>60.04 13.75</gml:lowerCorner>
+        <gml:upperCorner>68.41 17.92</gml:upperCorner>
+      </gml:Envelope>
     </georss:where>
   </atom:entry>
-  <atom:entry xmlns:georss="http://www.georss.org/georss" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:gml="http://www.opengis.net/gml" xsi:schemaLocation="http://www.w3.org/2005/Atom http://www.kbcafe.com/rss/atom.xsd.xml">
-    <atom:category>Vegetation-Cropland</atom:category>
+  <atom:entry xmlns:georss="http://www.georss.org/georss" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:gml="http://www.opengis.net/gml" xsi:schemaLocation="http://www.w3.org/2005/Atom http://www.kbcafe.com/rss/atom.xsd.xml">
+    <atom:category term="Vegetation-Cropland"/>
     <atom:id>urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63</atom:id>
+    <dc:identifier>urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63</dc:identifier>
     <atom:link href="http://localhost/pycsw/csw.py?config=tests/suites/atom/default.cfg?service=CSW&version=2.0.2&request=GetRepositoryItem&id=urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63"/>
-    <atom:summary>Curabitur lacinia, ante non porta tempus, mi lorem feugiat odio, eget suscipit eros pede ac velit.</atom:summary>
     <atom:title>Mauris sed neque</atom:title>
+    <atom:updated>PYCSW_TIMESTAMP</atom:updated>
+    <atom:summary>Curabitur lacinia, ante non porta tempus, mi lorem feugiat odio, eget suscipit eros pede ac velit.</atom:summary>
     <georss:where>
-      <gml:Polygon srsName="urn:x-ogc:def:crs:EPSG:6.11:4326">
-        <gml:exterior>
-          <gml:LinearRing>
-            <gml:posList>47.59 -4.1 51.22 -4.1 51.22 0.89 47.59 0.89 47.59 -4.1</gml:posList>
-          </gml:LinearRing>
-        </gml:exterior>
-      </gml:Polygon>
+      <gml:Envelope srsName="http://www.opengis.net/def/crs/EPSG/0/4326">
+        <gml:lowerCorner>47.59 -4.1</gml:lowerCorner>
+        <gml:upperCorner>51.22 0.89</gml:upperCorner>
+      </gml:Envelope>
     </georss:where>
   </atom:entry>
-  <atom:entry xmlns:georss="http://www.georss.org/georss" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:gml="http://www.opengis.net/gml" xsi:schemaLocation="http://www.w3.org/2005/Atom http://www.kbcafe.com/rss/atom.xsd.xml">
-    <atom:category>Hydrography-Oceanographic</atom:category>
+  <atom:entry xmlns:georss="http://www.georss.org/georss" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:gml="http://www.opengis.net/gml" xsi:schemaLocation="http://www.w3.org/2005/Atom http://www.kbcafe.com/rss/atom.xsd.xml">
+    <atom:category term="Hydrography-Oceanographic"/>
     <atom:id>urn:uuid:9a669547-b69b-469f-a11f-2d875366bbdc</atom:id>
+    <dc:identifier>urn:uuid:9a669547-b69b-469f-a11f-2d875366bbdc</dc:identifier>
     <atom:link href="http://localhost/pycsw/csw.py?config=tests/suites/atom/default.cfg?service=CSW&version=2.0.2&request=GetRepositoryItem&id=urn:uuid:9a669547-b69b-469f-a11f-2d875366bbdc"/>
     <atom:title>Ñunç elementum</atom:title>
+    <atom:updated>PYCSW_TIMESTAMP</atom:updated>
     <georss:where>
-      <gml:Polygon srsName="urn:x-ogc:def:crs:EPSG:6.11:4326">
-        <gml:exterior>
-          <gml:LinearRing>
-            <gml:posList>44.79 -6.17 51.13 -6.17 51.13 -2.23 44.79 -2.23 44.79 -6.17</gml:posList>
-          </gml:LinearRing>
-        </gml:exterior>
-      </gml:Polygon>
+      <gml:Envelope srsName="http://www.opengis.net/def/crs/EPSG/0/4326">
+        <gml:lowerCorner>44.79 -6.17</gml:lowerCorner>
+        <gml:upperCorner>51.13 -2.23</gml:upperCorner>
+      </gml:Envelope>
     </georss:where>
   </atom:entry>
 </atom:feed>
diff --git a/tests/expected/suites_atom_get_opensearch-ogc-count-and-page1.xml b/tests/expected/suites_atom_get_opensearch-ogc-count-and-page1.xml
index 6bdd5fd..abc2039 100644
--- a/tests/expected/suites_atom_get_opensearch-ogc-count-and-page1.xml
+++ b/tests/expected/suites_atom_get_opensearch-ogc-count-and-page1.xml
@@ -1,31 +1,32 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<atom:feed xmlns:os="http://a9.com/-/spec/opensearch/1.1/" xmlns:time="http://a9.com/-/opensearch/extensions/time/1.0/" xmlns:geo="http://a9.com/-/opensearch/extensions/geo/1.0/" xmlns:atom="http://www.w3.org/2005/Atom">
+<atom:feed xmlns:atom="http://www.w3.org/2005/Atom" xmlns:os="http://a9.com/-/spec/opensearch/1.1/">
   <atom:id>http://localhost/pycsw/csw.py?config=tests/suites/atom/default.cfg</atom:id>
   <atom:title>pycsw Geospatial Catalogue</atom:title>
   <os:totalResults>2</os:totalResults>
   <os:startIndex>1</os:startIndex>
   <os:itemsPerPage>2</os:itemsPerPage>
-  <atom:entry xmlns:georss="http://www.georss.org/georss" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.w3.org/2005/Atom http://www.kbcafe.com/rss/atom.xsd.xml">
-    <atom:category>Vegetation</atom:category>
+  <atom:entry xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dc="http://purl.org/dc/elements/1.1/" xsi:schemaLocation="http://www.w3.org/2005/Atom http://www.kbcafe.com/rss/atom.xsd.xml">
+    <atom:category term="Vegetation"/>
     <atom:id>urn:uuid:6a3de50b-fa66-4b58-a0e6-ca146fdd18d4</atom:id>
+    <dc:identifier>urn:uuid:6a3de50b-fa66-4b58-a0e6-ca146fdd18d4</dc:identifier>
     <atom:link href="http://localhost/pycsw/csw.py?config=tests/suites/atom/default.cfg?service=CSW&version=2.0.2&request=GetRepositoryItem&id=urn:uuid:6a3de50b-fa66-4b58-a0e6-ca146fdd18d4"/>
     <atom:title>Ut facilisis justo ut lacus</atom:title>
+    <atom:updated>PYCSW_TIMESTAMP</atom:updated>
   </atom:entry>
-  <atom:entry xmlns:georss="http://www.georss.org/georss" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:gml="http://www.opengis.net/gml" xsi:schemaLocation="http://www.w3.org/2005/Atom http://www.kbcafe.com/rss/atom.xsd.xml">
-    <atom:category>Vegetation-Cropland</atom:category>
+  <atom:entry xmlns:georss="http://www.georss.org/georss" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:gml="http://www.opengis.net/gml" xsi:schemaLocation="http://www.w3.org/2005/Atom http://www.kbcafe.com/rss/atom.xsd.xml">
+    <atom:category term="Vegetation-Cropland"/>
     <atom:id>urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63</atom:id>
+    <dc:identifier>urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63</dc:identifier>
     <atom:link href="http://localhost/pycsw/csw.py?config=tests/suites/atom/default.cfg?service=CSW&version=2.0.2&request=GetRepositoryItem&id=urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63"/>
-    <atom:summary>Curabitur lacinia, ante non porta tempus, mi lorem feugiat odio, eget suscipit eros pede ac velit.</atom:summary>
     <atom:title>Mauris sed neque</atom:title>
+    <atom:updated>PYCSW_TIMESTAMP</atom:updated>
+    <atom:summary>Curabitur lacinia, ante non porta tempus, mi lorem feugiat odio, eget suscipit eros pede ac velit.</atom:summary>
     <georss:where>
-      <gml:Polygon srsName="urn:x-ogc:def:crs:EPSG:6.11:4326">
-        <gml:exterior>
-          <gml:LinearRing>
-            <gml:posList>47.59 -4.1 51.22 -4.1 51.22 0.89 47.59 0.89 47.59 -4.1</gml:posList>
-          </gml:LinearRing>
-        </gml:exterior>
-      </gml:Polygon>
+      <gml:Envelope srsName="http://www.opengis.net/def/crs/EPSG/0/4326">
+        <gml:lowerCorner>47.59 -4.1</gml:lowerCorner>
+        <gml:upperCorner>51.22 0.89</gml:upperCorner>
+      </gml:Envelope>
     </georss:where>
   </atom:entry>
 </atom:feed>
diff --git a/tests/expected/suites_atom_get_opensearch-ogc-count-and-page2.xml b/tests/expected/suites_atom_get_opensearch-ogc-count-and-page2.xml
index 8df25af..709921a 100644
--- a/tests/expected/suites_atom_get_opensearch-ogc-count-and-page2.xml
+++ b/tests/expected/suites_atom_get_opensearch-ogc-count-and-page2.xml
@@ -1,15 +1,17 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<atom:feed xmlns:os="http://a9.com/-/spec/opensearch/1.1/" xmlns:time="http://a9.com/-/opensearch/extensions/time/1.0/" xmlns:geo="http://a9.com/-/opensearch/extensions/geo/1.0/" xmlns:atom="http://www.w3.org/2005/Atom">
+<atom:feed xmlns:atom="http://www.w3.org/2005/Atom" xmlns:os="http://a9.com/-/spec/opensearch/1.1/">
   <atom:id>http://localhost/pycsw/csw.py?config=tests/suites/atom/default.cfg</atom:id>
   <atom:title>pycsw Geospatial Catalogue</atom:title>
   <os:totalResults>2</os:totalResults>
   <os:startIndex>1</os:startIndex>
   <os:itemsPerPage>1</os:itemsPerPage>
-  <atom:entry xmlns:georss="http://www.georss.org/georss" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.w3.org/2005/Atom http://www.kbcafe.com/rss/atom.xsd.xml">
-    <atom:category>Vegetation</atom:category>
+  <atom:entry xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dc="http://purl.org/dc/elements/1.1/" xsi:schemaLocation="http://www.w3.org/2005/Atom http://www.kbcafe.com/rss/atom.xsd.xml">
+    <atom:category term="Vegetation"/>
     <atom:id>urn:uuid:6a3de50b-fa66-4b58-a0e6-ca146fdd18d4</atom:id>
+    <dc:identifier>urn:uuid:6a3de50b-fa66-4b58-a0e6-ca146fdd18d4</dc:identifier>
     <atom:link href="http://localhost/pycsw/csw.py?config=tests/suites/atom/default.cfg?service=CSW&version=2.0.2&request=GetRepositoryItem&id=urn:uuid:6a3de50b-fa66-4b58-a0e6-ca146fdd18d4"/>
     <atom:title>Ut facilisis justo ut lacus</atom:title>
+    <atom:updated>PYCSW_TIMESTAMP</atom:updated>
   </atom:entry>
 </atom:feed>
diff --git a/tests/expected/suites_atom_get_opensearch-ogc-q-and-bbox.xml b/tests/expected/suites_atom_get_opensearch-ogc-q-and-bbox.xml
index c2c5180..ed8c2a3 100644
--- a/tests/expected/suites_atom_get_opensearch-ogc-q-and-bbox.xml
+++ b/tests/expected/suites_atom_get_opensearch-ogc-q-and-bbox.xml
@@ -1,25 +1,24 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<atom:feed xmlns:os="http://a9.com/-/spec/opensearch/1.1/" xmlns:time="http://a9.com/-/opensearch/extensions/time/1.0/" xmlns:geo="http://a9.com/-/opensearch/extensions/geo/1.0/" xmlns:atom="http://www.w3.org/2005/Atom">
+<atom:feed xmlns:atom="http://www.w3.org/2005/Atom" xmlns:os="http://a9.com/-/spec/opensearch/1.1/">
   <atom:id>http://localhost/pycsw/csw.py?config=tests/suites/atom/default.cfg</atom:id>
   <atom:title>pycsw Geospatial Catalogue</atom:title>
   <os:totalResults>1</os:totalResults>
   <os:startIndex>1</os:startIndex>
   <os:itemsPerPage>1</os:itemsPerPage>
-  <atom:entry xmlns:georss="http://www.georss.org/georss" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:gml="http://www.opengis.net/gml" xsi:schemaLocation="http://www.w3.org/2005/Atom http://www.kbcafe.com/rss/atom.xsd.xml">
-    <atom:category>Vegetation-Cropland</atom:category>
+  <atom:entry xmlns:georss="http://www.georss.org/georss" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:gml="http://www.opengis.net/gml" xsi:schemaLocation="http://www.w3.org/2005/Atom http://www.kbcafe.com/rss/atom.xsd.xml">
+    <atom:category term="Vegetation-Cropland"/>
     <atom:id>urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63</atom:id>
+    <dc:identifier>urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63</dc:identifier>
     <atom:link href="http://localhost/pycsw/csw.py?config=tests/suites/atom/default.cfg?service=CSW&version=2.0.2&request=GetRepositoryItem&id=urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63"/>
-    <atom:summary>Curabitur lacinia, ante non porta tempus, mi lorem feugiat odio, eget suscipit eros pede ac velit.</atom:summary>
     <atom:title>Mauris sed neque</atom:title>
+    <atom:updated>PYCSW_TIMESTAMP</atom:updated>
+    <atom:summary>Curabitur lacinia, ante non porta tempus, mi lorem feugiat odio, eget suscipit eros pede ac velit.</atom:summary>
     <georss:where>
-      <gml:Polygon srsName="urn:x-ogc:def:crs:EPSG:6.11:4326">
-        <gml:exterior>
-          <gml:LinearRing>
-            <gml:posList>47.59 -4.1 51.22 -4.1 51.22 0.89 47.59 0.89 47.59 -4.1</gml:posList>
-          </gml:LinearRing>
-        </gml:exterior>
-      </gml:Polygon>
+      <gml:Envelope srsName="http://www.opengis.net/def/crs/EPSG/0/4326">
+        <gml:lowerCorner>47.59 -4.1</gml:lowerCorner>
+        <gml:upperCorner>51.22 0.89</gml:upperCorner>
+      </gml:Envelope>
     </georss:where>
   </atom:entry>
 </atom:feed>
diff --git a/tests/expected/suites_atom_get_opensearch-ogc-q-and-time.xml b/tests/expected/suites_atom_get_opensearch-ogc-q-and-time.xml
index d93c95d..281c6df 100644
--- a/tests/expected/suites_atom_get_opensearch-ogc-q-and-time.xml
+++ b/tests/expected/suites_atom_get_opensearch-ogc-q-and-time.xml
@@ -1,16 +1,18 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<atom:feed xmlns:os="http://a9.com/-/spec/opensearch/1.1/" xmlns:time="http://a9.com/-/opensearch/extensions/time/1.0/" xmlns:geo="http://a9.com/-/opensearch/extensions/geo/1.0/" xmlns:atom="http://www.w3.org/2005/Atom">
+<atom:feed xmlns:atom="http://www.w3.org/2005/Atom" xmlns:os="http://a9.com/-/spec/opensearch/1.1/">
   <atom:id>http://localhost/pycsw/csw.py?config=tests/suites/atom/default.cfg</atom:id>
   <atom:title>pycsw Geospatial Catalogue</atom:title>
   <os:totalResults>1</os:totalResults>
   <os:startIndex>1</os:startIndex>
   <os:itemsPerPage>1</os:itemsPerPage>
-  <atom:entry xmlns:georss="http://www.georss.org/georss" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.w3.org/2005/Atom http://www.kbcafe.com/rss/atom.xsd.xml">
-    <atom:category>Land titles</atom:category>
+  <atom:entry xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dc="http://purl.org/dc/elements/1.1/" xsi:schemaLocation="http://www.w3.org/2005/Atom http://www.kbcafe.com/rss/atom.xsd.xml">
+    <atom:category term="Land titles"/>
     <atom:id>urn:uuid:e9330592-0932-474b-be34-c3a3bb67c7db</atom:id>
+    <dc:identifier>urn:uuid:e9330592-0932-474b-be34-c3a3bb67c7db</dc:identifier>
     <atom:link href="http://localhost/pycsw/csw.py?config=tests/suites/atom/default.cfg?service=CSW&version=2.0.2&request=GetRepositoryItem&id=urn:uuid:e9330592-0932-474b-be34-c3a3bb67c7db"/>
-    <atom:summary>Morbi ultriçes, dui suscipit vestibulum prètium, velit ante pretium tortor, egët tincidunt pede odio ac nulla.</atom:summary>
     <atom:title>Fuscé vitae ligulä</atom:title>
+    <atom:updated>PYCSW_TIMESTAMP</atom:updated>
+    <atom:summary>Morbi ultriçes, dui suscipit vestibulum prètium, velit ante pretium tortor, egët tincidunt pede odio ac nulla.</atom:summary>
   </atom:entry>
 </atom:feed>
diff --git a/tests/expected/suites_atom_get_opensearch-ogc-q.xml b/tests/expected/suites_atom_get_opensearch-ogc-q.xml
index 83db210..7aaae42 100644
--- a/tests/expected/suites_atom_get_opensearch-ogc-q.xml
+++ b/tests/expected/suites_atom_get_opensearch-ogc-q.xml
@@ -1,16 +1,18 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<atom:feed xmlns:os="http://a9.com/-/spec/opensearch/1.1/" xmlns:time="http://a9.com/-/opensearch/extensions/time/1.0/" xmlns:geo="http://a9.com/-/opensearch/extensions/geo/1.0/" xmlns:atom="http://www.w3.org/2005/Atom">
+<atom:feed xmlns:atom="http://www.w3.org/2005/Atom" xmlns:os="http://a9.com/-/spec/opensearch/1.1/">
   <atom:id>http://localhost/pycsw/csw.py?config=tests/suites/atom/default.cfg</atom:id>
   <atom:title>pycsw Geospatial Catalogue</atom:title>
   <os:totalResults>1</os:totalResults>
   <os:startIndex>1</os:startIndex>
   <os:itemsPerPage>1</os:itemsPerPage>
-  <atom:entry xmlns:georss="http://www.georss.org/georss" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.w3.org/2005/Atom http://www.kbcafe.com/rss/atom.xsd.xml">
-    <atom:category>Tourism--Greece</atom:category>
+  <atom:entry xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dc="http://purl.org/dc/elements/1.1/" xsi:schemaLocation="http://www.w3.org/2005/Atom http://www.kbcafe.com/rss/atom.xsd.xml">
+    <atom:category term="Tourism--Greece"/>
     <atom:id>urn:uuid:19887a8a-f6b0-4a63-ae56-7fba0e17801f</atom:id>
+    <dc:identifier>urn:uuid:19887a8a-f6b0-4a63-ae56-7fba0e17801f</dc:identifier>
     <atom:link href="http://localhost/pycsw/csw.py?config=tests/suites/atom/default.cfg?service=CSW&version=2.0.2&request=GetRepositoryItem&id=urn:uuid:19887a8a-f6b0-4a63-ae56-7fba0e17801f"/>
-    <atom:summary>Quisque lacus diam, placerat mollis, pharetra in, commodo sed, augue. Duis iaculis arcu vel arcu.</atom:summary>
     <atom:title>Lorem ipsum</atom:title>
+    <atom:updated>PYCSW_TIMESTAMP</atom:updated>
+    <atom:summary>Quisque lacus diam, placerat mollis, pharetra in, commodo sed, augue. Duis iaculis arcu vel arcu.</atom:summary>
   </atom:entry>
 </atom:feed>
diff --git a/tests/expected/suites_atom_get_opensearch-ogc-time.xml b/tests/expected/suites_atom_get_opensearch-ogc-time.xml
index d93c95d..281c6df 100644
--- a/tests/expected/suites_atom_get_opensearch-ogc-time.xml
+++ b/tests/expected/suites_atom_get_opensearch-ogc-time.xml
@@ -1,16 +1,18 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<atom:feed xmlns:os="http://a9.com/-/spec/opensearch/1.1/" xmlns:time="http://a9.com/-/opensearch/extensions/time/1.0/" xmlns:geo="http://a9.com/-/opensearch/extensions/geo/1.0/" xmlns:atom="http://www.w3.org/2005/Atom">
+<atom:feed xmlns:atom="http://www.w3.org/2005/Atom" xmlns:os="http://a9.com/-/spec/opensearch/1.1/">
   <atom:id>http://localhost/pycsw/csw.py?config=tests/suites/atom/default.cfg</atom:id>
   <atom:title>pycsw Geospatial Catalogue</atom:title>
   <os:totalResults>1</os:totalResults>
   <os:startIndex>1</os:startIndex>
   <os:itemsPerPage>1</os:itemsPerPage>
-  <atom:entry xmlns:georss="http://www.georss.org/georss" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.w3.org/2005/Atom http://www.kbcafe.com/rss/atom.xsd.xml">
-    <atom:category>Land titles</atom:category>
+  <atom:entry xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dc="http://purl.org/dc/elements/1.1/" xsi:schemaLocation="http://www.w3.org/2005/Atom http://www.kbcafe.com/rss/atom.xsd.xml">
+    <atom:category term="Land titles"/>
     <atom:id>urn:uuid:e9330592-0932-474b-be34-c3a3bb67c7db</atom:id>
+    <dc:identifier>urn:uuid:e9330592-0932-474b-be34-c3a3bb67c7db</dc:identifier>
     <atom:link href="http://localhost/pycsw/csw.py?config=tests/suites/atom/default.cfg?service=CSW&version=2.0.2&request=GetRepositoryItem&id=urn:uuid:e9330592-0932-474b-be34-c3a3bb67c7db"/>
-    <atom:summary>Morbi ultriçes, dui suscipit vestibulum prètium, velit ante pretium tortor, egët tincidunt pede odio ac nulla.</atom:summary>
     <atom:title>Fuscé vitae ligulä</atom:title>
+    <atom:updated>PYCSW_TIMESTAMP</atom:updated>
+    <atom:summary>Morbi ultriçes, dui suscipit vestibulum prètium, velit ante pretium tortor, egët tincidunt pede odio ac nulla.</atom:summary>
   </atom:entry>
 </atom:feed>
diff --git a/tests/expected/suites_atom_get_opensearch-ogc-timeend.xml b/tests/expected/suites_atom_get_opensearch-ogc-timeend.xml
index d93c95d..281c6df 100644
--- a/tests/expected/suites_atom_get_opensearch-ogc-timeend.xml
+++ b/tests/expected/suites_atom_get_opensearch-ogc-timeend.xml
@@ -1,16 +1,18 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<atom:feed xmlns:os="http://a9.com/-/spec/opensearch/1.1/" xmlns:time="http://a9.com/-/opensearch/extensions/time/1.0/" xmlns:geo="http://a9.com/-/opensearch/extensions/geo/1.0/" xmlns:atom="http://www.w3.org/2005/Atom">
+<atom:feed xmlns:atom="http://www.w3.org/2005/Atom" xmlns:os="http://a9.com/-/spec/opensearch/1.1/">
   <atom:id>http://localhost/pycsw/csw.py?config=tests/suites/atom/default.cfg</atom:id>
   <atom:title>pycsw Geospatial Catalogue</atom:title>
   <os:totalResults>1</os:totalResults>
   <os:startIndex>1</os:startIndex>
   <os:itemsPerPage>1</os:itemsPerPage>
-  <atom:entry xmlns:georss="http://www.georss.org/georss" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.w3.org/2005/Atom http://www.kbcafe.com/rss/atom.xsd.xml">
-    <atom:category>Land titles</atom:category>
+  <atom:entry xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dc="http://purl.org/dc/elements/1.1/" xsi:schemaLocation="http://www.w3.org/2005/Atom http://www.kbcafe.com/rss/atom.xsd.xml">
+    <atom:category term="Land titles"/>
     <atom:id>urn:uuid:e9330592-0932-474b-be34-c3a3bb67c7db</atom:id>
+    <dc:identifier>urn:uuid:e9330592-0932-474b-be34-c3a3bb67c7db</dc:identifier>
     <atom:link href="http://localhost/pycsw/csw.py?config=tests/suites/atom/default.cfg?service=CSW&version=2.0.2&request=GetRepositoryItem&id=urn:uuid:e9330592-0932-474b-be34-c3a3bb67c7db"/>
-    <atom:summary>Morbi ultriçes, dui suscipit vestibulum prètium, velit ante pretium tortor, egët tincidunt pede odio ac nulla.</atom:summary>
     <atom:title>Fuscé vitae ligulä</atom:title>
+    <atom:updated>PYCSW_TIMESTAMP</atom:updated>
+    <atom:summary>Morbi ultriçes, dui suscipit vestibulum prètium, velit ante pretium tortor, egët tincidunt pede odio ac nulla.</atom:summary>
   </atom:entry>
 </atom:feed>
diff --git a/tests/expected/suites_atom_get_opensearch-ogc-timestart.xml b/tests/expected/suites_atom_get_opensearch-ogc-timestart.xml
index f7b1c74..6e16948 100644
--- a/tests/expected/suites_atom_get_opensearch-ogc-timestart.xml
+++ b/tests/expected/suites_atom_get_opensearch-ogc-timestart.xml
@@ -1,47 +1,47 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<atom:feed xmlns:os="http://a9.com/-/spec/opensearch/1.1/" xmlns:time="http://a9.com/-/opensearch/extensions/time/1.0/" xmlns:geo="http://a9.com/-/opensearch/extensions/geo/1.0/" xmlns:atom="http://www.w3.org/2005/Atom">
+<atom:feed xmlns:atom="http://www.w3.org/2005/Atom" xmlns:os="http://a9.com/-/spec/opensearch/1.1/">
   <atom:id>http://localhost/pycsw/csw.py?config=tests/suites/atom/default.cfg</atom:id>
   <atom:title>pycsw Geospatial Catalogue</atom:title>
   <os:totalResults>3</os:totalResults>
   <os:startIndex>1</os:startIndex>
   <os:itemsPerPage>3</os:itemsPerPage>
-  <atom:entry xmlns:georss="http://www.georss.org/georss" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:gml="http://www.opengis.net/gml" xsi:schemaLocation="http://www.w3.org/2005/Atom http://www.kbcafe.com/rss/atom.xsd.xml">
-    <atom:category>Hydrography-Oceanographic</atom:category>
+  <atom:entry xmlns:georss="http://www.georss.org/georss" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:gml="http://www.opengis.net/gml" xsi:schemaLocation="http://www.w3.org/2005/Atom http://www.kbcafe.com/rss/atom.xsd.xml">
+    <atom:category term="Hydrography-Oceanographic"/>
     <atom:id>urn:uuid:9a669547-b69b-469f-a11f-2d875366bbdc</atom:id>
+    <dc:identifier>urn:uuid:9a669547-b69b-469f-a11f-2d875366bbdc</dc:identifier>
     <atom:link href="http://localhost/pycsw/csw.py?config=tests/suites/atom/default.cfg?service=CSW&version=2.0.2&request=GetRepositoryItem&id=urn:uuid:9a669547-b69b-469f-a11f-2d875366bbdc"/>
     <atom:title>Ñunç elementum</atom:title>
+    <atom:updated>PYCSW_TIMESTAMP</atom:updated>
     <georss:where>
-      <gml:Polygon srsName="urn:x-ogc:def:crs:EPSG:6.11:4326">
-        <gml:exterior>
-          <gml:LinearRing>
-            <gml:posList>44.79 -6.17 51.13 -6.17 51.13 -2.23 44.79 -2.23 44.79 -6.17</gml:posList>
-          </gml:LinearRing>
-        </gml:exterior>
-      </gml:Polygon>
+      <gml:Envelope srsName="http://www.opengis.net/def/crs/EPSG/0/4326">
+        <gml:lowerCorner>44.79 -6.17</gml:lowerCorner>
+        <gml:upperCorner>51.13 -2.23</gml:upperCorner>
+      </gml:Envelope>
     </georss:where>
   </atom:entry>
-  <atom:entry xmlns:georss="http://www.georss.org/georss" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:gml="http://www.opengis.net/gml" xsi:schemaLocation="http://www.w3.org/2005/Atom http://www.kbcafe.com/rss/atom.xsd.xml">
-    <atom:category>Vegetation-Cropland</atom:category>
+  <atom:entry xmlns:georss="http://www.georss.org/georss" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:gml="http://www.opengis.net/gml" xsi:schemaLocation="http://www.w3.org/2005/Atom http://www.kbcafe.com/rss/atom.xsd.xml">
+    <atom:category term="Vegetation-Cropland"/>
     <atom:id>urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63</atom:id>
+    <dc:identifier>urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63</dc:identifier>
     <atom:link href="http://localhost/pycsw/csw.py?config=tests/suites/atom/default.cfg?service=CSW&version=2.0.2&request=GetRepositoryItem&id=urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63"/>
-    <atom:summary>Curabitur lacinia, ante non porta tempus, mi lorem feugiat odio, eget suscipit eros pede ac velit.</atom:summary>
     <atom:title>Mauris sed neque</atom:title>
+    <atom:updated>PYCSW_TIMESTAMP</atom:updated>
+    <atom:summary>Curabitur lacinia, ante non porta tempus, mi lorem feugiat odio, eget suscipit eros pede ac velit.</atom:summary>
     <georss:where>
-      <gml:Polygon srsName="urn:x-ogc:def:crs:EPSG:6.11:4326">
-        <gml:exterior>
-          <gml:LinearRing>
-            <gml:posList>47.59 -4.1 51.22 -4.1 51.22 0.89 47.59 0.89 47.59 -4.1</gml:posList>
-          </gml:LinearRing>
-        </gml:exterior>
-      </gml:Polygon>
+      <gml:Envelope srsName="http://www.opengis.net/def/crs/EPSG/0/4326">
+        <gml:lowerCorner>47.59 -4.1</gml:lowerCorner>
+        <gml:upperCorner>51.22 0.89</gml:upperCorner>
+      </gml:Envelope>
     </georss:where>
   </atom:entry>
-  <atom:entry xmlns:georss="http://www.georss.org/georss" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.w3.org/2005/Atom http://www.kbcafe.com/rss/atom.xsd.xml">
-    <atom:category>Hydrography--Dictionaries</atom:category>
+  <atom:entry xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dc="http://purl.org/dc/elements/1.1/" xsi:schemaLocation="http://www.w3.org/2005/Atom http://www.kbcafe.com/rss/atom.xsd.xml">
+    <atom:category term="Hydrography--Dictionaries"/>
     <atom:id>urn:uuid:784e2afd-a9fd-44a6-9a92-a3848371c8ec</atom:id>
+    <dc:identifier>urn:uuid:784e2afd-a9fd-44a6-9a92-a3848371c8ec</dc:identifier>
     <atom:link href="http://localhost/pycsw/csw.py?config=tests/suites/atom/default.cfg?service=CSW&version=2.0.2&request=GetRepositoryItem&id=urn:uuid:784e2afd-a9fd-44a6-9a92-a3848371c8ec"/>
-    <atom:summary>Vestibulum quis ipsum sit amet metus imperdiet vehicula. Nulla scelerisque cursus mi.</atom:summary>
     <atom:title>Aliquam fermentum purus quis arcu</atom:title>
+    <atom:updated>PYCSW_TIMESTAMP</atom:updated>
+    <atom:summary>Vestibulum quis ipsum sit amet metus imperdiet vehicula. Nulla scelerisque cursus mi.</atom:summary>
   </atom:entry>
 </atom:feed>
diff --git a/tests/expected/suites_atom_get_opensearch.xml b/tests/expected/suites_atom_get_opensearch.xml
index 494b7b4..68fbf0f 100644
--- a/tests/expected/suites_atom_get_opensearch.xml
+++ b/tests/expected/suites_atom_get_opensearch.xml
@@ -1,97 +1,110 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<atom:feed xmlns:os="http://a9.com/-/spec/opensearch/1.1/" xmlns:time="http://a9.com/-/opensearch/extensions/time/1.0/" xmlns:geo="http://a9.com/-/opensearch/extensions/geo/1.0/" xmlns:atom="http://www.w3.org/2005/Atom">
+<atom:feed xmlns:atom="http://www.w3.org/2005/Atom" xmlns:os="http://a9.com/-/spec/opensearch/1.1/">
   <atom:id>http://localhost/pycsw/csw.py?config=tests/suites/atom/default.cfg</atom:id>
   <atom:title>pycsw Geospatial Catalogue</atom:title>
   <os:totalResults>12</os:totalResults>
   <os:startIndex>1</os:startIndex>
   <os:itemsPerPage>10</os:itemsPerPage>
-  <atom:entry xmlns:georss="http://www.georss.org/georss" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.w3.org/2005/Atom http://www.kbcafe.com/rss/atom.xsd.xml">
-    <atom:category>Tourism--Greece</atom:category>
+  <atom:entry xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dc="http://purl.org/dc/elements/1.1/" xsi:schemaLocation="http://www.w3.org/2005/Atom http://www.kbcafe.com/rss/atom.xsd.xml">
+    <atom:category term="Tourism--Greece"/>
     <atom:id>urn:uuid:19887a8a-f6b0-4a63-ae56-7fba0e17801f</atom:id>
+    <dc:identifier>urn:uuid:19887a8a-f6b0-4a63-ae56-7fba0e17801f</dc:identifier>
     <atom:link href="http://localhost/pycsw/csw.py?config=tests/suites/atom/default.cfg?service=CSW&version=2.0.2&request=GetRepositoryItem&id=urn:uuid:19887a8a-f6b0-4a63-ae56-7fba0e17801f"/>
-    <atom:summary>Quisque lacus diam, placerat mollis, pharetra in, commodo sed, augue. Duis iaculis arcu vel arcu.</atom:summary>
     <atom:title>Lorem ipsum</atom:title>
+    <atom:updated>PYCSW_TIMESTAMP</atom:updated>
+    <atom:summary>Quisque lacus diam, placerat mollis, pharetra in, commodo sed, augue. Duis iaculis arcu vel arcu.</atom:summary>
   </atom:entry>
-  <atom:entry xmlns:georss="http://www.georss.org/georss" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:gml="http://www.opengis.net/gml" xsi:schemaLocation="http://www.w3.org/2005/Atom http://www.kbcafe.com/rss/atom.xsd.xml">
+  <atom:entry xmlns:georss="http://www.georss.org/georss" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:gml="http://www.opengis.net/gml" xsi:schemaLocation="http://www.w3.org/2005/Atom http://www.kbcafe.com/rss/atom.xsd.xml">
     <atom:id>urn:uuid:1ef30a8b-876d-4828-9246-c37ab4510bbd</atom:id>
+    <dc:identifier>urn:uuid:1ef30a8b-876d-4828-9246-c37ab4510bbd</dc:identifier>
     <atom:link href="http://localhost/pycsw/csw.py?config=tests/suites/atom/default.cfg?service=CSW&version=2.0.2&request=GetRepositoryItem&id=urn:uuid:1ef30a8b-876d-4828-9246-c37ab4510bbd"/>
+    <atom:title/>
+    <atom:updated>PYCSW_TIMESTAMP</atom:updated>
     <atom:summary>Proin sit amet justo. In justo. Aenean adipiscing nulla id tellus.</atom:summary>
     <georss:where>
-      <gml:Polygon srsName="urn:x-ogc:def:crs:EPSG:6.11:4326">
-        <gml:exterior>
-          <gml:LinearRing>
-            <gml:posList>60.04 13.75 68.41 13.75 68.41 17.92 60.04 17.92 60.04 13.75</gml:posList>
-          </gml:LinearRing>
-        </gml:exterior>
-      </gml:Polygon>
+      <gml:Envelope srsName="http://www.opengis.net/def/crs/EPSG/0/4326">
+        <gml:lowerCorner>60.04 13.75</gml:lowerCorner>
+        <gml:upperCorner>68.41 17.92</gml:upperCorner>
+      </gml:Envelope>
     </georss:where>
   </atom:entry>
-  <atom:entry xmlns:georss="http://www.georss.org/georss" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.w3.org/2005/Atom http://www.kbcafe.com/rss/atom.xsd.xml">
-    <atom:category>Marine sediments</atom:category>
+  <atom:entry xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dc="http://purl.org/dc/elements/1.1/" xsi:schemaLocation="http://www.w3.org/2005/Atom http://www.kbcafe.com/rss/atom.xsd.xml">
+    <atom:category term="Marine sediments"/>
     <atom:id>urn:uuid:66ae76b7-54ba-489b-a582-0f0633d96493</atom:id>
+    <dc:identifier>urn:uuid:66ae76b7-54ba-489b-a582-0f0633d96493</dc:identifier>
     <atom:link href="http://localhost/pycsw/csw.py?config=tests/suites/atom/default.cfg?service=CSW&version=2.0.2&request=GetRepositoryItem&id=urn:uuid:66ae76b7-54ba-489b-a582-0f0633d96493"/>
-    <atom:summary>Pellentesque tempus magna non sapien fringilla blandit.</atom:summary>
     <atom:title>Maecenas enim</atom:title>
+    <atom:updated>PYCSW_TIMESTAMP</atom:updated>
+    <atom:summary>Pellentesque tempus magna non sapien fringilla blandit.</atom:summary>
   </atom:entry>
-  <atom:entry xmlns:georss="http://www.georss.org/georss" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.w3.org/2005/Atom http://www.kbcafe.com/rss/atom.xsd.xml">
-    <atom:category>Vegetation</atom:category>
+  <atom:entry xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dc="http://purl.org/dc/elements/1.1/" xsi:schemaLocation="http://www.w3.org/2005/Atom http://www.kbcafe.com/rss/atom.xsd.xml">
+    <atom:category term="Vegetation"/>
     <atom:id>urn:uuid:6a3de50b-fa66-4b58-a0e6-ca146fdd18d4</atom:id>
+    <dc:identifier>urn:uuid:6a3de50b-fa66-4b58-a0e6-ca146fdd18d4</dc:identifier>
     <atom:link href="http://localhost/pycsw/csw.py?config=tests/suites/atom/default.cfg?service=CSW&version=2.0.2&request=GetRepositoryItem&id=urn:uuid:6a3de50b-fa66-4b58-a0e6-ca146fdd18d4"/>
     <atom:title>Ut facilisis justo ut lacus</atom:title>
+    <atom:updated>PYCSW_TIMESTAMP</atom:updated>
   </atom:entry>
-  <atom:entry xmlns:georss="http://www.georss.org/georss" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.w3.org/2005/Atom http://www.kbcafe.com/rss/atom.xsd.xml">
-    <atom:category>Hydrography--Dictionaries</atom:category>
+  <atom:entry xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dc="http://purl.org/dc/elements/1.1/" xsi:schemaLocation="http://www.w3.org/2005/Atom http://www.kbcafe.com/rss/atom.xsd.xml">
+    <atom:category term="Hydrography--Dictionaries"/>
     <atom:id>urn:uuid:784e2afd-a9fd-44a6-9a92-a3848371c8ec</atom:id>
+    <dc:identifier>urn:uuid:784e2afd-a9fd-44a6-9a92-a3848371c8ec</dc:identifier>
     <atom:link href="http://localhost/pycsw/csw.py?config=tests/suites/atom/default.cfg?service=CSW&version=2.0.2&request=GetRepositoryItem&id=urn:uuid:784e2afd-a9fd-44a6-9a92-a3848371c8ec"/>
-    <atom:summary>Vestibulum quis ipsum sit amet metus imperdiet vehicula. Nulla scelerisque cursus mi.</atom:summary>
     <atom:title>Aliquam fermentum purus quis arcu</atom:title>
+    <atom:updated>PYCSW_TIMESTAMP</atom:updated>
+    <atom:summary>Vestibulum quis ipsum sit amet metus imperdiet vehicula. Nulla scelerisque cursus mi.</atom:summary>
   </atom:entry>
-  <atom:entry xmlns:georss="http://www.georss.org/georss" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.w3.org/2005/Atom http://www.kbcafe.com/rss/atom.xsd.xml">
+  <atom:entry xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dc="http://purl.org/dc/elements/1.1/" xsi:schemaLocation="http://www.w3.org/2005/Atom http://www.kbcafe.com/rss/atom.xsd.xml">
     <atom:id>urn:uuid:829babb0-b2f1-49e1-8cd5-7b489fe71a1e</atom:id>
+    <dc:identifier>urn:uuid:829babb0-b2f1-49e1-8cd5-7b489fe71a1e</dc:identifier>
     <atom:link href="http://localhost/pycsw/csw.py?config=tests/suites/atom/default.cfg?service=CSW&version=2.0.2&request=GetRepositoryItem&id=urn:uuid:829babb0-b2f1-49e1-8cd5-7b489fe71a1e"/>
     <atom:title>Vestibulum massa purus</atom:title>
+    <atom:updated>PYCSW_TIMESTAMP</atom:updated>
   </atom:entry>
-  <atom:entry xmlns:georss="http://www.georss.org/georss" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.w3.org/2005/Atom http://www.kbcafe.com/rss/atom.xsd.xml">
-    <atom:category>Physiography-Landforms</atom:category>
+  <atom:entry xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dc="http://purl.org/dc/elements/1.1/" xsi:schemaLocation="http://www.w3.org/2005/Atom http://www.kbcafe.com/rss/atom.xsd.xml">
+    <atom:category term="Physiography-Landforms"/>
     <atom:id>urn:uuid:88247b56-4cbc-4df9-9860-db3f8042e357</atom:id>
+    <dc:identifier>urn:uuid:88247b56-4cbc-4df9-9860-db3f8042e357</dc:identifier>
     <atom:link href="http://localhost/pycsw/csw.py?config=tests/suites/atom/default.cfg?service=CSW&version=2.0.2&request=GetRepositoryItem&id=urn:uuid:88247b56-4cbc-4df9-9860-db3f8042e357"/>
+    <atom:title/>
+    <atom:updated>PYCSW_TIMESTAMP</atom:updated>
     <atom:summary>Donec scelerisque pede ut nisl luctus accumsan. Quisque ultrices, lorem eget feugiat fringilla, lorem dui porttitor ante, cursus ultrices magna odio eu neque.</atom:summary>
   </atom:entry>
-  <atom:entry xmlns:georss="http://www.georss.org/georss" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:gml="http://www.opengis.net/gml" xsi:schemaLocation="http://www.w3.org/2005/Atom http://www.kbcafe.com/rss/atom.xsd.xml">
-    <atom:category>Vegetation-Cropland</atom:category>
+  <atom:entry xmlns:georss="http://www.georss.org/georss" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:gml="http://www.opengis.net/gml" xsi:schemaLocation="http://www.w3.org/2005/Atom http://www.kbcafe.com/rss/atom.xsd.xml">
+    <atom:category term="Vegetation-Cropland"/>
     <atom:id>urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63</atom:id>
+    <dc:identifier>urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63</dc:identifier>
     <atom:link href="http://localhost/pycsw/csw.py?config=tests/suites/atom/default.cfg?service=CSW&version=2.0.2&request=GetRepositoryItem&id=urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63"/>
-    <atom:summary>Curabitur lacinia, ante non porta tempus, mi lorem feugiat odio, eget suscipit eros pede ac velit.</atom:summary>
     <atom:title>Mauris sed neque</atom:title>
+    <atom:updated>PYCSW_TIMESTAMP</atom:updated>
+    <atom:summary>Curabitur lacinia, ante non porta tempus, mi lorem feugiat odio, eget suscipit eros pede ac velit.</atom:summary>
     <georss:where>
-      <gml:Polygon srsName="urn:x-ogc:def:crs:EPSG:6.11:4326">
-        <gml:exterior>
-          <gml:LinearRing>
-            <gml:posList>47.59 -4.1 51.22 -4.1 51.22 0.89 47.59 0.89 47.59 -4.1</gml:posList>
-          </gml:LinearRing>
-        </gml:exterior>
-      </gml:Polygon>
+      <gml:Envelope srsName="http://www.opengis.net/def/crs/EPSG/0/4326">
+        <gml:lowerCorner>47.59 -4.1</gml:lowerCorner>
+        <gml:upperCorner>51.22 0.89</gml:upperCorner>
+      </gml:Envelope>
     </georss:where>
   </atom:entry>
-  <atom:entry xmlns:georss="http://www.georss.org/georss" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:gml="http://www.opengis.net/gml" xsi:schemaLocation="http://www.w3.org/2005/Atom http://www.kbcafe.com/rss/atom.xsd.xml">
-    <atom:category>Hydrography-Oceanographic</atom:category>
+  <atom:entry xmlns:georss="http://www.georss.org/georss" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:gml="http://www.opengis.net/gml" xsi:schemaLocation="http://www.w3.org/2005/Atom http://www.kbcafe.com/rss/atom.xsd.xml">
+    <atom:category term="Hydrography-Oceanographic"/>
     <atom:id>urn:uuid:9a669547-b69b-469f-a11f-2d875366bbdc</atom:id>
+    <dc:identifier>urn:uuid:9a669547-b69b-469f-a11f-2d875366bbdc</dc:identifier>
     <atom:link href="http://localhost/pycsw/csw.py?config=tests/suites/atom/default.cfg?service=CSW&version=2.0.2&request=GetRepositoryItem&id=urn:uuid:9a669547-b69b-469f-a11f-2d875366bbdc"/>
     <atom:title>Ñunç elementum</atom:title>
+    <atom:updated>PYCSW_TIMESTAMP</atom:updated>
     <georss:where>
-      <gml:Polygon srsName="urn:x-ogc:def:crs:EPSG:6.11:4326">
-        <gml:exterior>
-          <gml:LinearRing>
-            <gml:posList>44.79 -6.17 51.13 -6.17 51.13 -2.23 44.79 -2.23 44.79 -6.17</gml:posList>
-          </gml:LinearRing>
-        </gml:exterior>
-      </gml:Polygon>
+      <gml:Envelope srsName="http://www.opengis.net/def/crs/EPSG/0/4326">
+        <gml:lowerCorner>44.79 -6.17</gml:lowerCorner>
+        <gml:upperCorner>51.13 -2.23</gml:upperCorner>
+      </gml:Envelope>
     </georss:where>
   </atom:entry>
-  <atom:entry xmlns:georss="http://www.georss.org/georss" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.w3.org/2005/Atom http://www.kbcafe.com/rss/atom.xsd.xml">
+  <atom:entry xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dc="http://purl.org/dc/elements/1.1/" xsi:schemaLocation="http://www.w3.org/2005/Atom http://www.kbcafe.com/rss/atom.xsd.xml">
     <atom:id>urn:uuid:a06af396-3105-442d-8b40-22b57a90d2f2</atom:id>
+    <dc:identifier>urn:uuid:a06af396-3105-442d-8b40-22b57a90d2f2</dc:identifier>
     <atom:link href="http://localhost/pycsw/csw.py?config=tests/suites/atom/default.cfg?service=CSW&version=2.0.2&request=GetRepositoryItem&id=urn:uuid:a06af396-3105-442d-8b40-22b57a90d2f2"/>
     <atom:title>Lorem ipsum dolor sit amet</atom:title>
+    <atom:updated>PYCSW_TIMESTAMP</atom:updated>
   </atom:entry>
 </atom:feed>
diff --git a/tests/expected/suites_atom_post_DescribeRecord.xml b/tests/expected/suites_atom_post_DescribeRecord.xml
index 04284a4..5f82a7d 100644
--- a/tests/expected/suites_atom_post_DescribeRecord.xml
+++ b/tests/expected/suites_atom_post_DescribeRecord.xml
@@ -1,3 +1,3 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<csw:DescribeRecordResponse xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ows="http://www.opengis.net/ows" xmlns:fgdc="http://www.opengis.net/cat/csw/ [...]
+<csw:DescribeRecordResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/cat/csw/2.0.2 http://schemas.opengis.net/csw/2.0.2/CSW-discovery.xsd"/>
diff --git a/tests/expected/suites_atom_post_GetCapabilities.xml b/tests/expected/suites_atom_post_GetCapabilities.xml
index b1fa99b..7ce6b56 100644
--- a/tests/expected/suites_atom_post_GetCapabilities.xml
+++ b/tests/expected/suites_atom_post_GetCapabilities.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<csw:Capabilities xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ows="http://www.opengis.net/ows" xmlns:fgdc="http://www.opengis.net/cat/csw/csdgm" xml [...]
+<csw:Capabilities xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ogc="http://www.opengis.net/ogc" xmlns:ows="http://www.opengis.net/ows" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" updateSequence="PYCSW_UPDATESEQUENCE" ve [...]
   <ows:ServiceIdentification>
     <ows:Title>pycsw Geospatial Catalogue</ows:Title>
     <ows:Abstract>pycsw is an OGC CSW server implementation written in Python</ows:Abstract>
@@ -11,6 +11,7 @@
     </ows:Keywords>
     <ows:ServiceType codeSpace="OGC">CSW</ows:ServiceType>
     <ows:ServiceTypeVersion>2.0.2</ows:ServiceTypeVersion>
+    <ows:ServiceTypeVersion>3.0.0</ows:ServiceTypeVersion>
     <ows:Fees>None</ows:Fees>
     <ows:AccessConstraints>None</ows:AccessConstraints>
   </ows:ServiceIdentification>
@@ -49,19 +50,12 @@
         </ows:HTTP>
       </ows:DCP>
       <ows:Parameter name="sections">
+        <ows:Value>Filter_Capabilities</ows:Value>
+        <ows:Value>OperationsMetadata</ows:Value>
         <ows:Value>ServiceIdentification</ows:Value>
         <ows:Value>ServiceProvider</ows:Value>
-        <ows:Value>OperationsMetadata</ows:Value>
-        <ows:Value>Filter_Capabilities</ows:Value>
       </ows:Parameter>
     </ows:Operation>
-    <ows:Operation name="GetRepositoryItem">
-      <ows:DCP>
-        <ows:HTTP>
-          <ows:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/atom/default.cfg"/>
-        </ows:HTTP>
-      </ows:DCP>
-    </ows:Operation>
     <ows:Operation name="DescribeRecord">
       <ows:DCP>
         <ows:HTTP>
@@ -69,14 +63,14 @@
           <ows:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/atom/default.cfg"/>
         </ows:HTTP>
       </ows:DCP>
-      <ows:Parameter name="schemaLanguage">
-        <ows:Value>http://www.w3.org/XML/Schema</ows:Value>
-        <ows:Value>http://www.w3.org/TR/xmlschema-1/</ows:Value>
-        <ows:Value>http://www.w3.org/2001/XMLSchema</ows:Value>
-      </ows:Parameter>
       <ows:Parameter name="outputFormat">
-        <ows:Value>application/xml</ows:Value>
         <ows:Value>application/json</ows:Value>
+        <ows:Value>application/xml</ows:Value>
+      </ows:Parameter>
+      <ows:Parameter name="schemaLanguage">
+        <ows:Value>http://www.w3.org/2001/XMLSchema</ows:Value>
+        <ows:Value>http://www.w3.org/TR/xmlschema-1/</ows:Value>
+        <ows:Value>http://www.w3.org/XML/Schema</ows:Value>
       </ows:Parameter>
       <ows:Parameter name="typeName">
         <ows:Value>csw:Record</ows:Value>
@@ -90,64 +84,47 @@
         </ows:HTTP>
       </ows:DCP>
       <ows:Parameter name="ParameterName">
+        <ows:Value>DescribeRecord.outputFormat</ows:Value>
+        <ows:Value>DescribeRecord.schemaLanguage</ows:Value>
+        <ows:Value>DescribeRecord.typeName</ows:Value>
+        <ows:Value>GetCapabilities.sections</ows:Value>
+        <ows:Value>GetRecordById.ElementSetName</ows:Value>
+        <ows:Value>GetRecordById.outputFormat</ows:Value>
+        <ows:Value>GetRecordById.outputSchema</ows:Value>
+        <ows:Value>GetRecords.CONSTRAINTLANGUAGE</ows:Value>
+        <ows:Value>GetRecords.ElementSetName</ows:Value>
         <ows:Value>GetRecords.outputFormat</ows:Value>
         <ows:Value>GetRecords.outputSchema</ows:Value>
-        <ows:Value>GetRecords.CONSTRAINTLANGUAGE</ows:Value>
         <ows:Value>GetRecords.resultType</ows:Value>
         <ows:Value>GetRecords.typeNames</ows:Value>
-        <ows:Value>GetRecords.ElementSetName</ows:Value>
-        <ows:Value>GetCapabilities.sections</ows:Value>
-        <ows:Value>GetRecordById.outputFormat</ows:Value>
-        <ows:Value>GetRecordById.outputSchema</ows:Value>
-        <ows:Value>GetRecordById.ElementSetName</ows:Value>
-        <ows:Value>DescribeRecord.schemaLanguage</ows:Value>
-        <ows:Value>DescribeRecord.outputFormat</ows:Value>
-        <ows:Value>DescribeRecord.typeName</ows:Value>
       </ows:Parameter>
     </ows:Operation>
-    <ows:Operation name="GetRecordById">
+    <ows:Operation name="GetRecords">
       <ows:DCP>
         <ows:HTTP>
           <ows:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/atom/default.cfg"/>
           <ows:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/atom/default.cfg"/>
         </ows:HTTP>
       </ows:DCP>
-      <ows:Parameter name="outputFormat">
-        <ows:Value>application/xml</ows:Value>
-        <ows:Value>application/json</ows:Value>
-      </ows:Parameter>
-      <ows:Parameter name="outputSchema">
-        <ows:Value>http://www.opengis.net/cat/csw/2.0.2</ows:Value>
-        <ows:Value>http://www.w3.org/2005/Atom</ows:Value>
-        <ows:Value>http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/</ows:Value>
-        <ows:Value>http://www.opengis.net/cat/csw/csdgm</ows:Value>
+      <ows:Parameter name="CONSTRAINTLANGUAGE">
+        <ows:Value>CQL_TEXT</ows:Value>
+        <ows:Value>FILTER</ows:Value>
       </ows:Parameter>
       <ows:Parameter name="ElementSetName">
         <ows:Value>brief</ows:Value>
-        <ows:Value>summary</ows:Value>
         <ows:Value>full</ows:Value>
+        <ows:Value>summary</ows:Value>
       </ows:Parameter>
-    </ows:Operation>
-    <ows:Operation name="GetRecords">
-      <ows:DCP>
-        <ows:HTTP>
-          <ows:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/atom/default.cfg"/>
-          <ows:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/atom/default.cfg"/>
-        </ows:HTTP>
-      </ows:DCP>
       <ows:Parameter name="outputFormat">
-        <ows:Value>application/xml</ows:Value>
         <ows:Value>application/json</ows:Value>
+        <ows:Value>application/xml</ows:Value>
       </ows:Parameter>
       <ows:Parameter name="outputSchema">
-        <ows:Value>http://www.opengis.net/cat/csw/2.0.2</ows:Value>
-        <ows:Value>http://www.w3.org/2005/Atom</ows:Value>
         <ows:Value>http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/</ows:Value>
+        <ows:Value>http://www.interlis.ch/INTERLIS2.3</ows:Value>
+        <ows:Value>http://www.opengis.net/cat/csw/2.0.2</ows:Value>
         <ows:Value>http://www.opengis.net/cat/csw/csdgm</ows:Value>
-      </ows:Parameter>
-      <ows:Parameter name="CONSTRAINTLANGUAGE">
-        <ows:Value>FILTER</ows:Value>
-        <ows:Value>CQL_TEXT</ows:Value>
+        <ows:Value>http://www.w3.org/2005/Atom</ows:Value>
       </ows:Parameter>
       <ows:Parameter name="resultType">
         <ows:Value>hits</ows:Value>
@@ -157,39 +134,66 @@
       <ows:Parameter name="typeNames">
         <ows:Value>csw:Record</ows:Value>
       </ows:Parameter>
-      <ows:Parameter name="ElementSetName">
-        <ows:Value>brief</ows:Value>
-        <ows:Value>summary</ows:Value>
-        <ows:Value>full</ows:Value>
-      </ows:Parameter>
       <ows:Constraint name="SupportedDublinCoreQueryables">
+        <ows:Value>csw:AnyText</ows:Value>
         <ows:Value>dc:contributor</ows:Value>
-        <ows:Value>dc:source</ows:Value>
-        <ows:Value>dc:language</ows:Value>
-        <ows:Value>dc:title</ows:Value>
-        <ows:Value>dc:subject</ows:Value>
         <ows:Value>dc:creator</ows:Value>
-        <ows:Value>dc:type</ows:Value>
-        <ows:Value>ows:BoundingBox</ows:Value>
-        <ows:Value>dct:modified</ows:Value>
-        <ows:Value>dct:abstract</ows:Value>
-        <ows:Value>dc:relation</ows:Value>
         <ows:Value>dc:date</ows:Value>
+        <ows:Value>dc:format</ows:Value>
         <ows:Value>dc:identifier</ows:Value>
+        <ows:Value>dc:language</ows:Value>
         <ows:Value>dc:publisher</ows:Value>
-        <ows:Value>dc:format</ows:Value>
-        <ows:Value>csw:AnyText</ows:Value>
+        <ows:Value>dc:relation</ows:Value>
         <ows:Value>dc:rights</ows:Value>
+        <ows:Value>dc:source</ows:Value>
+        <ows:Value>dc:subject</ows:Value>
+        <ows:Value>dc:title</ows:Value>
+        <ows:Value>dc:type</ows:Value>
+        <ows:Value>dct:abstract</ows:Value>
+        <ows:Value>dct:modified</ows:Value>
+        <ows:Value>ows:BoundingBox</ows:Value>
       </ows:Constraint>
     </ows:Operation>
-    <ows:Parameter name="version">
-      <ows:Value>2.0.2</ows:Value>
-    </ows:Parameter>
+    <ows:Operation name="GetRecordById">
+      <ows:DCP>
+        <ows:HTTP>
+          <ows:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/atom/default.cfg"/>
+          <ows:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/atom/default.cfg"/>
+        </ows:HTTP>
+      </ows:DCP>
+      <ows:Parameter name="ElementSetName">
+        <ows:Value>brief</ows:Value>
+        <ows:Value>full</ows:Value>
+        <ows:Value>summary</ows:Value>
+      </ows:Parameter>
+      <ows:Parameter name="outputFormat">
+        <ows:Value>application/json</ows:Value>
+        <ows:Value>application/xml</ows:Value>
+      </ows:Parameter>
+      <ows:Parameter name="outputSchema">
+        <ows:Value>http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/</ows:Value>
+        <ows:Value>http://www.interlis.ch/INTERLIS2.3</ows:Value>
+        <ows:Value>http://www.opengis.net/cat/csw/2.0.2</ows:Value>
+        <ows:Value>http://www.opengis.net/cat/csw/csdgm</ows:Value>
+        <ows:Value>http://www.w3.org/2005/Atom</ows:Value>
+      </ows:Parameter>
+    </ows:Operation>
+    <ows:Operation name="GetRepositoryItem">
+      <ows:DCP>
+        <ows:HTTP>
+          <ows:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/atom/default.cfg"/>
+        </ows:HTTP>
+      </ows:DCP>
+    </ows:Operation>
     <ows:Parameter name="service">
       <ows:Value>CSW</ows:Value>
     </ows:Parameter>
-    <ows:Constraint name="XPathQueryables">
-      <ows:Value>allowed</ows:Value>
+    <ows:Parameter name="version">
+      <ows:Value>2.0.2</ows:Value>
+      <ows:Value>3.0.0</ows:Value>
+    </ows:Parameter>
+    <ows:Constraint name="FederatedCatalogues">
+      <ows:Value>http://geo.data.gov/geoportal/csw/discovery</ows:Value>
     </ows:Constraint>
     <ows:Constraint name="MaxRecordDefault">
       <ows:Value>10</ows:Value>
@@ -198,8 +202,8 @@
       <ows:Value>XML</ows:Value>
       <ows:Value>SOAP</ows:Value>
     </ows:Constraint>
-    <ows:Constraint name="FederatedCatalogues">
-      <ows:Value>http://geo.data.gov/geoportal/csw/discovery</ows:Value>
+    <ows:Constraint name="XPathQueryables">
+      <ows:Value>allowed</ows:Value>
     </ows:Constraint>
   </ows:OperationsMetadata>
   <ogc:Filter_Capabilities>
@@ -229,11 +233,11 @@
       <ogc:ComparisonOperators>
         <ogc:ComparisonOperator>Between</ogc:ComparisonOperator>
         <ogc:ComparisonOperator>EqualTo</ogc:ComparisonOperator>
-        <ogc:ComparisonOperator>LessThanEqualTo</ogc:ComparisonOperator>
         <ogc:ComparisonOperator>GreaterThan</ogc:ComparisonOperator>
-        <ogc:ComparisonOperator>Like</ogc:ComparisonOperator>
-        <ogc:ComparisonOperator>LessThan</ogc:ComparisonOperator>
         <ogc:ComparisonOperator>GreaterThanEqualTo</ogc:ComparisonOperator>
+        <ogc:ComparisonOperator>LessThan</ogc:ComparisonOperator>
+        <ogc:ComparisonOperator>LessThanEqualTo</ogc:ComparisonOperator>
+        <ogc:ComparisonOperator>Like</ogc:ComparisonOperator>
         <ogc:ComparisonOperator>NotEqualTo</ogc:ComparisonOperator>
         <ogc:ComparisonOperator>NullCheck</ogc:ComparisonOperator>
       </ogc:ComparisonOperators>
diff --git a/tests/expected/suites_atom_post_GetRecords-filter-bbox.xml b/tests/expected/suites_atom_post_GetRecords-filter-bbox.xml
index 9f6eec9..c345e05 100644
--- a/tests/expected/suites_atom_post_GetRecords-filter-bbox.xml
+++ b/tests/expected/suites_atom_post_GetRecords-filter-bbox.xml
@@ -1,37 +1,35 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<csw:GetRecordsResponse xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ows="http://www.opengis.net/ows" xmlns:fgdc="http://www.opengis.net/cat/csw/csdg [...]
+<csw:GetRecordsResponse xmlns:atom="http://www.w3.org/2005/Atom" xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.0.2" xsi:schemaLocation="http://www.opengis.net/cat/csw/2.0.2 ht [...]
   <csw:SearchStatus timestamp="PYCSW_TIMESTAMP"/>
   <csw:SearchResults nextRecord="0" numberOfRecordsMatched="2" numberOfRecordsReturned="2" recordSchema="http://www.w3.org/2005/Atom" elementSet="brief">
     <atom:entry xmlns:georss="http://www.georss.org/georss" xsi:schemaLocation="http://www.w3.org/2005/Atom http://www.kbcafe.com/rss/atom.xsd.xml">
-      <atom:category>Vegetation-Cropland</atom:category>
+      <atom:category term="Vegetation-Cropland"/>
       <atom:id>urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63</atom:id>
+      <dc:identifier>urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63</dc:identifier>
       <atom:link href="http://localhost/pycsw/csw.py?config=tests/suites/atom/default.cfg?service=CSW&version=2.0.2&request=GetRepositoryItem&id=urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63"/>
-      <atom:summary>Curabitur lacinia, ante non porta tempus, mi lorem feugiat odio, eget suscipit eros pede ac velit.</atom:summary>
       <atom:title>Mauris sed neque</atom:title>
+      <atom:updated>PYCSW_TIMESTAMP</atom:updated>
+      <atom:summary>Curabitur lacinia, ante non porta tempus, mi lorem feugiat odio, eget suscipit eros pede ac velit.</atom:summary>
       <georss:where>
-        <gml:Polygon srsName="urn:x-ogc:def:crs:EPSG:6.11:4326">
-          <gml:exterior>
-            <gml:LinearRing>
-              <gml:posList>47.59 -4.1 51.22 -4.1 51.22 0.89 47.59 0.89 47.59 -4.1</gml:posList>
-            </gml:LinearRing>
-          </gml:exterior>
-        </gml:Polygon>
+        <gml:Envelope srsName="http://www.opengis.net/def/crs/EPSG/0/4326">
+          <gml:lowerCorner>47.59 -4.1</gml:lowerCorner>
+          <gml:upperCorner>51.22 0.89</gml:upperCorner>
+        </gml:Envelope>
       </georss:where>
     </atom:entry>
     <atom:entry xmlns:georss="http://www.georss.org/georss" xsi:schemaLocation="http://www.w3.org/2005/Atom http://www.kbcafe.com/rss/atom.xsd.xml">
-      <atom:category>Hydrography-Oceanographic</atom:category>
+      <atom:category term="Hydrography-Oceanographic"/>
       <atom:id>urn:uuid:9a669547-b69b-469f-a11f-2d875366bbdc</atom:id>
+      <dc:identifier>urn:uuid:9a669547-b69b-469f-a11f-2d875366bbdc</dc:identifier>
       <atom:link href="http://localhost/pycsw/csw.py?config=tests/suites/atom/default.cfg?service=CSW&version=2.0.2&request=GetRepositoryItem&id=urn:uuid:9a669547-b69b-469f-a11f-2d875366bbdc"/>
       <atom:title>Ñunç elementum</atom:title>
+      <atom:updated>PYCSW_TIMESTAMP</atom:updated>
       <georss:where>
-        <gml:Polygon srsName="urn:x-ogc:def:crs:EPSG:6.11:4326">
-          <gml:exterior>
-            <gml:LinearRing>
-              <gml:posList>44.79 -6.17 51.13 -6.17 51.13 -2.23 44.79 -2.23 44.79 -6.17</gml:posList>
-            </gml:LinearRing>
-          </gml:exterior>
-        </gml:Polygon>
+        <gml:Envelope srsName="http://www.opengis.net/def/crs/EPSG/0/4326">
+          <gml:lowerCorner>44.79 -6.17</gml:lowerCorner>
+          <gml:upperCorner>51.13 -2.23</gml:upperCorner>
+        </gml:Envelope>
       </georss:where>
     </atom:entry>
   </csw:SearchResults>
diff --git a/tests/expected/suites_cite_get_27e17158-c57a-4493-92ac-dba8934cf462.xml b/tests/expected/suites_cite_get_27e17158-c57a-4493-92ac-dba8934cf462.xml
index 5c5c068..2d6fc73 100644
--- a/tests/expected/suites_cite_get_27e17158-c57a-4493-92ac-dba8934cf462.xml
+++ b/tests/expected/suites_cite_get_27e17158-c57a-4493-92ac-dba8934cf462.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<csw:Capabilities xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ows="http://www.opengis.net/ows" xmlns:fgdc="http://www.opengis.net/cat/csw/csdgm" xml [...]
+<csw:Capabilities xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ogc="http://www.opengis.net/ogc" xmlns:ows="http://www.opengis.net/ows" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" updateSequence="PYCSW_UPDATESEQUENCE" ve [...]
   <ows:ServiceIdentification>
     <ows:Title>pycsw Geospatial Catalogue</ows:Title>
     <ows:Abstract>pycsw is an OGC CSW server implementation written in Python</ows:Abstract>
@@ -11,6 +11,7 @@
     </ows:Keywords>
     <ows:ServiceType codeSpace="OGC">CSW</ows:ServiceType>
     <ows:ServiceTypeVersion>2.0.2</ows:ServiceTypeVersion>
+    <ows:ServiceTypeVersion>3.0.0</ows:ServiceTypeVersion>
     <ows:Fees>None</ows:Fees>
     <ows:AccessConstraints>None</ows:AccessConstraints>
   </ows:ServiceIdentification>
@@ -49,26 +50,12 @@
         </ows:HTTP>
       </ows:DCP>
       <ows:Parameter name="sections">
+        <ows:Value>Filter_Capabilities</ows:Value>
+        <ows:Value>OperationsMetadata</ows:Value>
         <ows:Value>ServiceIdentification</ows:Value>
         <ows:Value>ServiceProvider</ows:Value>
-        <ows:Value>OperationsMetadata</ows:Value>
-        <ows:Value>Filter_Capabilities</ows:Value>
       </ows:Parameter>
     </ows:Operation>
-    <ows:Operation name="Transaction">
-      <ows:DCP>
-        <ows:HTTP>
-          <ows:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/cite/default.cfg"/>
-        </ows:HTTP>
-      </ows:DCP>
-    </ows:Operation>
-    <ows:Operation name="GetRepositoryItem">
-      <ows:DCP>
-        <ows:HTTP>
-          <ows:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/cite/default.cfg"/>
-        </ows:HTTP>
-      </ows:DCP>
-    </ows:Operation>
     <ows:Operation name="DescribeRecord">
       <ows:DCP>
         <ows:HTTP>
@@ -76,14 +63,14 @@
           <ows:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/cite/default.cfg"/>
         </ows:HTTP>
       </ows:DCP>
-      <ows:Parameter name="schemaLanguage">
-        <ows:Value>http://www.w3.org/XML/Schema</ows:Value>
-        <ows:Value>http://www.w3.org/TR/xmlschema-1/</ows:Value>
-        <ows:Value>http://www.w3.org/2001/XMLSchema</ows:Value>
-      </ows:Parameter>
       <ows:Parameter name="outputFormat">
-        <ows:Value>application/xml</ows:Value>
         <ows:Value>application/json</ows:Value>
+        <ows:Value>application/xml</ows:Value>
+      </ows:Parameter>
+      <ows:Parameter name="schemaLanguage">
+        <ows:Value>http://www.w3.org/2001/XMLSchema</ows:Value>
+        <ows:Value>http://www.w3.org/TR/xmlschema-1/</ows:Value>
+        <ows:Value>http://www.w3.org/XML/Schema</ows:Value>
       </ows:Parameter>
       <ows:Parameter name="typeName">
         <ows:Value>csw:Record</ows:Value>
@@ -97,65 +84,49 @@
         </ows:HTTP>
       </ows:DCP>
       <ows:Parameter name="ParameterName">
-        <ows:Value>GetCapabilities.sections</ows:Value>
-        <ows:Value>DescribeRecord.schemaLanguage</ows:Value>
         <ows:Value>DescribeRecord.outputFormat</ows:Value>
+        <ows:Value>DescribeRecord.schemaLanguage</ows:Value>
         <ows:Value>DescribeRecord.typeName</ows:Value>
+        <ows:Value>GetCapabilities.sections</ows:Value>
+        <ows:Value>GetRecordById.ElementSetName</ows:Value>
         <ows:Value>GetRecordById.outputFormat</ows:Value>
         <ows:Value>GetRecordById.outputSchema</ows:Value>
-        <ows:Value>GetRecordById.ElementSetName</ows:Value>
+        <ows:Value>GetRecords.CONSTRAINTLANGUAGE</ows:Value>
+        <ows:Value>GetRecords.ElementSetName</ows:Value>
         <ows:Value>GetRecords.outputFormat</ows:Value>
         <ows:Value>GetRecords.outputSchema</ows:Value>
-        <ows:Value>GetRecords.CONSTRAINTLANGUAGE</ows:Value>
         <ows:Value>GetRecords.resultType</ows:Value>
         <ows:Value>GetRecords.typeNames</ows:Value>
-        <ows:Value>GetRecords.ElementSetName</ows:Value>
         <ows:Value>Harvest.ResourceType</ows:Value>
+        <ows:Value>Transaction.TransactionSchemas</ows:Value>
       </ows:Parameter>
     </ows:Operation>
-    <ows:Operation name="GetRecordById">
+    <ows:Operation name="GetRecords">
       <ows:DCP>
         <ows:HTTP>
           <ows:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/cite/default.cfg"/>
           <ows:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/cite/default.cfg"/>
         </ows:HTTP>
       </ows:DCP>
-      <ows:Parameter name="outputFormat">
-        <ows:Value>application/xml</ows:Value>
-        <ows:Value>application/json</ows:Value>
-      </ows:Parameter>
-      <ows:Parameter name="outputSchema">
-        <ows:Value>http://www.opengis.net/cat/csw/2.0.2</ows:Value>
-        <ows:Value>http://www.w3.org/2005/Atom</ows:Value>
-        <ows:Value>http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/</ows:Value>
-        <ows:Value>http://www.opengis.net/cat/csw/csdgm</ows:Value>
+      <ows:Parameter name="CONSTRAINTLANGUAGE">
+        <ows:Value>CQL_TEXT</ows:Value>
+        <ows:Value>FILTER</ows:Value>
       </ows:Parameter>
       <ows:Parameter name="ElementSetName">
         <ows:Value>brief</ows:Value>
-        <ows:Value>summary</ows:Value>
         <ows:Value>full</ows:Value>
+        <ows:Value>summary</ows:Value>
       </ows:Parameter>
-    </ows:Operation>
-    <ows:Operation name="GetRecords">
-      <ows:DCP>
-        <ows:HTTP>
-          <ows:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/cite/default.cfg"/>
-          <ows:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/cite/default.cfg"/>
-        </ows:HTTP>
-      </ows:DCP>
       <ows:Parameter name="outputFormat">
-        <ows:Value>application/xml</ows:Value>
         <ows:Value>application/json</ows:Value>
+        <ows:Value>application/xml</ows:Value>
       </ows:Parameter>
       <ows:Parameter name="outputSchema">
-        <ows:Value>http://www.opengis.net/cat/csw/2.0.2</ows:Value>
-        <ows:Value>http://www.w3.org/2005/Atom</ows:Value>
         <ows:Value>http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/</ows:Value>
+        <ows:Value>http://www.interlis.ch/INTERLIS2.3</ows:Value>
+        <ows:Value>http://www.opengis.net/cat/csw/2.0.2</ows:Value>
         <ows:Value>http://www.opengis.net/cat/csw/csdgm</ows:Value>
-      </ows:Parameter>
-      <ows:Parameter name="CONSTRAINTLANGUAGE">
-        <ows:Value>FILTER</ows:Value>
-        <ows:Value>CQL_TEXT</ows:Value>
+        <ows:Value>http://www.w3.org/2005/Atom</ows:Value>
       </ows:Parameter>
       <ows:Parameter name="resultType">
         <ows:Value>hits</ows:Value>
@@ -165,60 +136,110 @@
       <ows:Parameter name="typeNames">
         <ows:Value>csw:Record</ows:Value>
       </ows:Parameter>
-      <ows:Parameter name="ElementSetName">
-        <ows:Value>brief</ows:Value>
-        <ows:Value>summary</ows:Value>
-        <ows:Value>full</ows:Value>
-      </ows:Parameter>
       <ows:Constraint name="SupportedDublinCoreQueryables">
+        <ows:Value>csw:AnyText</ows:Value>
         <ows:Value>dc:contributor</ows:Value>
-        <ows:Value>dc:source</ows:Value>
-        <ows:Value>dc:language</ows:Value>
-        <ows:Value>dc:title</ows:Value>
-        <ows:Value>dc:subject</ows:Value>
         <ows:Value>dc:creator</ows:Value>
-        <ows:Value>dc:type</ows:Value>
-        <ows:Value>ows:BoundingBox</ows:Value>
-        <ows:Value>dct:modified</ows:Value>
-        <ows:Value>dct:abstract</ows:Value>
-        <ows:Value>dc:relation</ows:Value>
         <ows:Value>dc:date</ows:Value>
+        <ows:Value>dc:format</ows:Value>
         <ows:Value>dc:identifier</ows:Value>
+        <ows:Value>dc:language</ows:Value>
         <ows:Value>dc:publisher</ows:Value>
-        <ows:Value>dc:format</ows:Value>
-        <ows:Value>csw:AnyText</ows:Value>
+        <ows:Value>dc:relation</ows:Value>
         <ows:Value>dc:rights</ows:Value>
+        <ows:Value>dc:source</ows:Value>
+        <ows:Value>dc:subject</ows:Value>
+        <ows:Value>dc:title</ows:Value>
+        <ows:Value>dc:type</ows:Value>
+        <ows:Value>dct:abstract</ows:Value>
+        <ows:Value>dct:modified</ows:Value>
+        <ows:Value>ows:BoundingBox</ows:Value>
       </ows:Constraint>
     </ows:Operation>
-    <ows:Operation name="Harvest">
+    <ows:Operation name="GetRecordById">
       <ows:DCP>
         <ows:HTTP>
+          <ows:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/cite/default.cfg"/>
           <ows:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/cite/default.cfg"/>
         </ows:HTTP>
       </ows:DCP>
-      <ows:Parameter name="ResourceType">
+      <ows:Parameter name="ElementSetName">
+        <ows:Value>brief</ows:Value>
+        <ows:Value>full</ows:Value>
+        <ows:Value>summary</ows:Value>
+      </ows:Parameter>
+      <ows:Parameter name="outputFormat">
+        <ows:Value>application/json</ows:Value>
+        <ows:Value>application/xml</ows:Value>
+      </ows:Parameter>
+      <ows:Parameter name="outputSchema">
+        <ows:Value>http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/</ows:Value>
+        <ows:Value>http://www.interlis.ch/INTERLIS2.3</ows:Value>
         <ows:Value>http://www.opengis.net/cat/csw/2.0.2</ows:Value>
-        <ows:Value>http://www.opengis.net/wms</ows:Value>
-        <ows:Value>http://www.opengis.net/wfs</ows:Value>
-        <ows:Value>http://www.opengis.net/wcs</ows:Value>
-        <ows:Value>http://www.opengis.net/wps/1.0.0</ows:Value>
+        <ows:Value>http://www.opengis.net/cat/csw/csdgm</ows:Value>
+        <ows:Value>http://www.w3.org/2005/Atom</ows:Value>
+      </ows:Parameter>
+    </ows:Operation>
+    <ows:Operation name="GetRepositoryItem">
+      <ows:DCP>
+        <ows:HTTP>
+          <ows:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/cite/default.cfg"/>
+        </ows:HTTP>
+      </ows:DCP>
+    </ows:Operation>
+    <ows:Operation name="Transaction">
+      <ows:DCP>
+        <ows:HTTP>
+          <ows:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/cite/default.cfg"/>
+        </ows:HTTP>
+      </ows:DCP>
+      <ows:Parameter name="TransactionSchemas">
+        <ows:Value>http://www.isotc211.org/2005/gmi</ows:Value>
+        <ows:Value>http://www.opengis.net/cat/csw/2.0.2</ows:Value>
+        <ows:Value>http://www.opengis.net/cat/csw/3.0</ows:Value>
         <ows:Value>http://www.opengis.net/sos/1.0</ows:Value>
         <ows:Value>http://www.opengis.net/sos/2.0</ows:Value>
-        <ows:Value>http://www.isotc211.org/2005/gmi</ows:Value>
+        <ows:Value>http://www.opengis.net/wcs</ows:Value>
+        <ows:Value>http://www.opengis.net/wfs</ows:Value>
+        <ows:Value>http://www.opengis.net/wms</ows:Value>
+        <ows:Value>http://www.opengis.net/wmts/1.0</ows:Value>
+        <ows:Value>http://www.opengis.net/wps/1.0.0</ows:Value>
         <ows:Value>urn:geoss:waf</ows:Value>
-        <ows:Value>http://www.w3.org/2005/Atom</ows:Value>
+      </ows:Parameter>
+    </ows:Operation>
+    <ows:Operation name="Harvest">
+      <ows:DCP>
+        <ows:HTTP>
+          <ows:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/cite/default.cfg"/>
+        </ows:HTTP>
+      </ows:DCP>
+      <ows:Parameter name="ResourceType">
         <ows:Value>http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/</ows:Value>
+        <ows:Value>http://www.interlis.ch/INTERLIS2.3</ows:Value>
+        <ows:Value>http://www.isotc211.org/2005/gmi</ows:Value>
+        <ows:Value>http://www.opengis.net/cat/csw/2.0.2</ows:Value>
+        <ows:Value>http://www.opengis.net/cat/csw/3.0</ows:Value>
         <ows:Value>http://www.opengis.net/cat/csw/csdgm</ows:Value>
+        <ows:Value>http://www.opengis.net/sos/1.0</ows:Value>
+        <ows:Value>http://www.opengis.net/sos/2.0</ows:Value>
+        <ows:Value>http://www.opengis.net/wcs</ows:Value>
+        <ows:Value>http://www.opengis.net/wfs</ows:Value>
+        <ows:Value>http://www.opengis.net/wms</ows:Value>
+        <ows:Value>http://www.opengis.net/wmts/1.0</ows:Value>
+        <ows:Value>http://www.opengis.net/wps/1.0.0</ows:Value>
+        <ows:Value>http://www.w3.org/2005/Atom</ows:Value>
+        <ows:Value>urn:geoss:waf</ows:Value>
       </ows:Parameter>
     </ows:Operation>
-    <ows:Parameter name="version">
-      <ows:Value>2.0.2</ows:Value>
-    </ows:Parameter>
     <ows:Parameter name="service">
       <ows:Value>CSW</ows:Value>
     </ows:Parameter>
-    <ows:Constraint name="XPathQueryables">
-      <ows:Value>allowed</ows:Value>
+    <ows:Parameter name="version">
+      <ows:Value>2.0.2</ows:Value>
+      <ows:Value>3.0.0</ows:Value>
+    </ows:Parameter>
+    <ows:Constraint name="FederatedCatalogues">
+      <ows:Value>http://geo.data.gov/geoportal/csw/discovery</ows:Value>
     </ows:Constraint>
     <ows:Constraint name="MaxRecordDefault">
       <ows:Value>10</ows:Value>
@@ -227,8 +248,8 @@
       <ows:Value>XML</ows:Value>
       <ows:Value>SOAP</ows:Value>
     </ows:Constraint>
-    <ows:Constraint name="FederatedCatalogues">
-      <ows:Value>http://geo.data.gov/geoportal/csw/discovery</ows:Value>
+    <ows:Constraint name="XPathQueryables">
+      <ows:Value>allowed</ows:Value>
     </ows:Constraint>
   </ows:OperationsMetadata>
   <ogc:Filter_Capabilities>
@@ -258,11 +279,11 @@
       <ogc:ComparisonOperators>
         <ogc:ComparisonOperator>Between</ogc:ComparisonOperator>
         <ogc:ComparisonOperator>EqualTo</ogc:ComparisonOperator>
-        <ogc:ComparisonOperator>LessThanEqualTo</ogc:ComparisonOperator>
         <ogc:ComparisonOperator>GreaterThan</ogc:ComparisonOperator>
-        <ogc:ComparisonOperator>Like</ogc:ComparisonOperator>
-        <ogc:ComparisonOperator>LessThan</ogc:ComparisonOperator>
         <ogc:ComparisonOperator>GreaterThanEqualTo</ogc:ComparisonOperator>
+        <ogc:ComparisonOperator>LessThan</ogc:ComparisonOperator>
+        <ogc:ComparisonOperator>LessThanEqualTo</ogc:ComparisonOperator>
+        <ogc:ComparisonOperator>Like</ogc:ComparisonOperator>
         <ogc:ComparisonOperator>NotEqualTo</ogc:ComparisonOperator>
         <ogc:ComparisonOperator>NullCheck</ogc:ComparisonOperator>
       </ogc:ComparisonOperators>
diff --git a/tests/expected/suites_cite_get_27f69b66-5f05-4311-a89c-73ca55c2686b.xml b/tests/expected/suites_cite_get_27f69b66-5f05-4311-a89c-73ca55c2686b.xml
index 82d7b75..ccdc8dc 100644
--- a/tests/expected/suites_cite_get_27f69b66-5f05-4311-a89c-73ca55c2686b.xml
+++ b/tests/expected/suites_cite_get_27f69b66-5f05-4311-a89c-73ca55c2686b.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<csw:GetRecordByIdResponse xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ows="http://www.opengis.net/ows" xmlns:fgdc="http://www.opengis.net/cat/csw/c [...]
+<csw:GetRecordByIdResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/cat/csw/2.0.2 http://schemas.opengis.net/csw/2.0.2/CSW-discovery.xsd">
   <csw:BriefRecord>
     <dc:identifier>urn:uuid:19887a8a-f6b0-4a63-ae56-7fba0e17801f</dc:identifier>
     <dc:title>Lorem ipsum</dc:title>
diff --git a/tests/expected/suites_cite_get_2ab7d1fa-885b-459f-80e4-b6282eab4f8c.xml b/tests/expected/suites_cite_get_2ab7d1fa-885b-459f-80e4-b6282eab4f8c.xml
index 5c5c068..2d6fc73 100644
--- a/tests/expected/suites_cite_get_2ab7d1fa-885b-459f-80e4-b6282eab4f8c.xml
+++ b/tests/expected/suites_cite_get_2ab7d1fa-885b-459f-80e4-b6282eab4f8c.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<csw:Capabilities xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ows="http://www.opengis.net/ows" xmlns:fgdc="http://www.opengis.net/cat/csw/csdgm" xml [...]
+<csw:Capabilities xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ogc="http://www.opengis.net/ogc" xmlns:ows="http://www.opengis.net/ows" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" updateSequence="PYCSW_UPDATESEQUENCE" ve [...]
   <ows:ServiceIdentification>
     <ows:Title>pycsw Geospatial Catalogue</ows:Title>
     <ows:Abstract>pycsw is an OGC CSW server implementation written in Python</ows:Abstract>
@@ -11,6 +11,7 @@
     </ows:Keywords>
     <ows:ServiceType codeSpace="OGC">CSW</ows:ServiceType>
     <ows:ServiceTypeVersion>2.0.2</ows:ServiceTypeVersion>
+    <ows:ServiceTypeVersion>3.0.0</ows:ServiceTypeVersion>
     <ows:Fees>None</ows:Fees>
     <ows:AccessConstraints>None</ows:AccessConstraints>
   </ows:ServiceIdentification>
@@ -49,26 +50,12 @@
         </ows:HTTP>
       </ows:DCP>
       <ows:Parameter name="sections">
+        <ows:Value>Filter_Capabilities</ows:Value>
+        <ows:Value>OperationsMetadata</ows:Value>
         <ows:Value>ServiceIdentification</ows:Value>
         <ows:Value>ServiceProvider</ows:Value>
-        <ows:Value>OperationsMetadata</ows:Value>
-        <ows:Value>Filter_Capabilities</ows:Value>
       </ows:Parameter>
     </ows:Operation>
-    <ows:Operation name="Transaction">
-      <ows:DCP>
-        <ows:HTTP>
-          <ows:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/cite/default.cfg"/>
-        </ows:HTTP>
-      </ows:DCP>
-    </ows:Operation>
-    <ows:Operation name="GetRepositoryItem">
-      <ows:DCP>
-        <ows:HTTP>
-          <ows:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/cite/default.cfg"/>
-        </ows:HTTP>
-      </ows:DCP>
-    </ows:Operation>
     <ows:Operation name="DescribeRecord">
       <ows:DCP>
         <ows:HTTP>
@@ -76,14 +63,14 @@
           <ows:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/cite/default.cfg"/>
         </ows:HTTP>
       </ows:DCP>
-      <ows:Parameter name="schemaLanguage">
-        <ows:Value>http://www.w3.org/XML/Schema</ows:Value>
-        <ows:Value>http://www.w3.org/TR/xmlschema-1/</ows:Value>
-        <ows:Value>http://www.w3.org/2001/XMLSchema</ows:Value>
-      </ows:Parameter>
       <ows:Parameter name="outputFormat">
-        <ows:Value>application/xml</ows:Value>
         <ows:Value>application/json</ows:Value>
+        <ows:Value>application/xml</ows:Value>
+      </ows:Parameter>
+      <ows:Parameter name="schemaLanguage">
+        <ows:Value>http://www.w3.org/2001/XMLSchema</ows:Value>
+        <ows:Value>http://www.w3.org/TR/xmlschema-1/</ows:Value>
+        <ows:Value>http://www.w3.org/XML/Schema</ows:Value>
       </ows:Parameter>
       <ows:Parameter name="typeName">
         <ows:Value>csw:Record</ows:Value>
@@ -97,65 +84,49 @@
         </ows:HTTP>
       </ows:DCP>
       <ows:Parameter name="ParameterName">
-        <ows:Value>GetCapabilities.sections</ows:Value>
-        <ows:Value>DescribeRecord.schemaLanguage</ows:Value>
         <ows:Value>DescribeRecord.outputFormat</ows:Value>
+        <ows:Value>DescribeRecord.schemaLanguage</ows:Value>
         <ows:Value>DescribeRecord.typeName</ows:Value>
+        <ows:Value>GetCapabilities.sections</ows:Value>
+        <ows:Value>GetRecordById.ElementSetName</ows:Value>
         <ows:Value>GetRecordById.outputFormat</ows:Value>
         <ows:Value>GetRecordById.outputSchema</ows:Value>
-        <ows:Value>GetRecordById.ElementSetName</ows:Value>
+        <ows:Value>GetRecords.CONSTRAINTLANGUAGE</ows:Value>
+        <ows:Value>GetRecords.ElementSetName</ows:Value>
         <ows:Value>GetRecords.outputFormat</ows:Value>
         <ows:Value>GetRecords.outputSchema</ows:Value>
-        <ows:Value>GetRecords.CONSTRAINTLANGUAGE</ows:Value>
         <ows:Value>GetRecords.resultType</ows:Value>
         <ows:Value>GetRecords.typeNames</ows:Value>
-        <ows:Value>GetRecords.ElementSetName</ows:Value>
         <ows:Value>Harvest.ResourceType</ows:Value>
+        <ows:Value>Transaction.TransactionSchemas</ows:Value>
       </ows:Parameter>
     </ows:Operation>
-    <ows:Operation name="GetRecordById">
+    <ows:Operation name="GetRecords">
       <ows:DCP>
         <ows:HTTP>
           <ows:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/cite/default.cfg"/>
           <ows:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/cite/default.cfg"/>
         </ows:HTTP>
       </ows:DCP>
-      <ows:Parameter name="outputFormat">
-        <ows:Value>application/xml</ows:Value>
-        <ows:Value>application/json</ows:Value>
-      </ows:Parameter>
-      <ows:Parameter name="outputSchema">
-        <ows:Value>http://www.opengis.net/cat/csw/2.0.2</ows:Value>
-        <ows:Value>http://www.w3.org/2005/Atom</ows:Value>
-        <ows:Value>http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/</ows:Value>
-        <ows:Value>http://www.opengis.net/cat/csw/csdgm</ows:Value>
+      <ows:Parameter name="CONSTRAINTLANGUAGE">
+        <ows:Value>CQL_TEXT</ows:Value>
+        <ows:Value>FILTER</ows:Value>
       </ows:Parameter>
       <ows:Parameter name="ElementSetName">
         <ows:Value>brief</ows:Value>
-        <ows:Value>summary</ows:Value>
         <ows:Value>full</ows:Value>
+        <ows:Value>summary</ows:Value>
       </ows:Parameter>
-    </ows:Operation>
-    <ows:Operation name="GetRecords">
-      <ows:DCP>
-        <ows:HTTP>
-          <ows:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/cite/default.cfg"/>
-          <ows:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/cite/default.cfg"/>
-        </ows:HTTP>
-      </ows:DCP>
       <ows:Parameter name="outputFormat">
-        <ows:Value>application/xml</ows:Value>
         <ows:Value>application/json</ows:Value>
+        <ows:Value>application/xml</ows:Value>
       </ows:Parameter>
       <ows:Parameter name="outputSchema">
-        <ows:Value>http://www.opengis.net/cat/csw/2.0.2</ows:Value>
-        <ows:Value>http://www.w3.org/2005/Atom</ows:Value>
         <ows:Value>http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/</ows:Value>
+        <ows:Value>http://www.interlis.ch/INTERLIS2.3</ows:Value>
+        <ows:Value>http://www.opengis.net/cat/csw/2.0.2</ows:Value>
         <ows:Value>http://www.opengis.net/cat/csw/csdgm</ows:Value>
-      </ows:Parameter>
-      <ows:Parameter name="CONSTRAINTLANGUAGE">
-        <ows:Value>FILTER</ows:Value>
-        <ows:Value>CQL_TEXT</ows:Value>
+        <ows:Value>http://www.w3.org/2005/Atom</ows:Value>
       </ows:Parameter>
       <ows:Parameter name="resultType">
         <ows:Value>hits</ows:Value>
@@ -165,60 +136,110 @@
       <ows:Parameter name="typeNames">
         <ows:Value>csw:Record</ows:Value>
       </ows:Parameter>
-      <ows:Parameter name="ElementSetName">
-        <ows:Value>brief</ows:Value>
-        <ows:Value>summary</ows:Value>
-        <ows:Value>full</ows:Value>
-      </ows:Parameter>
       <ows:Constraint name="SupportedDublinCoreQueryables">
+        <ows:Value>csw:AnyText</ows:Value>
         <ows:Value>dc:contributor</ows:Value>
-        <ows:Value>dc:source</ows:Value>
-        <ows:Value>dc:language</ows:Value>
-        <ows:Value>dc:title</ows:Value>
-        <ows:Value>dc:subject</ows:Value>
         <ows:Value>dc:creator</ows:Value>
-        <ows:Value>dc:type</ows:Value>
-        <ows:Value>ows:BoundingBox</ows:Value>
-        <ows:Value>dct:modified</ows:Value>
-        <ows:Value>dct:abstract</ows:Value>
-        <ows:Value>dc:relation</ows:Value>
         <ows:Value>dc:date</ows:Value>
+        <ows:Value>dc:format</ows:Value>
         <ows:Value>dc:identifier</ows:Value>
+        <ows:Value>dc:language</ows:Value>
         <ows:Value>dc:publisher</ows:Value>
-        <ows:Value>dc:format</ows:Value>
-        <ows:Value>csw:AnyText</ows:Value>
+        <ows:Value>dc:relation</ows:Value>
         <ows:Value>dc:rights</ows:Value>
+        <ows:Value>dc:source</ows:Value>
+        <ows:Value>dc:subject</ows:Value>
+        <ows:Value>dc:title</ows:Value>
+        <ows:Value>dc:type</ows:Value>
+        <ows:Value>dct:abstract</ows:Value>
+        <ows:Value>dct:modified</ows:Value>
+        <ows:Value>ows:BoundingBox</ows:Value>
       </ows:Constraint>
     </ows:Operation>
-    <ows:Operation name="Harvest">
+    <ows:Operation name="GetRecordById">
       <ows:DCP>
         <ows:HTTP>
+          <ows:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/cite/default.cfg"/>
           <ows:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/cite/default.cfg"/>
         </ows:HTTP>
       </ows:DCP>
-      <ows:Parameter name="ResourceType">
+      <ows:Parameter name="ElementSetName">
+        <ows:Value>brief</ows:Value>
+        <ows:Value>full</ows:Value>
+        <ows:Value>summary</ows:Value>
+      </ows:Parameter>
+      <ows:Parameter name="outputFormat">
+        <ows:Value>application/json</ows:Value>
+        <ows:Value>application/xml</ows:Value>
+      </ows:Parameter>
+      <ows:Parameter name="outputSchema">
+        <ows:Value>http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/</ows:Value>
+        <ows:Value>http://www.interlis.ch/INTERLIS2.3</ows:Value>
         <ows:Value>http://www.opengis.net/cat/csw/2.0.2</ows:Value>
-        <ows:Value>http://www.opengis.net/wms</ows:Value>
-        <ows:Value>http://www.opengis.net/wfs</ows:Value>
-        <ows:Value>http://www.opengis.net/wcs</ows:Value>
-        <ows:Value>http://www.opengis.net/wps/1.0.0</ows:Value>
+        <ows:Value>http://www.opengis.net/cat/csw/csdgm</ows:Value>
+        <ows:Value>http://www.w3.org/2005/Atom</ows:Value>
+      </ows:Parameter>
+    </ows:Operation>
+    <ows:Operation name="GetRepositoryItem">
+      <ows:DCP>
+        <ows:HTTP>
+          <ows:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/cite/default.cfg"/>
+        </ows:HTTP>
+      </ows:DCP>
+    </ows:Operation>
+    <ows:Operation name="Transaction">
+      <ows:DCP>
+        <ows:HTTP>
+          <ows:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/cite/default.cfg"/>
+        </ows:HTTP>
+      </ows:DCP>
+      <ows:Parameter name="TransactionSchemas">
+        <ows:Value>http://www.isotc211.org/2005/gmi</ows:Value>
+        <ows:Value>http://www.opengis.net/cat/csw/2.0.2</ows:Value>
+        <ows:Value>http://www.opengis.net/cat/csw/3.0</ows:Value>
         <ows:Value>http://www.opengis.net/sos/1.0</ows:Value>
         <ows:Value>http://www.opengis.net/sos/2.0</ows:Value>
-        <ows:Value>http://www.isotc211.org/2005/gmi</ows:Value>
+        <ows:Value>http://www.opengis.net/wcs</ows:Value>
+        <ows:Value>http://www.opengis.net/wfs</ows:Value>
+        <ows:Value>http://www.opengis.net/wms</ows:Value>
+        <ows:Value>http://www.opengis.net/wmts/1.0</ows:Value>
+        <ows:Value>http://www.opengis.net/wps/1.0.0</ows:Value>
         <ows:Value>urn:geoss:waf</ows:Value>
-        <ows:Value>http://www.w3.org/2005/Atom</ows:Value>
+      </ows:Parameter>
+    </ows:Operation>
+    <ows:Operation name="Harvest">
+      <ows:DCP>
+        <ows:HTTP>
+          <ows:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/cite/default.cfg"/>
+        </ows:HTTP>
+      </ows:DCP>
+      <ows:Parameter name="ResourceType">
         <ows:Value>http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/</ows:Value>
+        <ows:Value>http://www.interlis.ch/INTERLIS2.3</ows:Value>
+        <ows:Value>http://www.isotc211.org/2005/gmi</ows:Value>
+        <ows:Value>http://www.opengis.net/cat/csw/2.0.2</ows:Value>
+        <ows:Value>http://www.opengis.net/cat/csw/3.0</ows:Value>
         <ows:Value>http://www.opengis.net/cat/csw/csdgm</ows:Value>
+        <ows:Value>http://www.opengis.net/sos/1.0</ows:Value>
+        <ows:Value>http://www.opengis.net/sos/2.0</ows:Value>
+        <ows:Value>http://www.opengis.net/wcs</ows:Value>
+        <ows:Value>http://www.opengis.net/wfs</ows:Value>
+        <ows:Value>http://www.opengis.net/wms</ows:Value>
+        <ows:Value>http://www.opengis.net/wmts/1.0</ows:Value>
+        <ows:Value>http://www.opengis.net/wps/1.0.0</ows:Value>
+        <ows:Value>http://www.w3.org/2005/Atom</ows:Value>
+        <ows:Value>urn:geoss:waf</ows:Value>
       </ows:Parameter>
     </ows:Operation>
-    <ows:Parameter name="version">
-      <ows:Value>2.0.2</ows:Value>
-    </ows:Parameter>
     <ows:Parameter name="service">
       <ows:Value>CSW</ows:Value>
     </ows:Parameter>
-    <ows:Constraint name="XPathQueryables">
-      <ows:Value>allowed</ows:Value>
+    <ows:Parameter name="version">
+      <ows:Value>2.0.2</ows:Value>
+      <ows:Value>3.0.0</ows:Value>
+    </ows:Parameter>
+    <ows:Constraint name="FederatedCatalogues">
+      <ows:Value>http://geo.data.gov/geoportal/csw/discovery</ows:Value>
     </ows:Constraint>
     <ows:Constraint name="MaxRecordDefault">
       <ows:Value>10</ows:Value>
@@ -227,8 +248,8 @@
       <ows:Value>XML</ows:Value>
       <ows:Value>SOAP</ows:Value>
     </ows:Constraint>
-    <ows:Constraint name="FederatedCatalogues">
-      <ows:Value>http://geo.data.gov/geoportal/csw/discovery</ows:Value>
+    <ows:Constraint name="XPathQueryables">
+      <ows:Value>allowed</ows:Value>
     </ows:Constraint>
   </ows:OperationsMetadata>
   <ogc:Filter_Capabilities>
@@ -258,11 +279,11 @@
       <ogc:ComparisonOperators>
         <ogc:ComparisonOperator>Between</ogc:ComparisonOperator>
         <ogc:ComparisonOperator>EqualTo</ogc:ComparisonOperator>
-        <ogc:ComparisonOperator>LessThanEqualTo</ogc:ComparisonOperator>
         <ogc:ComparisonOperator>GreaterThan</ogc:ComparisonOperator>
-        <ogc:ComparisonOperator>Like</ogc:ComparisonOperator>
-        <ogc:ComparisonOperator>LessThan</ogc:ComparisonOperator>
         <ogc:ComparisonOperator>GreaterThanEqualTo</ogc:ComparisonOperator>
+        <ogc:ComparisonOperator>LessThan</ogc:ComparisonOperator>
+        <ogc:ComparisonOperator>LessThanEqualTo</ogc:ComparisonOperator>
+        <ogc:ComparisonOperator>Like</ogc:ComparisonOperator>
         <ogc:ComparisonOperator>NotEqualTo</ogc:ComparisonOperator>
         <ogc:ComparisonOperator>NullCheck</ogc:ComparisonOperator>
       </ogc:ComparisonOperators>
diff --git a/tests/expected/suites_cite_get_37aa90e2-6ff0-420c-af15-8b9463099a73.xml b/tests/expected/suites_cite_get_37aa90e2-6ff0-420c-af15-8b9463099a73.xml
index 7af5f73..fb6934a 100644
--- a/tests/expected/suites_cite_get_37aa90e2-6ff0-420c-af15-8b9463099a73.xml
+++ b/tests/expected/suites_cite_get_37aa90e2-6ff0-420c-af15-8b9463099a73.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<csw:GetRecordByIdResponse xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ows="http://www.opengis.net/ows" xmlns:fgdc="http://www.opengis.net/cat/csw/c [...]
+<csw:GetRecordByIdResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/cat/csw/2.0.2 http://schemas.opengis.net/csw/2.0.2/CSW-discovery.xsd">
   <csw:SummaryRecord>
     <dc:identifier>urn:uuid:9a669547-b69b-469f-a11f-2d875366bbdc</dc:identifier>
     <dc:title>Ñunç elementum</dc:title>
diff --git a/tests/expected/suites_cite_get_3a8a3c47-455f-4f49-9078-03119f3e70b3.xml b/tests/expected/suites_cite_get_3a8a3c47-455f-4f49-9078-03119f3e70b3.xml
index 5c5c068..29f606b 100644
--- a/tests/expected/suites_cite_get_3a8a3c47-455f-4f49-9078-03119f3e70b3.xml
+++ b/tests/expected/suites_cite_get_3a8a3c47-455f-4f49-9078-03119f3e70b3.xml
@@ -1,287 +1,7 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<csw:Capabilities xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ows="http://www.opengis.net/ows" xmlns:fgdc="http://www.opengis.net/cat/csw/csdgm" xml [...]
-  <ows:ServiceIdentification>
-    <ows:Title>pycsw Geospatial Catalogue</ows:Title>
-    <ows:Abstract>pycsw is an OGC CSW server implementation written in Python</ows:Abstract>
-    <ows:Keywords>
-      <ows:Keyword>catalogue</ows:Keyword>
-      <ows:Keyword>discovery</ows:Keyword>
-      <ows:Type codeSpace="ISOTC211/19115">theme</ows:Type>
-    </ows:Keywords>
-    <ows:ServiceType codeSpace="OGC">CSW</ows:ServiceType>
-    <ows:ServiceTypeVersion>2.0.2</ows:ServiceTypeVersion>
-    <ows:Fees>None</ows:Fees>
-    <ows:AccessConstraints>None</ows:AccessConstraints>
-  </ows:ServiceIdentification>
-  <ows:ServiceProvider>
-    <ows:ProviderName>pycsw</ows:ProviderName>
-    <ows:ProviderSite xlink:type="simple" xlink:href="http://pycsw.org/"/>
-    <ows:ServiceContact>
-      <ows:IndividualName>Kralidis, Tom</ows:IndividualName>
-      <ows:PositionName>Senior Systems Scientist</ows:PositionName>
-      <ows:ContactInfo>
-        <ows:Phone>
-          <ows:Voice>+01-416-xxx-xxxx</ows:Voice>
-          <ows:Facsimile>+01-416-xxx-xxxx</ows:Facsimile>
-        </ows:Phone>
-        <ows:Address>
-          <ows:DeliveryPoint>TBA</ows:DeliveryPoint>
-          <ows:City>Toronto</ows:City>
-          <ows:AdministrativeArea>Ontario</ows:AdministrativeArea>
-          <ows:PostalCode>M9C 3Z9</ows:PostalCode>
-          <ows:Country>Canada</ows:Country>
-          <ows:ElectronicMailAddress>tomkralidis at gmail.com</ows:ElectronicMailAddress>
-        </ows:Address>
-        <ows:OnlineResource xlink:type="simple" xlink:href="http://kralidis.ca/"/>
-        <ows:HoursOfService>0800h - 1600h EST</ows:HoursOfService>
-        <ows:ContactInstructions>During hours of service.  Off on weekends.</ows:ContactInstructions>
-      </ows:ContactInfo>
-      <ows:Role codeSpace="ISOTC211/19115">pointOfContact</ows:Role>
-    </ows:ServiceContact>
-  </ows:ServiceProvider>
-  <ows:OperationsMetadata>
-    <ows:Operation name="GetCapabilities">
-      <ows:DCP>
-        <ows:HTTP>
-          <ows:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/cite/default.cfg"/>
-          <ows:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/cite/default.cfg"/>
-        </ows:HTTP>
-      </ows:DCP>
-      <ows:Parameter name="sections">
-        <ows:Value>ServiceIdentification</ows:Value>
-        <ows:Value>ServiceProvider</ows:Value>
-        <ows:Value>OperationsMetadata</ows:Value>
-        <ows:Value>Filter_Capabilities</ows:Value>
-      </ows:Parameter>
-    </ows:Operation>
-    <ows:Operation name="Transaction">
-      <ows:DCP>
-        <ows:HTTP>
-          <ows:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/cite/default.cfg"/>
-        </ows:HTTP>
-      </ows:DCP>
-    </ows:Operation>
-    <ows:Operation name="GetRepositoryItem">
-      <ows:DCP>
-        <ows:HTTP>
-          <ows:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/cite/default.cfg"/>
-        </ows:HTTP>
-      </ows:DCP>
-    </ows:Operation>
-    <ows:Operation name="DescribeRecord">
-      <ows:DCP>
-        <ows:HTTP>
-          <ows:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/cite/default.cfg"/>
-          <ows:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/cite/default.cfg"/>
-        </ows:HTTP>
-      </ows:DCP>
-      <ows:Parameter name="schemaLanguage">
-        <ows:Value>http://www.w3.org/XML/Schema</ows:Value>
-        <ows:Value>http://www.w3.org/TR/xmlschema-1/</ows:Value>
-        <ows:Value>http://www.w3.org/2001/XMLSchema</ows:Value>
-      </ows:Parameter>
-      <ows:Parameter name="outputFormat">
-        <ows:Value>application/xml</ows:Value>
-        <ows:Value>application/json</ows:Value>
-      </ows:Parameter>
-      <ows:Parameter name="typeName">
-        <ows:Value>csw:Record</ows:Value>
-      </ows:Parameter>
-    </ows:Operation>
-    <ows:Operation name="GetDomain">
-      <ows:DCP>
-        <ows:HTTP>
-          <ows:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/cite/default.cfg"/>
-          <ows:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/cite/default.cfg"/>
-        </ows:HTTP>
-      </ows:DCP>
-      <ows:Parameter name="ParameterName">
-        <ows:Value>GetCapabilities.sections</ows:Value>
-        <ows:Value>DescribeRecord.schemaLanguage</ows:Value>
-        <ows:Value>DescribeRecord.outputFormat</ows:Value>
-        <ows:Value>DescribeRecord.typeName</ows:Value>
-        <ows:Value>GetRecordById.outputFormat</ows:Value>
-        <ows:Value>GetRecordById.outputSchema</ows:Value>
-        <ows:Value>GetRecordById.ElementSetName</ows:Value>
-        <ows:Value>GetRecords.outputFormat</ows:Value>
-        <ows:Value>GetRecords.outputSchema</ows:Value>
-        <ows:Value>GetRecords.CONSTRAINTLANGUAGE</ows:Value>
-        <ows:Value>GetRecords.resultType</ows:Value>
-        <ows:Value>GetRecords.typeNames</ows:Value>
-        <ows:Value>GetRecords.ElementSetName</ows:Value>
-        <ows:Value>Harvest.ResourceType</ows:Value>
-      </ows:Parameter>
-    </ows:Operation>
-    <ows:Operation name="GetRecordById">
-      <ows:DCP>
-        <ows:HTTP>
-          <ows:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/cite/default.cfg"/>
-          <ows:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/cite/default.cfg"/>
-        </ows:HTTP>
-      </ows:DCP>
-      <ows:Parameter name="outputFormat">
-        <ows:Value>application/xml</ows:Value>
-        <ows:Value>application/json</ows:Value>
-      </ows:Parameter>
-      <ows:Parameter name="outputSchema">
-        <ows:Value>http://www.opengis.net/cat/csw/2.0.2</ows:Value>
-        <ows:Value>http://www.w3.org/2005/Atom</ows:Value>
-        <ows:Value>http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/</ows:Value>
-        <ows:Value>http://www.opengis.net/cat/csw/csdgm</ows:Value>
-      </ows:Parameter>
-      <ows:Parameter name="ElementSetName">
-        <ows:Value>brief</ows:Value>
-        <ows:Value>summary</ows:Value>
-        <ows:Value>full</ows:Value>
-      </ows:Parameter>
-    </ows:Operation>
-    <ows:Operation name="GetRecords">
-      <ows:DCP>
-        <ows:HTTP>
-          <ows:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/cite/default.cfg"/>
-          <ows:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/cite/default.cfg"/>
-        </ows:HTTP>
-      </ows:DCP>
-      <ows:Parameter name="outputFormat">
-        <ows:Value>application/xml</ows:Value>
-        <ows:Value>application/json</ows:Value>
-      </ows:Parameter>
-      <ows:Parameter name="outputSchema">
-        <ows:Value>http://www.opengis.net/cat/csw/2.0.2</ows:Value>
-        <ows:Value>http://www.w3.org/2005/Atom</ows:Value>
-        <ows:Value>http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/</ows:Value>
-        <ows:Value>http://www.opengis.net/cat/csw/csdgm</ows:Value>
-      </ows:Parameter>
-      <ows:Parameter name="CONSTRAINTLANGUAGE">
-        <ows:Value>FILTER</ows:Value>
-        <ows:Value>CQL_TEXT</ows:Value>
-      </ows:Parameter>
-      <ows:Parameter name="resultType">
-        <ows:Value>hits</ows:Value>
-        <ows:Value>results</ows:Value>
-        <ows:Value>validate</ows:Value>
-      </ows:Parameter>
-      <ows:Parameter name="typeNames">
-        <ows:Value>csw:Record</ows:Value>
-      </ows:Parameter>
-      <ows:Parameter name="ElementSetName">
-        <ows:Value>brief</ows:Value>
-        <ows:Value>summary</ows:Value>
-        <ows:Value>full</ows:Value>
-      </ows:Parameter>
-      <ows:Constraint name="SupportedDublinCoreQueryables">
-        <ows:Value>dc:contributor</ows:Value>
-        <ows:Value>dc:source</ows:Value>
-        <ows:Value>dc:language</ows:Value>
-        <ows:Value>dc:title</ows:Value>
-        <ows:Value>dc:subject</ows:Value>
-        <ows:Value>dc:creator</ows:Value>
-        <ows:Value>dc:type</ows:Value>
-        <ows:Value>ows:BoundingBox</ows:Value>
-        <ows:Value>dct:modified</ows:Value>
-        <ows:Value>dct:abstract</ows:Value>
-        <ows:Value>dc:relation</ows:Value>
-        <ows:Value>dc:date</ows:Value>
-        <ows:Value>dc:identifier</ows:Value>
-        <ows:Value>dc:publisher</ows:Value>
-        <ows:Value>dc:format</ows:Value>
-        <ows:Value>csw:AnyText</ows:Value>
-        <ows:Value>dc:rights</ows:Value>
-      </ows:Constraint>
-    </ows:Operation>
-    <ows:Operation name="Harvest">
-      <ows:DCP>
-        <ows:HTTP>
-          <ows:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/cite/default.cfg"/>
-        </ows:HTTP>
-      </ows:DCP>
-      <ows:Parameter name="ResourceType">
-        <ows:Value>http://www.opengis.net/cat/csw/2.0.2</ows:Value>
-        <ows:Value>http://www.opengis.net/wms</ows:Value>
-        <ows:Value>http://www.opengis.net/wfs</ows:Value>
-        <ows:Value>http://www.opengis.net/wcs</ows:Value>
-        <ows:Value>http://www.opengis.net/wps/1.0.0</ows:Value>
-        <ows:Value>http://www.opengis.net/sos/1.0</ows:Value>
-        <ows:Value>http://www.opengis.net/sos/2.0</ows:Value>
-        <ows:Value>http://www.isotc211.org/2005/gmi</ows:Value>
-        <ows:Value>urn:geoss:waf</ows:Value>
-        <ows:Value>http://www.w3.org/2005/Atom</ows:Value>
-        <ows:Value>http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/</ows:Value>
-        <ows:Value>http://www.opengis.net/cat/csw/csdgm</ows:Value>
-      </ows:Parameter>
-    </ows:Operation>
-    <ows:Parameter name="version">
-      <ows:Value>2.0.2</ows:Value>
-    </ows:Parameter>
-    <ows:Parameter name="service">
-      <ows:Value>CSW</ows:Value>
-    </ows:Parameter>
-    <ows:Constraint name="XPathQueryables">
-      <ows:Value>allowed</ows:Value>
-    </ows:Constraint>
-    <ows:Constraint name="MaxRecordDefault">
-      <ows:Value>10</ows:Value>
-    </ows:Constraint>
-    <ows:Constraint name="PostEncoding">
-      <ows:Value>XML</ows:Value>
-      <ows:Value>SOAP</ows:Value>
-    </ows:Constraint>
-    <ows:Constraint name="FederatedCatalogues">
-      <ows:Value>http://geo.data.gov/geoportal/csw/discovery</ows:Value>
-    </ows:Constraint>
-  </ows:OperationsMetadata>
-  <ogc:Filter_Capabilities>
-    <ogc:Spatial_Capabilities>
-      <ogc:GeometryOperands>
-        <ogc:GeometryOperand>gml:Point</ogc:GeometryOperand>
-        <ogc:GeometryOperand>gml:LineString</ogc:GeometryOperand>
-        <ogc:GeometryOperand>gml:Polygon</ogc:GeometryOperand>
-        <ogc:GeometryOperand>gml:Envelope</ogc:GeometryOperand>
-      </ogc:GeometryOperands>
-      <ogc:SpatialOperators>
-        <ogc:SpatialOperator name="BBOX"/>
-        <ogc:SpatialOperator name="Beyond"/>
-        <ogc:SpatialOperator name="Contains"/>
-        <ogc:SpatialOperator name="Crosses"/>
-        <ogc:SpatialOperator name="Disjoint"/>
-        <ogc:SpatialOperator name="DWithin"/>
-        <ogc:SpatialOperator name="Equals"/>
-        <ogc:SpatialOperator name="Intersects"/>
-        <ogc:SpatialOperator name="Overlaps"/>
-        <ogc:SpatialOperator name="Touches"/>
-        <ogc:SpatialOperator name="Within"/>
-      </ogc:SpatialOperators>
-    </ogc:Spatial_Capabilities>
-    <ogc:Scalar_Capabilities>
-      <ogc:LogicalOperators/>
-      <ogc:ComparisonOperators>
-        <ogc:ComparisonOperator>Between</ogc:ComparisonOperator>
-        <ogc:ComparisonOperator>EqualTo</ogc:ComparisonOperator>
-        <ogc:ComparisonOperator>LessThanEqualTo</ogc:ComparisonOperator>
-        <ogc:ComparisonOperator>GreaterThan</ogc:ComparisonOperator>
-        <ogc:ComparisonOperator>Like</ogc:ComparisonOperator>
-        <ogc:ComparisonOperator>LessThan</ogc:ComparisonOperator>
-        <ogc:ComparisonOperator>GreaterThanEqualTo</ogc:ComparisonOperator>
-        <ogc:ComparisonOperator>NotEqualTo</ogc:ComparisonOperator>
-        <ogc:ComparisonOperator>NullCheck</ogc:ComparisonOperator>
-      </ogc:ComparisonOperators>
-      <ogc:ArithmeticOperators>
-        <ogc:Functions>
-          <ogc:FunctionNames>
-            <ogc:FunctionName nArgs="1">length</ogc:FunctionName>
-            <ogc:FunctionName nArgs="1">lower</ogc:FunctionName>
-            <ogc:FunctionName nArgs="1">ltrim</ogc:FunctionName>
-            <ogc:FunctionName nArgs="1">rtrim</ogc:FunctionName>
-            <ogc:FunctionName nArgs="1">trim</ogc:FunctionName>
-            <ogc:FunctionName nArgs="1">upper</ogc:FunctionName>
-          </ogc:FunctionNames>
-        </ogc:Functions>
-      </ogc:ArithmeticOperators>
-    </ogc:Scalar_Capabilities>
-    <ogc:Id_Capabilities>
-      <ogc:EID/>
-      <ogc:FID/>
-    </ogc:Id_Capabilities>
-  </ogc:Filter_Capabilities>
-</csw:Capabilities>
+<ows20:ExceptionReport xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:ows20="http://www.opengis.net/ows/2.0" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="3.0.0" xml:lang="en-US" xsi:schemaLocation="http://www.opengis. [...]
+  <ows20:Exception exceptionCode="InvalidParameterValue" locator="acceptformats">
+    <ows20:ExceptionText>Invalid acceptFormats parameter value: message/example</ows20:ExceptionText>
+  </ows20:Exception>
+</ows20:ExceptionReport>
diff --git a/tests/expected/suites_cite_get_4515831f-834a-4699-95f6-ab0c2cbfcfd0.xml b/tests/expected/suites_cite_get_4515831f-834a-4699-95f6-ab0c2cbfcfd0.xml
index 76a5a54..95a2f28 100644
--- a/tests/expected/suites_cite_get_4515831f-834a-4699-95f6-ab0c2cbfcfd0.xml
+++ b/tests/expected/suites_cite_get_4515831f-834a-4699-95f6-ab0c2cbfcfd0.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<ows:ExceptionReport xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ows="http://www.opengis.net/ows" xmlns:fgdc="http://www.opengis.net/cat/csw/csdgm"  [...]
+<ows:ExceptionReport xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" language="en-US" version="1.2.0" xsi:schemaLocation="http://www.opengis.net/ows http://schemas.opengis.net/ows/1.0.0/ow [...]
   <ows:Exception exceptionCode="MissingParameterValue" locator="id">
     <ows:ExceptionText>Missing id parameter</ows:ExceptionText>
   </ows:Exception>
diff --git a/tests/expected/suites_cite_get_477b23a3-baa9-47c8-9541-5fe27735ed49.xml b/tests/expected/suites_cite_get_477b23a3-baa9-47c8-9541-5fe27735ed49.xml
index 15b88f1..d127684 100644
--- a/tests/expected/suites_cite_get_477b23a3-baa9-47c8-9541-5fe27735ed49.xml
+++ b/tests/expected/suites_cite_get_477b23a3-baa9-47c8-9541-5fe27735ed49.xml
@@ -1,57 +1,541 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<csw:Capabilities xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ows="http://www.opengis.net/ows" xmlns:fgdc="http://www.opengis.net/cat/csw/csdgm" xml [...]
-  <ogc:Filter_Capabilities>
-    <ogc:Spatial_Capabilities>
-      <ogc:GeometryOperands>
-        <ogc:GeometryOperand>gml:Point</ogc:GeometryOperand>
-        <ogc:GeometryOperand>gml:LineString</ogc:GeometryOperand>
-        <ogc:GeometryOperand>gml:Polygon</ogc:GeometryOperand>
-        <ogc:GeometryOperand>gml:Envelope</ogc:GeometryOperand>
-      </ogc:GeometryOperands>
-      <ogc:SpatialOperators>
-        <ogc:SpatialOperator name="BBOX"/>
-        <ogc:SpatialOperator name="Beyond"/>
-        <ogc:SpatialOperator name="Contains"/>
-        <ogc:SpatialOperator name="Crosses"/>
-        <ogc:SpatialOperator name="Disjoint"/>
-        <ogc:SpatialOperator name="DWithin"/>
-        <ogc:SpatialOperator name="Equals"/>
-        <ogc:SpatialOperator name="Intersects"/>
-        <ogc:SpatialOperator name="Overlaps"/>
-        <ogc:SpatialOperator name="Touches"/>
-        <ogc:SpatialOperator name="Within"/>
-      </ogc:SpatialOperators>
-    </ogc:Spatial_Capabilities>
-    <ogc:Scalar_Capabilities>
-      <ogc:LogicalOperators/>
-      <ogc:ComparisonOperators>
-        <ogc:ComparisonOperator>Between</ogc:ComparisonOperator>
-        <ogc:ComparisonOperator>EqualTo</ogc:ComparisonOperator>
-        <ogc:ComparisonOperator>LessThanEqualTo</ogc:ComparisonOperator>
-        <ogc:ComparisonOperator>GreaterThan</ogc:ComparisonOperator>
-        <ogc:ComparisonOperator>Like</ogc:ComparisonOperator>
-        <ogc:ComparisonOperator>LessThan</ogc:ComparisonOperator>
-        <ogc:ComparisonOperator>GreaterThanEqualTo</ogc:ComparisonOperator>
-        <ogc:ComparisonOperator>NotEqualTo</ogc:ComparisonOperator>
-        <ogc:ComparisonOperator>NullCheck</ogc:ComparisonOperator>
-      </ogc:ComparisonOperators>
-      <ogc:ArithmeticOperators>
-        <ogc:Functions>
-          <ogc:FunctionNames>
-            <ogc:FunctionName nArgs="1">length</ogc:FunctionName>
-            <ogc:FunctionName nArgs="1">lower</ogc:FunctionName>
-            <ogc:FunctionName nArgs="1">ltrim</ogc:FunctionName>
-            <ogc:FunctionName nArgs="1">rtrim</ogc:FunctionName>
-            <ogc:FunctionName nArgs="1">trim</ogc:FunctionName>
-            <ogc:FunctionName nArgs="1">upper</ogc:FunctionName>
-          </ogc:FunctionNames>
-        </ogc:Functions>
-      </ogc:ArithmeticOperators>
-    </ogc:Scalar_Capabilities>
-    <ogc:Id_Capabilities>
-      <ogc:EID/>
-      <ogc:FID/>
-    </ogc:Id_Capabilities>
-  </ogc:Filter_Capabilities>
-</csw:Capabilities>
+<csw30:Capabilities xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:csw30="http://www.opengis.net/cat/csw/3.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:fes20="http://www.opengis.net/fes/2.0" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:ows11="http://www.opengis.net/ows/1.1" xmlns:ows20="http://www.opengis.net/ows/2.0" xmlns:xlink="http://www.w3.org/199 [...]
+  <ows20:ServiceIdentification>
+    <ows20:Title>pycsw Geospatial Catalogue</ows20:Title>
+    <ows20:Abstract>pycsw is an OGC CSW server implementation written in Python</ows20:Abstract>
+    <ows20:Keywords>
+      <ows20:Keyword>catalogue</ows20:Keyword>
+      <ows20:Keyword>discovery</ows20:Keyword>
+      <ows20:Type codeSpace="ISOTC211/19115">theme</ows20:Type>
+    </ows20:Keywords>
+    <ows20:ServiceType codeSpace="OGC">CSW</ows20:ServiceType>
+    <ows20:ServiceTypeVersion>2.0.2</ows20:ServiceTypeVersion>
+    <ows20:ServiceTypeVersion>3.0.0</ows20:ServiceTypeVersion>
+    <ows20:Fees>None</ows20:Fees>
+    <ows20:AccessConstraints>None</ows20:AccessConstraints>
+  </ows20:ServiceIdentification>
+  <ows20:ServiceProvider>
+    <ows20:ProviderName>pycsw</ows20:ProviderName>
+    <ows20:ProviderSite xlink:type="simple" xlink:href="http://pycsw.org/"/>
+    <ows20:ServiceContact>
+      <ows20:IndividualName>Kralidis, Tom</ows20:IndividualName>
+      <ows20:PositionName>Senior Systems Scientist</ows20:PositionName>
+      <ows20:ContactInfo>
+        <ows20:Phone>
+          <ows20:Voice>+01-416-xxx-xxxx</ows20:Voice>
+          <ows20:Facsimile>+01-416-xxx-xxxx</ows20:Facsimile>
+        </ows20:Phone>
+        <ows20:Address>
+          <ows20:DeliveryPoint>TBA</ows20:DeliveryPoint>
+          <ows20:City>Toronto</ows20:City>
+          <ows20:AdministrativeArea>Ontario</ows20:AdministrativeArea>
+          <ows20:PostalCode>M9C 3Z9</ows20:PostalCode>
+          <ows20:Country>Canada</ows20:Country>
+          <ows20:ElectronicMailAddress>tomkralidis at gmail.com</ows20:ElectronicMailAddress>
+        </ows20:Address>
+        <ows20:OnlineResource xlink:type="simple" xlink:href="http://kralidis.ca/"/>
+        <ows20:HoursOfService>0800h - 1600h EST</ows20:HoursOfService>
+        <ows20:ContactInstructions>During hours of service.  Off on weekends.</ows20:ContactInstructions>
+      </ows20:ContactInfo>
+      <ows20:Role codeSpace="ISOTC211/19115">pointOfContact</ows20:Role>
+    </ows20:ServiceContact>
+  </ows20:ServiceProvider>
+  <ows20:OperationsMetadata>
+    <ows20:Operation name="GetCapabilities">
+      <ows20:DCP>
+        <ows20:HTTP>
+          <ows20:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/cite/default.cfg"/>
+          <ows20:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/cite/default.cfg"/>
+        </ows20:HTTP>
+      </ows20:DCP>
+      <ows20:Parameter name="acceptFormats">
+        <ows20:AllowedValues>
+          <ows20:Value>application/xml</ows20:Value>
+          <ows20:Value>text/xml</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Parameter name="acceptVersions">
+        <ows20:AllowedValues>
+          <ows20:Value>2.0.2</ows20:Value>
+          <ows20:Value>3.0.0</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Parameter name="sections">
+        <ows20:AllowedValues>
+          <ows20:Value>All</ows20:Value>
+          <ows20:Value>Filter_Capabilities</ows20:Value>
+          <ows20:Value>OperationsMetadata</ows20:Value>
+          <ows20:Value>ServiceIdentification</ows20:Value>
+          <ows20:Value>ServiceProvider</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+    </ows20:Operation>
+    <ows20:Operation name="GetDomain">
+      <ows20:DCP>
+        <ows20:HTTP>
+          <ows20:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/cite/default.cfg"/>
+          <ows20:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/cite/default.cfg"/>
+        </ows20:HTTP>
+      </ows20:DCP>
+      <ows20:Parameter name="ParameterName">
+        <ows20:AllowedValues>
+          <ows20:Value>GetCapabilities.acceptFormats</ows20:Value>
+          <ows20:Value>GetCapabilities.acceptVersions</ows20:Value>
+          <ows20:Value>GetCapabilities.sections</ows20:Value>
+          <ows20:Value>GetRecordById.ElementSetName</ows20:Value>
+          <ows20:Value>GetRecordById.outputFormat</ows20:Value>
+          <ows20:Value>GetRecordById.outputSchema</ows20:Value>
+          <ows20:Value>GetRecords.CONSTRAINTLANGUAGE</ows20:Value>
+          <ows20:Value>GetRecords.ElementSetName</ows20:Value>
+          <ows20:Value>GetRecords.outputFormat</ows20:Value>
+          <ows20:Value>GetRecords.outputSchema</ows20:Value>
+          <ows20:Value>GetRecords.typeNames</ows20:Value>
+          <ows20:Value>Harvest.ResourceType</ows20:Value>
+          <ows20:Value>Transaction.TransactionSchemas</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+    </ows20:Operation>
+    <ows20:Operation name="GetRecords">
+      <ows20:DCP>
+        <ows20:HTTP>
+          <ows20:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/cite/default.cfg"/>
+          <ows20:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/cite/default.cfg"/>
+        </ows20:HTTP>
+      </ows20:DCP>
+      <ows20:Parameter name="CONSTRAINTLANGUAGE">
+        <ows20:AllowedValues>
+          <ows20:Value>CQL_TEXT</ows20:Value>
+          <ows20:Value>FILTER</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Parameter name="ElementSetName">
+        <ows20:AllowedValues>
+          <ows20:Value>brief</ows20:Value>
+          <ows20:Value>full</ows20:Value>
+          <ows20:Value>summary</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Parameter name="outputFormat">
+        <ows20:AllowedValues>
+          <ows20:Value>application/atom+xml</ows20:Value>
+          <ows20:Value>application/json</ows20:Value>
+          <ows20:Value>application/xml</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Parameter name="outputSchema">
+        <ows20:AllowedValues>
+          <ows20:Value>http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/</ows20:Value>
+          <ows20:Value>http://www.interlis.ch/INTERLIS2.3</ows20:Value>
+          <ows20:Value>http://www.opengis.net/cat/csw/3.0</ows20:Value>
+          <ows20:Value>http://www.opengis.net/cat/csw/csdgm</ows20:Value>
+          <ows20:Value>http://www.w3.org/2005/Atom</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Parameter name="typeNames">
+        <ows20:AllowedValues>
+          <ows20:Value>csw:Record</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Constraint name="MaxRecordDefault">
+        <ows20:AllowedValues>
+          <ows20:Value>10</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Constraint>
+      <ows20:Constraint name="OpenSearchDescriptionDocument">
+        <ows20:AllowedValues>
+          <ows20:Value>http://localhost/pycsw/csw.py?config=tests/suites/cite/default.cfg?mode=opensearch&service=CSW&version=3.0.0&request=GetCapabilities</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Constraint>
+      <ows20:Constraint name="FederatedCatalogues">
+        <ows20:AllowedValues>
+          <ows20:Value>http://geo.data.gov/geoportal/csw/discovery</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Constraint>
+    </ows20:Operation>
+    <ows20:Operation name="GetRecordById">
+      <ows20:DCP>
+        <ows20:HTTP>
+          <ows20:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/cite/default.cfg"/>
+          <ows20:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/cite/default.cfg"/>
+        </ows20:HTTP>
+      </ows20:DCP>
+      <ows20:Parameter name="ElementSetName">
+        <ows20:AllowedValues>
+          <ows20:Value>brief</ows20:Value>
+          <ows20:Value>full</ows20:Value>
+          <ows20:Value>summary</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Parameter name="outputFormat">
+        <ows20:AllowedValues>
+          <ows20:Value>application/atom+xml</ows20:Value>
+          <ows20:Value>application/json</ows20:Value>
+          <ows20:Value>application/xml</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Parameter name="outputSchema">
+        <ows20:AllowedValues>
+          <ows20:Value>http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/</ows20:Value>
+          <ows20:Value>http://www.interlis.ch/INTERLIS2.3</ows20:Value>
+          <ows20:Value>http://www.opengis.net/cat/csw/3.0</ows20:Value>
+          <ows20:Value>http://www.opengis.net/cat/csw/csdgm</ows20:Value>
+          <ows20:Value>http://www.w3.org/2005/Atom</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+    </ows20:Operation>
+    <ows20:Operation name="GetRepositoryItem">
+      <ows20:DCP>
+        <ows20:HTTP>
+          <ows20:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/cite/default.cfg"/>
+        </ows20:HTTP>
+      </ows20:DCP>
+    </ows20:Operation>
+    <ows20:Operation name="Transaction">
+      <ows20:DCP>
+        <ows20:HTTP>
+          <ows20:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/cite/default.cfg"/>
+        </ows20:HTTP>
+      </ows20:DCP>
+      <ows20:Parameter name="TransactionSchemas">
+        <ows20:AllowedValues>
+          <ows20:Value>http://www.isotc211.org/2005/gmi</ows20:Value>
+          <ows20:Value>http://www.opengis.net/cat/csw/2.0.2</ows20:Value>
+          <ows20:Value>http://www.opengis.net/cat/csw/3.0</ows20:Value>
+          <ows20:Value>http://www.opengis.net/sos/1.0</ows20:Value>
+          <ows20:Value>http://www.opengis.net/sos/2.0</ows20:Value>
+          <ows20:Value>http://www.opengis.net/wcs</ows20:Value>
+          <ows20:Value>http://www.opengis.net/wfs</ows20:Value>
+          <ows20:Value>http://www.opengis.net/wms</ows20:Value>
+          <ows20:Value>http://www.opengis.net/wmts/1.0</ows20:Value>
+          <ows20:Value>http://www.opengis.net/wps/1.0.0</ows20:Value>
+          <ows20:Value>urn:geoss:waf</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+    </ows20:Operation>
+    <ows20:Operation name="Harvest">
+      <ows20:DCP>
+        <ows20:HTTP>
+          <ows20:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/cite/default.cfg"/>
+        </ows20:HTTP>
+      </ows20:DCP>
+      <ows20:Parameter name="ResourceType">
+        <ows20:AllowedValues>
+          <ows20:Value>http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/</ows20:Value>
+          <ows20:Value>http://www.interlis.ch/INTERLIS2.3</ows20:Value>
+          <ows20:Value>http://www.isotc211.org/2005/gmi</ows20:Value>
+          <ows20:Value>http://www.opengis.net/cat/csw/2.0.2</ows20:Value>
+          <ows20:Value>http://www.opengis.net/cat/csw/3.0</ows20:Value>
+          <ows20:Value>http://www.opengis.net/cat/csw/csdgm</ows20:Value>
+          <ows20:Value>http://www.opengis.net/sos/1.0</ows20:Value>
+          <ows20:Value>http://www.opengis.net/sos/2.0</ows20:Value>
+          <ows20:Value>http://www.opengis.net/wcs</ows20:Value>
+          <ows20:Value>http://www.opengis.net/wfs</ows20:Value>
+          <ows20:Value>http://www.opengis.net/wms</ows20:Value>
+          <ows20:Value>http://www.opengis.net/wmts/1.0</ows20:Value>
+          <ows20:Value>http://www.opengis.net/wps/1.0.0</ows20:Value>
+          <ows20:Value>http://www.w3.org/2005/Atom</ows20:Value>
+          <ows20:Value>urn:geoss:waf</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+    </ows20:Operation>
+    <ows20:Parameter name="service">
+      <ows20:AllowedValues>
+        <ows20:Value>CSW</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Parameter>
+    <ows20:Parameter name="version">
+      <ows20:AllowedValues>
+        <ows20:Value>2.0.2</ows20:Value>
+        <ows20:Value>3.0.0</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Parameter>
+    <ows20:Constraint name="CoreQueryables">
+      <ows20:AllowedValues>
+        <ows20:Value>csw:AnyText</ows20:Value>
+        <ows20:Value>dc:contributor</ows20:Value>
+        <ows20:Value>dc:creator</ows20:Value>
+        <ows20:Value>dc:date</ows20:Value>
+        <ows20:Value>dc:format</ows20:Value>
+        <ows20:Value>dc:identifier</ows20:Value>
+        <ows20:Value>dc:language</ows20:Value>
+        <ows20:Value>dc:publisher</ows20:Value>
+        <ows20:Value>dc:relation</ows20:Value>
+        <ows20:Value>dc:rights</ows20:Value>
+        <ows20:Value>dc:source</ows20:Value>
+        <ows20:Value>dc:subject</ows20:Value>
+        <ows20:Value>dc:title</ows20:Value>
+        <ows20:Value>dc:type</ows20:Value>
+        <ows20:Value>dct:abstract</ows20:Value>
+        <ows20:Value>dct:modified</ows20:Value>
+        <ows20:Value>ows:BoundingBox</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="FederatedCatalogues">
+      <ows20:AllowedValues>
+        <ows20:Value>http://geo.data.gov/geoportal/csw/discovery</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="MaxRecordDefault">
+      <ows20:AllowedValues>
+        <ows20:Value>10</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="PostEncoding">
+      <ows20:AllowedValues>
+        <ows20:Value>SOAP</ows20:Value>
+        <ows20:Value>XML</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="XPathQueryables">
+      <ows20:AllowedValues>
+        <ows20:Value>allowed</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/CoreQueryables">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/CoreSortables">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/DefaultSortingAlgorithm">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Filter-CQL">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Filter-FES-KVP-Advanced">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Filter-FES-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetCapabilities-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetDomain-KVP">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetDomain-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetRecordById-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetRecords-Async-KVP">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetRecords-Async-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetRecords-Basic-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetRecords-Distributed-KVP">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetRecords-Distributed-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Harvest-Async-KVP">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Harvest-Async-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Harvest-Basic-KVP">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Harvest-Basic-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Harvest-Periodic-KVP">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Harvest-Periodic-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/OpenSearch">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/SupportedGMLVersions">
+      <ows20:AllowedValues>
+        <ows20:Value>http://www.opengis.net/gml</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Transaction">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+  </ows20:OperationsMetadata>
+  <ows20:Languages>
+    <ows20:Language>en</ows20:Language>
+  </ows20:Languages>
+  <fes20:Filter_Capabilities>
+    <fes20:Conformance>
+      <fes20:Constraint name="ImplementsQuery">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsAdHocQuery">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsFunctions">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsResourceld">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsMinStandardFilter">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsStandardFilter">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsMinSpatialFilter">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsSpatialFilter">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsMinTemporalFilter">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsTemporalFilter">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsVersionNav">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsSorting">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsExtendedOperators">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsMinimumXPath">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsSchemaElementFunc">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+    </fes20:Conformance>
+    <fes20:Id_Capabilities>
+      <fes20:ResourceIdentifier name="csw30:id"/>
+    </fes20:Id_Capabilities>
+    <fes20:Scalar_Capabilities>
+      <fes20:LogicalOperators/>
+      <fes20:ComparisonOperators>
+        <fes20:ComparisonOperator name="PropertyIsBetween"/>
+        <fes20:ComparisonOperator name="PropertyIsEqualTo"/>
+        <fes20:ComparisonOperator name="PropertyIsGreaterThan"/>
+        <fes20:ComparisonOperator name="PropertyIsGreaterThanOrEqualTo"/>
+        <fes20:ComparisonOperator name="PropertyIsLessThan"/>
+        <fes20:ComparisonOperator name="PropertyIsLessThanOrEqualTo"/>
+        <fes20:ComparisonOperator name="PropertyIsLike"/>
+        <fes20:ComparisonOperator name="PropertyIsNotEqualTo"/>
+        <fes20:ComparisonOperator name="PropertyIsNull"/>
+      </fes20:ComparisonOperators>
+    </fes20:Scalar_Capabilities>
+    <fes20:Spatial_Capabilities>
+      <fes20:GeometryOperands>
+        <fes20:GeometryOperand name="gml:Point"/>
+        <fes20:GeometryOperand name="gml:LineString"/>
+        <fes20:GeometryOperand name="gml:Polygon"/>
+        <fes20:GeometryOperand name="gml:Envelope"/>
+      </fes20:GeometryOperands>
+      <fes20:SpatialOperators>
+        <fes20:SpatialOperator name="BBOX"/>
+        <fes20:SpatialOperator name="Beyond"/>
+        <fes20:SpatialOperator name="Contains"/>
+        <fes20:SpatialOperator name="Crosses"/>
+        <fes20:SpatialOperator name="Disjoint"/>
+        <fes20:SpatialOperator name="DWithin"/>
+        <fes20:SpatialOperator name="Equals"/>
+        <fes20:SpatialOperator name="Intersects"/>
+        <fes20:SpatialOperator name="Overlaps"/>
+        <fes20:SpatialOperator name="Touches"/>
+        <fes20:SpatialOperator name="Within"/>
+      </fes20:SpatialOperators>
+    </fes20:Spatial_Capabilities>
+    <fes20:Functions>
+      <fes20:Function name="length">
+        <fes20:Returns>xs:string</fes20:Returns>
+      </fes20:Function>
+      <fes20:Function name="lower">
+        <fes20:Returns>xs:string</fes20:Returns>
+      </fes20:Function>
+      <fes20:Function name="ltrim">
+        <fes20:Returns>xs:string</fes20:Returns>
+      </fes20:Function>
+      <fes20:Function name="rtrim">
+        <fes20:Returns>xs:string</fes20:Returns>
+      </fes20:Function>
+      <fes20:Function name="trim">
+        <fes20:Returns>xs:string</fes20:Returns>
+      </fes20:Function>
+      <fes20:Function name="upper">
+        <fes20:Returns>xs:string</fes20:Returns>
+      </fes20:Function>
+    </fes20:Functions>
+  </fes20:Filter_Capabilities>
+</csw30:Capabilities>
diff --git a/tests/expected/suites_cite_get_48f26761-3a9d-48db-bee1-da089f5fb857.xml b/tests/expected/suites_cite_get_48f26761-3a9d-48db-bee1-da089f5fb857.xml
index 5c5c068..2d6fc73 100644
--- a/tests/expected/suites_cite_get_48f26761-3a9d-48db-bee1-da089f5fb857.xml
+++ b/tests/expected/suites_cite_get_48f26761-3a9d-48db-bee1-da089f5fb857.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<csw:Capabilities xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ows="http://www.opengis.net/ows" xmlns:fgdc="http://www.opengis.net/cat/csw/csdgm" xml [...]
+<csw:Capabilities xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ogc="http://www.opengis.net/ogc" xmlns:ows="http://www.opengis.net/ows" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" updateSequence="PYCSW_UPDATESEQUENCE" ve [...]
   <ows:ServiceIdentification>
     <ows:Title>pycsw Geospatial Catalogue</ows:Title>
     <ows:Abstract>pycsw is an OGC CSW server implementation written in Python</ows:Abstract>
@@ -11,6 +11,7 @@
     </ows:Keywords>
     <ows:ServiceType codeSpace="OGC">CSW</ows:ServiceType>
     <ows:ServiceTypeVersion>2.0.2</ows:ServiceTypeVersion>
+    <ows:ServiceTypeVersion>3.0.0</ows:ServiceTypeVersion>
     <ows:Fees>None</ows:Fees>
     <ows:AccessConstraints>None</ows:AccessConstraints>
   </ows:ServiceIdentification>
@@ -49,26 +50,12 @@
         </ows:HTTP>
       </ows:DCP>
       <ows:Parameter name="sections">
+        <ows:Value>Filter_Capabilities</ows:Value>
+        <ows:Value>OperationsMetadata</ows:Value>
         <ows:Value>ServiceIdentification</ows:Value>
         <ows:Value>ServiceProvider</ows:Value>
-        <ows:Value>OperationsMetadata</ows:Value>
-        <ows:Value>Filter_Capabilities</ows:Value>
       </ows:Parameter>
     </ows:Operation>
-    <ows:Operation name="Transaction">
-      <ows:DCP>
-        <ows:HTTP>
-          <ows:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/cite/default.cfg"/>
-        </ows:HTTP>
-      </ows:DCP>
-    </ows:Operation>
-    <ows:Operation name="GetRepositoryItem">
-      <ows:DCP>
-        <ows:HTTP>
-          <ows:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/cite/default.cfg"/>
-        </ows:HTTP>
-      </ows:DCP>
-    </ows:Operation>
     <ows:Operation name="DescribeRecord">
       <ows:DCP>
         <ows:HTTP>
@@ -76,14 +63,14 @@
           <ows:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/cite/default.cfg"/>
         </ows:HTTP>
       </ows:DCP>
-      <ows:Parameter name="schemaLanguage">
-        <ows:Value>http://www.w3.org/XML/Schema</ows:Value>
-        <ows:Value>http://www.w3.org/TR/xmlschema-1/</ows:Value>
-        <ows:Value>http://www.w3.org/2001/XMLSchema</ows:Value>
-      </ows:Parameter>
       <ows:Parameter name="outputFormat">
-        <ows:Value>application/xml</ows:Value>
         <ows:Value>application/json</ows:Value>
+        <ows:Value>application/xml</ows:Value>
+      </ows:Parameter>
+      <ows:Parameter name="schemaLanguage">
+        <ows:Value>http://www.w3.org/2001/XMLSchema</ows:Value>
+        <ows:Value>http://www.w3.org/TR/xmlschema-1/</ows:Value>
+        <ows:Value>http://www.w3.org/XML/Schema</ows:Value>
       </ows:Parameter>
       <ows:Parameter name="typeName">
         <ows:Value>csw:Record</ows:Value>
@@ -97,65 +84,49 @@
         </ows:HTTP>
       </ows:DCP>
       <ows:Parameter name="ParameterName">
-        <ows:Value>GetCapabilities.sections</ows:Value>
-        <ows:Value>DescribeRecord.schemaLanguage</ows:Value>
         <ows:Value>DescribeRecord.outputFormat</ows:Value>
+        <ows:Value>DescribeRecord.schemaLanguage</ows:Value>
         <ows:Value>DescribeRecord.typeName</ows:Value>
+        <ows:Value>GetCapabilities.sections</ows:Value>
+        <ows:Value>GetRecordById.ElementSetName</ows:Value>
         <ows:Value>GetRecordById.outputFormat</ows:Value>
         <ows:Value>GetRecordById.outputSchema</ows:Value>
-        <ows:Value>GetRecordById.ElementSetName</ows:Value>
+        <ows:Value>GetRecords.CONSTRAINTLANGUAGE</ows:Value>
+        <ows:Value>GetRecords.ElementSetName</ows:Value>
         <ows:Value>GetRecords.outputFormat</ows:Value>
         <ows:Value>GetRecords.outputSchema</ows:Value>
-        <ows:Value>GetRecords.CONSTRAINTLANGUAGE</ows:Value>
         <ows:Value>GetRecords.resultType</ows:Value>
         <ows:Value>GetRecords.typeNames</ows:Value>
-        <ows:Value>GetRecords.ElementSetName</ows:Value>
         <ows:Value>Harvest.ResourceType</ows:Value>
+        <ows:Value>Transaction.TransactionSchemas</ows:Value>
       </ows:Parameter>
     </ows:Operation>
-    <ows:Operation name="GetRecordById">
+    <ows:Operation name="GetRecords">
       <ows:DCP>
         <ows:HTTP>
           <ows:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/cite/default.cfg"/>
           <ows:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/cite/default.cfg"/>
         </ows:HTTP>
       </ows:DCP>
-      <ows:Parameter name="outputFormat">
-        <ows:Value>application/xml</ows:Value>
-        <ows:Value>application/json</ows:Value>
-      </ows:Parameter>
-      <ows:Parameter name="outputSchema">
-        <ows:Value>http://www.opengis.net/cat/csw/2.0.2</ows:Value>
-        <ows:Value>http://www.w3.org/2005/Atom</ows:Value>
-        <ows:Value>http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/</ows:Value>
-        <ows:Value>http://www.opengis.net/cat/csw/csdgm</ows:Value>
+      <ows:Parameter name="CONSTRAINTLANGUAGE">
+        <ows:Value>CQL_TEXT</ows:Value>
+        <ows:Value>FILTER</ows:Value>
       </ows:Parameter>
       <ows:Parameter name="ElementSetName">
         <ows:Value>brief</ows:Value>
-        <ows:Value>summary</ows:Value>
         <ows:Value>full</ows:Value>
+        <ows:Value>summary</ows:Value>
       </ows:Parameter>
-    </ows:Operation>
-    <ows:Operation name="GetRecords">
-      <ows:DCP>
-        <ows:HTTP>
-          <ows:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/cite/default.cfg"/>
-          <ows:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/cite/default.cfg"/>
-        </ows:HTTP>
-      </ows:DCP>
       <ows:Parameter name="outputFormat">
-        <ows:Value>application/xml</ows:Value>
         <ows:Value>application/json</ows:Value>
+        <ows:Value>application/xml</ows:Value>
       </ows:Parameter>
       <ows:Parameter name="outputSchema">
-        <ows:Value>http://www.opengis.net/cat/csw/2.0.2</ows:Value>
-        <ows:Value>http://www.w3.org/2005/Atom</ows:Value>
         <ows:Value>http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/</ows:Value>
+        <ows:Value>http://www.interlis.ch/INTERLIS2.3</ows:Value>
+        <ows:Value>http://www.opengis.net/cat/csw/2.0.2</ows:Value>
         <ows:Value>http://www.opengis.net/cat/csw/csdgm</ows:Value>
-      </ows:Parameter>
-      <ows:Parameter name="CONSTRAINTLANGUAGE">
-        <ows:Value>FILTER</ows:Value>
-        <ows:Value>CQL_TEXT</ows:Value>
+        <ows:Value>http://www.w3.org/2005/Atom</ows:Value>
       </ows:Parameter>
       <ows:Parameter name="resultType">
         <ows:Value>hits</ows:Value>
@@ -165,60 +136,110 @@
       <ows:Parameter name="typeNames">
         <ows:Value>csw:Record</ows:Value>
       </ows:Parameter>
-      <ows:Parameter name="ElementSetName">
-        <ows:Value>brief</ows:Value>
-        <ows:Value>summary</ows:Value>
-        <ows:Value>full</ows:Value>
-      </ows:Parameter>
       <ows:Constraint name="SupportedDublinCoreQueryables">
+        <ows:Value>csw:AnyText</ows:Value>
         <ows:Value>dc:contributor</ows:Value>
-        <ows:Value>dc:source</ows:Value>
-        <ows:Value>dc:language</ows:Value>
-        <ows:Value>dc:title</ows:Value>
-        <ows:Value>dc:subject</ows:Value>
         <ows:Value>dc:creator</ows:Value>
-        <ows:Value>dc:type</ows:Value>
-        <ows:Value>ows:BoundingBox</ows:Value>
-        <ows:Value>dct:modified</ows:Value>
-        <ows:Value>dct:abstract</ows:Value>
-        <ows:Value>dc:relation</ows:Value>
         <ows:Value>dc:date</ows:Value>
+        <ows:Value>dc:format</ows:Value>
         <ows:Value>dc:identifier</ows:Value>
+        <ows:Value>dc:language</ows:Value>
         <ows:Value>dc:publisher</ows:Value>
-        <ows:Value>dc:format</ows:Value>
-        <ows:Value>csw:AnyText</ows:Value>
+        <ows:Value>dc:relation</ows:Value>
         <ows:Value>dc:rights</ows:Value>
+        <ows:Value>dc:source</ows:Value>
+        <ows:Value>dc:subject</ows:Value>
+        <ows:Value>dc:title</ows:Value>
+        <ows:Value>dc:type</ows:Value>
+        <ows:Value>dct:abstract</ows:Value>
+        <ows:Value>dct:modified</ows:Value>
+        <ows:Value>ows:BoundingBox</ows:Value>
       </ows:Constraint>
     </ows:Operation>
-    <ows:Operation name="Harvest">
+    <ows:Operation name="GetRecordById">
       <ows:DCP>
         <ows:HTTP>
+          <ows:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/cite/default.cfg"/>
           <ows:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/cite/default.cfg"/>
         </ows:HTTP>
       </ows:DCP>
-      <ows:Parameter name="ResourceType">
+      <ows:Parameter name="ElementSetName">
+        <ows:Value>brief</ows:Value>
+        <ows:Value>full</ows:Value>
+        <ows:Value>summary</ows:Value>
+      </ows:Parameter>
+      <ows:Parameter name="outputFormat">
+        <ows:Value>application/json</ows:Value>
+        <ows:Value>application/xml</ows:Value>
+      </ows:Parameter>
+      <ows:Parameter name="outputSchema">
+        <ows:Value>http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/</ows:Value>
+        <ows:Value>http://www.interlis.ch/INTERLIS2.3</ows:Value>
         <ows:Value>http://www.opengis.net/cat/csw/2.0.2</ows:Value>
-        <ows:Value>http://www.opengis.net/wms</ows:Value>
-        <ows:Value>http://www.opengis.net/wfs</ows:Value>
-        <ows:Value>http://www.opengis.net/wcs</ows:Value>
-        <ows:Value>http://www.opengis.net/wps/1.0.0</ows:Value>
+        <ows:Value>http://www.opengis.net/cat/csw/csdgm</ows:Value>
+        <ows:Value>http://www.w3.org/2005/Atom</ows:Value>
+      </ows:Parameter>
+    </ows:Operation>
+    <ows:Operation name="GetRepositoryItem">
+      <ows:DCP>
+        <ows:HTTP>
+          <ows:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/cite/default.cfg"/>
+        </ows:HTTP>
+      </ows:DCP>
+    </ows:Operation>
+    <ows:Operation name="Transaction">
+      <ows:DCP>
+        <ows:HTTP>
+          <ows:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/cite/default.cfg"/>
+        </ows:HTTP>
+      </ows:DCP>
+      <ows:Parameter name="TransactionSchemas">
+        <ows:Value>http://www.isotc211.org/2005/gmi</ows:Value>
+        <ows:Value>http://www.opengis.net/cat/csw/2.0.2</ows:Value>
+        <ows:Value>http://www.opengis.net/cat/csw/3.0</ows:Value>
         <ows:Value>http://www.opengis.net/sos/1.0</ows:Value>
         <ows:Value>http://www.opengis.net/sos/2.0</ows:Value>
-        <ows:Value>http://www.isotc211.org/2005/gmi</ows:Value>
+        <ows:Value>http://www.opengis.net/wcs</ows:Value>
+        <ows:Value>http://www.opengis.net/wfs</ows:Value>
+        <ows:Value>http://www.opengis.net/wms</ows:Value>
+        <ows:Value>http://www.opengis.net/wmts/1.0</ows:Value>
+        <ows:Value>http://www.opengis.net/wps/1.0.0</ows:Value>
         <ows:Value>urn:geoss:waf</ows:Value>
-        <ows:Value>http://www.w3.org/2005/Atom</ows:Value>
+      </ows:Parameter>
+    </ows:Operation>
+    <ows:Operation name="Harvest">
+      <ows:DCP>
+        <ows:HTTP>
+          <ows:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/cite/default.cfg"/>
+        </ows:HTTP>
+      </ows:DCP>
+      <ows:Parameter name="ResourceType">
         <ows:Value>http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/</ows:Value>
+        <ows:Value>http://www.interlis.ch/INTERLIS2.3</ows:Value>
+        <ows:Value>http://www.isotc211.org/2005/gmi</ows:Value>
+        <ows:Value>http://www.opengis.net/cat/csw/2.0.2</ows:Value>
+        <ows:Value>http://www.opengis.net/cat/csw/3.0</ows:Value>
         <ows:Value>http://www.opengis.net/cat/csw/csdgm</ows:Value>
+        <ows:Value>http://www.opengis.net/sos/1.0</ows:Value>
+        <ows:Value>http://www.opengis.net/sos/2.0</ows:Value>
+        <ows:Value>http://www.opengis.net/wcs</ows:Value>
+        <ows:Value>http://www.opengis.net/wfs</ows:Value>
+        <ows:Value>http://www.opengis.net/wms</ows:Value>
+        <ows:Value>http://www.opengis.net/wmts/1.0</ows:Value>
+        <ows:Value>http://www.opengis.net/wps/1.0.0</ows:Value>
+        <ows:Value>http://www.w3.org/2005/Atom</ows:Value>
+        <ows:Value>urn:geoss:waf</ows:Value>
       </ows:Parameter>
     </ows:Operation>
-    <ows:Parameter name="version">
-      <ows:Value>2.0.2</ows:Value>
-    </ows:Parameter>
     <ows:Parameter name="service">
       <ows:Value>CSW</ows:Value>
     </ows:Parameter>
-    <ows:Constraint name="XPathQueryables">
-      <ows:Value>allowed</ows:Value>
+    <ows:Parameter name="version">
+      <ows:Value>2.0.2</ows:Value>
+      <ows:Value>3.0.0</ows:Value>
+    </ows:Parameter>
+    <ows:Constraint name="FederatedCatalogues">
+      <ows:Value>http://geo.data.gov/geoportal/csw/discovery</ows:Value>
     </ows:Constraint>
     <ows:Constraint name="MaxRecordDefault">
       <ows:Value>10</ows:Value>
@@ -227,8 +248,8 @@
       <ows:Value>XML</ows:Value>
       <ows:Value>SOAP</ows:Value>
     </ows:Constraint>
-    <ows:Constraint name="FederatedCatalogues">
-      <ows:Value>http://geo.data.gov/geoportal/csw/discovery</ows:Value>
+    <ows:Constraint name="XPathQueryables">
+      <ows:Value>allowed</ows:Value>
     </ows:Constraint>
   </ows:OperationsMetadata>
   <ogc:Filter_Capabilities>
@@ -258,11 +279,11 @@
       <ogc:ComparisonOperators>
         <ogc:ComparisonOperator>Between</ogc:ComparisonOperator>
         <ogc:ComparisonOperator>EqualTo</ogc:ComparisonOperator>
-        <ogc:ComparisonOperator>LessThanEqualTo</ogc:ComparisonOperator>
         <ogc:ComparisonOperator>GreaterThan</ogc:ComparisonOperator>
-        <ogc:ComparisonOperator>Like</ogc:ComparisonOperator>
-        <ogc:ComparisonOperator>LessThan</ogc:ComparisonOperator>
         <ogc:ComparisonOperator>GreaterThanEqualTo</ogc:ComparisonOperator>
+        <ogc:ComparisonOperator>LessThan</ogc:ComparisonOperator>
+        <ogc:ComparisonOperator>LessThanEqualTo</ogc:ComparisonOperator>
+        <ogc:ComparisonOperator>Like</ogc:ComparisonOperator>
         <ogc:ComparisonOperator>NotEqualTo</ogc:ComparisonOperator>
         <ogc:ComparisonOperator>NullCheck</ogc:ComparisonOperator>
       </ogc:ComparisonOperators>
diff --git a/tests/expected/suites_cite_get_4e38092f-1586-44b8-988e-0acfa5855916.xml b/tests/expected/suites_cite_get_4e38092f-1586-44b8-988e-0acfa5855916.xml
index ef68f28..82bbd70 100644
--- a/tests/expected/suites_cite_get_4e38092f-1586-44b8-988e-0acfa5855916.xml
+++ b/tests/expected/suites_cite_get_4e38092f-1586-44b8-988e-0acfa5855916.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<ows:ExceptionReport xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ows="http://www.opengis.net/ows" xmlns:fgdc="http://www.opengis.net/cat/csw/csdgm"  [...]
+<ows:ExceptionReport xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" language="en-US" version="1.2.0" xsi:schemaLocation="http://www.opengis.net/ows http://schemas.opengis.net/ows/1.0.0/ow [...]
   <ows:Exception exceptionCode="InvalidParameterValue" locator="outputformat">
     <ows:ExceptionText>Invalid outputformat parameter application/bogus_xml</ows:ExceptionText>
   </ows:Exception>
diff --git a/tests/expected/suites_cite_get_55c38f00-2553-42c1-99ab-33edbb561ad7.xml b/tests/expected/suites_cite_get_55c38f00-2553-42c1-99ab-33edbb561ad7.xml
index de807dd..7d56ad6 100644
--- a/tests/expected/suites_cite_get_55c38f00-2553-42c1-99ab-33edbb561ad7.xml
+++ b/tests/expected/suites_cite_get_55c38f00-2553-42c1-99ab-33edbb561ad7.xml
@@ -1,261 +1,390 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<csw:Capabilities xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ows="http://www.opengis.net/ows" xmlns:fgdc="http://www.opengis.net/cat/csw/csdgm" xml [...]
-  <ows:ServiceIdentification>
-    <ows:Title>pycsw Geospatial Catalogue</ows:Title>
-    <ows:Abstract>pycsw is an OGC CSW server implementation written in Python</ows:Abstract>
-    <ows:Keywords>
-      <ows:Keyword>catalogue</ows:Keyword>
-      <ows:Keyword>discovery</ows:Keyword>
-      <ows:Type codeSpace="ISOTC211/19115">theme</ows:Type>
-    </ows:Keywords>
-    <ows:ServiceType codeSpace="OGC">CSW</ows:ServiceType>
-    <ows:ServiceTypeVersion>2.0.2</ows:ServiceTypeVersion>
-    <ows:Fees>None</ows:Fees>
-    <ows:AccessConstraints>None</ows:AccessConstraints>
-  </ows:ServiceIdentification>
-  <ows:OperationsMetadata>
-    <ows:Operation name="GetCapabilities">
-      <ows:DCP>
-        <ows:HTTP>
-          <ows:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/cite/default.cfg"/>
-          <ows:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/cite/default.cfg"/>
-        </ows:HTTP>
-      </ows:DCP>
-      <ows:Parameter name="sections">
-        <ows:Value>ServiceIdentification</ows:Value>
-        <ows:Value>ServiceProvider</ows:Value>
-        <ows:Value>OperationsMetadata</ows:Value>
-        <ows:Value>Filter_Capabilities</ows:Value>
-      </ows:Parameter>
-    </ows:Operation>
-    <ows:Operation name="Transaction">
-      <ows:DCP>
-        <ows:HTTP>
-          <ows:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/cite/default.cfg"/>
-        </ows:HTTP>
-      </ows:DCP>
-    </ows:Operation>
-    <ows:Operation name="GetRepositoryItem">
-      <ows:DCP>
-        <ows:HTTP>
-          <ows:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/cite/default.cfg"/>
-        </ows:HTTP>
-      </ows:DCP>
-    </ows:Operation>
-    <ows:Operation name="DescribeRecord">
-      <ows:DCP>
-        <ows:HTTP>
-          <ows:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/cite/default.cfg"/>
-          <ows:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/cite/default.cfg"/>
-        </ows:HTTP>
-      </ows:DCP>
-      <ows:Parameter name="schemaLanguage">
-        <ows:Value>http://www.w3.org/XML/Schema</ows:Value>
-        <ows:Value>http://www.w3.org/TR/xmlschema-1/</ows:Value>
-        <ows:Value>http://www.w3.org/2001/XMLSchema</ows:Value>
-      </ows:Parameter>
-      <ows:Parameter name="outputFormat">
-        <ows:Value>application/xml</ows:Value>
-        <ows:Value>application/json</ows:Value>
-      </ows:Parameter>
-      <ows:Parameter name="typeName">
-        <ows:Value>csw:Record</ows:Value>
-      </ows:Parameter>
-    </ows:Operation>
-    <ows:Operation name="GetDomain">
-      <ows:DCP>
-        <ows:HTTP>
-          <ows:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/cite/default.cfg"/>
-          <ows:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/cite/default.cfg"/>
-        </ows:HTTP>
-      </ows:DCP>
-      <ows:Parameter name="ParameterName">
-        <ows:Value>GetCapabilities.sections</ows:Value>
-        <ows:Value>DescribeRecord.schemaLanguage</ows:Value>
-        <ows:Value>DescribeRecord.outputFormat</ows:Value>
-        <ows:Value>DescribeRecord.typeName</ows:Value>
-        <ows:Value>GetRecordById.outputFormat</ows:Value>
-        <ows:Value>GetRecordById.outputSchema</ows:Value>
-        <ows:Value>GetRecordById.ElementSetName</ows:Value>
-        <ows:Value>GetRecords.outputFormat</ows:Value>
-        <ows:Value>GetRecords.outputSchema</ows:Value>
-        <ows:Value>GetRecords.CONSTRAINTLANGUAGE</ows:Value>
-        <ows:Value>GetRecords.resultType</ows:Value>
-        <ows:Value>GetRecords.typeNames</ows:Value>
-        <ows:Value>GetRecords.ElementSetName</ows:Value>
-        <ows:Value>Harvest.ResourceType</ows:Value>
-      </ows:Parameter>
-    </ows:Operation>
-    <ows:Operation name="GetRecordById">
-      <ows:DCP>
-        <ows:HTTP>
-          <ows:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/cite/default.cfg"/>
-          <ows:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/cite/default.cfg"/>
-        </ows:HTTP>
-      </ows:DCP>
-      <ows:Parameter name="outputFormat">
-        <ows:Value>application/xml</ows:Value>
-        <ows:Value>application/json</ows:Value>
-      </ows:Parameter>
-      <ows:Parameter name="outputSchema">
-        <ows:Value>http://www.opengis.net/cat/csw/2.0.2</ows:Value>
-        <ows:Value>http://www.w3.org/2005/Atom</ows:Value>
-        <ows:Value>http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/</ows:Value>
-        <ows:Value>http://www.opengis.net/cat/csw/csdgm</ows:Value>
-      </ows:Parameter>
-      <ows:Parameter name="ElementSetName">
-        <ows:Value>brief</ows:Value>
-        <ows:Value>summary</ows:Value>
-        <ows:Value>full</ows:Value>
-      </ows:Parameter>
-    </ows:Operation>
-    <ows:Operation name="GetRecords">
-      <ows:DCP>
-        <ows:HTTP>
-          <ows:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/cite/default.cfg"/>
-          <ows:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/cite/default.cfg"/>
-        </ows:HTTP>
-      </ows:DCP>
-      <ows:Parameter name="outputFormat">
-        <ows:Value>application/xml</ows:Value>
-        <ows:Value>application/json</ows:Value>
-      </ows:Parameter>
-      <ows:Parameter name="outputSchema">
-        <ows:Value>http://www.opengis.net/cat/csw/2.0.2</ows:Value>
-        <ows:Value>http://www.w3.org/2005/Atom</ows:Value>
-        <ows:Value>http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/</ows:Value>
-        <ows:Value>http://www.opengis.net/cat/csw/csdgm</ows:Value>
-      </ows:Parameter>
-      <ows:Parameter name="CONSTRAINTLANGUAGE">
-        <ows:Value>FILTER</ows:Value>
-        <ows:Value>CQL_TEXT</ows:Value>
-      </ows:Parameter>
-      <ows:Parameter name="resultType">
-        <ows:Value>hits</ows:Value>
-        <ows:Value>results</ows:Value>
-        <ows:Value>validate</ows:Value>
-      </ows:Parameter>
-      <ows:Parameter name="typeNames">
-        <ows:Value>csw:Record</ows:Value>
-      </ows:Parameter>
-      <ows:Parameter name="ElementSetName">
-        <ows:Value>brief</ows:Value>
-        <ows:Value>summary</ows:Value>
-        <ows:Value>full</ows:Value>
-      </ows:Parameter>
-      <ows:Constraint name="SupportedDublinCoreQueryables">
-        <ows:Value>dc:contributor</ows:Value>
-        <ows:Value>dc:source</ows:Value>
-        <ows:Value>dc:language</ows:Value>
-        <ows:Value>dc:title</ows:Value>
-        <ows:Value>dc:subject</ows:Value>
-        <ows:Value>dc:creator</ows:Value>
-        <ows:Value>dc:type</ows:Value>
-        <ows:Value>ows:BoundingBox</ows:Value>
-        <ows:Value>dct:modified</ows:Value>
-        <ows:Value>dct:abstract</ows:Value>
-        <ows:Value>dc:relation</ows:Value>
-        <ows:Value>dc:date</ows:Value>
-        <ows:Value>dc:identifier</ows:Value>
-        <ows:Value>dc:publisher</ows:Value>
-        <ows:Value>dc:format</ows:Value>
-        <ows:Value>csw:AnyText</ows:Value>
-        <ows:Value>dc:rights</ows:Value>
-      </ows:Constraint>
-    </ows:Operation>
-    <ows:Operation name="Harvest">
-      <ows:DCP>
-        <ows:HTTP>
-          <ows:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/cite/default.cfg"/>
-        </ows:HTTP>
-      </ows:DCP>
-      <ows:Parameter name="ResourceType">
-        <ows:Value>http://www.opengis.net/cat/csw/2.0.2</ows:Value>
-        <ows:Value>http://www.opengis.net/wms</ows:Value>
-        <ows:Value>http://www.opengis.net/wfs</ows:Value>
-        <ows:Value>http://www.opengis.net/wcs</ows:Value>
-        <ows:Value>http://www.opengis.net/wps/1.0.0</ows:Value>
-        <ows:Value>http://www.opengis.net/sos/1.0</ows:Value>
-        <ows:Value>http://www.opengis.net/sos/2.0</ows:Value>
-        <ows:Value>http://www.isotc211.org/2005/gmi</ows:Value>
-        <ows:Value>urn:geoss:waf</ows:Value>
-        <ows:Value>http://www.w3.org/2005/Atom</ows:Value>
-        <ows:Value>http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/</ows:Value>
-        <ows:Value>http://www.opengis.net/cat/csw/csdgm</ows:Value>
-      </ows:Parameter>
-    </ows:Operation>
-    <ows:Parameter name="version">
-      <ows:Value>2.0.2</ows:Value>
-    </ows:Parameter>
-    <ows:Parameter name="service">
-      <ows:Value>CSW</ows:Value>
-    </ows:Parameter>
-    <ows:Constraint name="XPathQueryables">
-      <ows:Value>allowed</ows:Value>
-    </ows:Constraint>
-    <ows:Constraint name="MaxRecordDefault">
-      <ows:Value>10</ows:Value>
-    </ows:Constraint>
-    <ows:Constraint name="PostEncoding">
-      <ows:Value>XML</ows:Value>
-      <ows:Value>SOAP</ows:Value>
-    </ows:Constraint>
-    <ows:Constraint name="FederatedCatalogues">
-      <ows:Value>http://geo.data.gov/geoportal/csw/discovery</ows:Value>
-    </ows:Constraint>
-  </ows:OperationsMetadata>
-  <ogc:Filter_Capabilities>
-    <ogc:Spatial_Capabilities>
-      <ogc:GeometryOperands>
-        <ogc:GeometryOperand>gml:Point</ogc:GeometryOperand>
-        <ogc:GeometryOperand>gml:LineString</ogc:GeometryOperand>
-        <ogc:GeometryOperand>gml:Polygon</ogc:GeometryOperand>
-        <ogc:GeometryOperand>gml:Envelope</ogc:GeometryOperand>
-      </ogc:GeometryOperands>
-      <ogc:SpatialOperators>
-        <ogc:SpatialOperator name="BBOX"/>
-        <ogc:SpatialOperator name="Beyond"/>
-        <ogc:SpatialOperator name="Contains"/>
-        <ogc:SpatialOperator name="Crosses"/>
-        <ogc:SpatialOperator name="Disjoint"/>
-        <ogc:SpatialOperator name="DWithin"/>
-        <ogc:SpatialOperator name="Equals"/>
-        <ogc:SpatialOperator name="Intersects"/>
-        <ogc:SpatialOperator name="Overlaps"/>
-        <ogc:SpatialOperator name="Touches"/>
-        <ogc:SpatialOperator name="Within"/>
-      </ogc:SpatialOperators>
-    </ogc:Spatial_Capabilities>
-    <ogc:Scalar_Capabilities>
-      <ogc:LogicalOperators/>
-      <ogc:ComparisonOperators>
-        <ogc:ComparisonOperator>Between</ogc:ComparisonOperator>
-        <ogc:ComparisonOperator>EqualTo</ogc:ComparisonOperator>
-        <ogc:ComparisonOperator>LessThanEqualTo</ogc:ComparisonOperator>
-        <ogc:ComparisonOperator>GreaterThan</ogc:ComparisonOperator>
-        <ogc:ComparisonOperator>Like</ogc:ComparisonOperator>
-        <ogc:ComparisonOperator>LessThan</ogc:ComparisonOperator>
-        <ogc:ComparisonOperator>GreaterThanEqualTo</ogc:ComparisonOperator>
-        <ogc:ComparisonOperator>NotEqualTo</ogc:ComparisonOperator>
-        <ogc:ComparisonOperator>NullCheck</ogc:ComparisonOperator>
-      </ogc:ComparisonOperators>
-      <ogc:ArithmeticOperators>
-        <ogc:Functions>
-          <ogc:FunctionNames>
-            <ogc:FunctionName nArgs="1">length</ogc:FunctionName>
-            <ogc:FunctionName nArgs="1">lower</ogc:FunctionName>
-            <ogc:FunctionName nArgs="1">ltrim</ogc:FunctionName>
-            <ogc:FunctionName nArgs="1">rtrim</ogc:FunctionName>
-            <ogc:FunctionName nArgs="1">trim</ogc:FunctionName>
-            <ogc:FunctionName nArgs="1">upper</ogc:FunctionName>
-          </ogc:FunctionNames>
-        </ogc:Functions>
-      </ogc:ArithmeticOperators>
-    </ogc:Scalar_Capabilities>
-    <ogc:Id_Capabilities>
-      <ogc:EID/>
-      <ogc:FID/>
-    </ogc:Id_Capabilities>
-  </ogc:Filter_Capabilities>
-</csw:Capabilities>
+<csw30:Capabilities xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:csw30="http://www.opengis.net/cat/csw/3.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:ows20="http://www.opengis.net/ows/2.0" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XML [...]
+  <ows20:ServiceIdentification>
+    <ows20:Title>pycsw Geospatial Catalogue</ows20:Title>
+    <ows20:Abstract>pycsw is an OGC CSW server implementation written in Python</ows20:Abstract>
+    <ows20:Keywords>
+      <ows20:Keyword>catalogue</ows20:Keyword>
+      <ows20:Keyword>discovery</ows20:Keyword>
+      <ows20:Type codeSpace="ISOTC211/19115">theme</ows20:Type>
+    </ows20:Keywords>
+    <ows20:ServiceType codeSpace="OGC">CSW</ows20:ServiceType>
+    <ows20:ServiceTypeVersion>2.0.2</ows20:ServiceTypeVersion>
+    <ows20:ServiceTypeVersion>3.0.0</ows20:ServiceTypeVersion>
+    <ows20:Fees>None</ows20:Fees>
+    <ows20:AccessConstraints>None</ows20:AccessConstraints>
+  </ows20:ServiceIdentification>
+  <ows20:OperationsMetadata>
+    <ows20:Operation name="GetCapabilities">
+      <ows20:DCP>
+        <ows20:HTTP>
+          <ows20:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/cite/default.cfg"/>
+          <ows20:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/cite/default.cfg"/>
+        </ows20:HTTP>
+      </ows20:DCP>
+      <ows20:Parameter name="acceptFormats">
+        <ows20:AllowedValues>
+          <ows20:Value>application/xml</ows20:Value>
+          <ows20:Value>text/xml</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Parameter name="acceptVersions">
+        <ows20:AllowedValues>
+          <ows20:Value>2.0.2</ows20:Value>
+          <ows20:Value>3.0.0</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Parameter name="sections">
+        <ows20:AllowedValues>
+          <ows20:Value>All</ows20:Value>
+          <ows20:Value>Filter_Capabilities</ows20:Value>
+          <ows20:Value>OperationsMetadata</ows20:Value>
+          <ows20:Value>ServiceIdentification</ows20:Value>
+          <ows20:Value>ServiceProvider</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+    </ows20:Operation>
+    <ows20:Operation name="GetDomain">
+      <ows20:DCP>
+        <ows20:HTTP>
+          <ows20:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/cite/default.cfg"/>
+          <ows20:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/cite/default.cfg"/>
+        </ows20:HTTP>
+      </ows20:DCP>
+      <ows20:Parameter name="ParameterName">
+        <ows20:AllowedValues>
+          <ows20:Value>GetCapabilities.acceptFormats</ows20:Value>
+          <ows20:Value>GetCapabilities.acceptVersions</ows20:Value>
+          <ows20:Value>GetCapabilities.sections</ows20:Value>
+          <ows20:Value>GetRecordById.ElementSetName</ows20:Value>
+          <ows20:Value>GetRecordById.outputFormat</ows20:Value>
+          <ows20:Value>GetRecordById.outputSchema</ows20:Value>
+          <ows20:Value>GetRecords.CONSTRAINTLANGUAGE</ows20:Value>
+          <ows20:Value>GetRecords.ElementSetName</ows20:Value>
+          <ows20:Value>GetRecords.outputFormat</ows20:Value>
+          <ows20:Value>GetRecords.outputSchema</ows20:Value>
+          <ows20:Value>GetRecords.typeNames</ows20:Value>
+          <ows20:Value>Harvest.ResourceType</ows20:Value>
+          <ows20:Value>Transaction.TransactionSchemas</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+    </ows20:Operation>
+    <ows20:Operation name="GetRecords">
+      <ows20:DCP>
+        <ows20:HTTP>
+          <ows20:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/cite/default.cfg"/>
+          <ows20:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/cite/default.cfg"/>
+        </ows20:HTTP>
+      </ows20:DCP>
+      <ows20:Parameter name="CONSTRAINTLANGUAGE">
+        <ows20:AllowedValues>
+          <ows20:Value>CQL_TEXT</ows20:Value>
+          <ows20:Value>FILTER</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Parameter name="ElementSetName">
+        <ows20:AllowedValues>
+          <ows20:Value>brief</ows20:Value>
+          <ows20:Value>full</ows20:Value>
+          <ows20:Value>summary</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Parameter name="outputFormat">
+        <ows20:AllowedValues>
+          <ows20:Value>application/atom+xml</ows20:Value>
+          <ows20:Value>application/json</ows20:Value>
+          <ows20:Value>application/xml</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Parameter name="outputSchema">
+        <ows20:AllowedValues>
+          <ows20:Value>http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/</ows20:Value>
+          <ows20:Value>http://www.interlis.ch/INTERLIS2.3</ows20:Value>
+          <ows20:Value>http://www.opengis.net/cat/csw/3.0</ows20:Value>
+          <ows20:Value>http://www.opengis.net/cat/csw/csdgm</ows20:Value>
+          <ows20:Value>http://www.w3.org/2005/Atom</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Parameter name="typeNames">
+        <ows20:AllowedValues>
+          <ows20:Value>csw:Record</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Constraint name="MaxRecordDefault">
+        <ows20:AllowedValues>
+          <ows20:Value>10</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Constraint>
+      <ows20:Constraint name="OpenSearchDescriptionDocument">
+        <ows20:AllowedValues>
+          <ows20:Value>http://localhost/pycsw/csw.py?config=tests/suites/cite/default.cfg?mode=opensearch&service=CSW&version=3.0.0&request=GetCapabilities</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Constraint>
+      <ows20:Constraint name="FederatedCatalogues">
+        <ows20:AllowedValues>
+          <ows20:Value>http://geo.data.gov/geoportal/csw/discovery</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Constraint>
+    </ows20:Operation>
+    <ows20:Operation name="GetRecordById">
+      <ows20:DCP>
+        <ows20:HTTP>
+          <ows20:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/cite/default.cfg"/>
+          <ows20:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/cite/default.cfg"/>
+        </ows20:HTTP>
+      </ows20:DCP>
+      <ows20:Parameter name="ElementSetName">
+        <ows20:AllowedValues>
+          <ows20:Value>brief</ows20:Value>
+          <ows20:Value>full</ows20:Value>
+          <ows20:Value>summary</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Parameter name="outputFormat">
+        <ows20:AllowedValues>
+          <ows20:Value>application/atom+xml</ows20:Value>
+          <ows20:Value>application/json</ows20:Value>
+          <ows20:Value>application/xml</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Parameter name="outputSchema">
+        <ows20:AllowedValues>
+          <ows20:Value>http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/</ows20:Value>
+          <ows20:Value>http://www.interlis.ch/INTERLIS2.3</ows20:Value>
+          <ows20:Value>http://www.opengis.net/cat/csw/3.0</ows20:Value>
+          <ows20:Value>http://www.opengis.net/cat/csw/csdgm</ows20:Value>
+          <ows20:Value>http://www.w3.org/2005/Atom</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+    </ows20:Operation>
+    <ows20:Operation name="GetRepositoryItem">
+      <ows20:DCP>
+        <ows20:HTTP>
+          <ows20:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/cite/default.cfg"/>
+        </ows20:HTTP>
+      </ows20:DCP>
+    </ows20:Operation>
+    <ows20:Operation name="Transaction">
+      <ows20:DCP>
+        <ows20:HTTP>
+          <ows20:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/cite/default.cfg"/>
+        </ows20:HTTP>
+      </ows20:DCP>
+      <ows20:Parameter name="TransactionSchemas">
+        <ows20:AllowedValues>
+          <ows20:Value>http://www.isotc211.org/2005/gmi</ows20:Value>
+          <ows20:Value>http://www.opengis.net/cat/csw/2.0.2</ows20:Value>
+          <ows20:Value>http://www.opengis.net/cat/csw/3.0</ows20:Value>
+          <ows20:Value>http://www.opengis.net/sos/1.0</ows20:Value>
+          <ows20:Value>http://www.opengis.net/sos/2.0</ows20:Value>
+          <ows20:Value>http://www.opengis.net/wcs</ows20:Value>
+          <ows20:Value>http://www.opengis.net/wfs</ows20:Value>
+          <ows20:Value>http://www.opengis.net/wms</ows20:Value>
+          <ows20:Value>http://www.opengis.net/wmts/1.0</ows20:Value>
+          <ows20:Value>http://www.opengis.net/wps/1.0.0</ows20:Value>
+          <ows20:Value>urn:geoss:waf</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+    </ows20:Operation>
+    <ows20:Operation name="Harvest">
+      <ows20:DCP>
+        <ows20:HTTP>
+          <ows20:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/cite/default.cfg"/>
+        </ows20:HTTP>
+      </ows20:DCP>
+      <ows20:Parameter name="ResourceType">
+        <ows20:AllowedValues>
+          <ows20:Value>http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/</ows20:Value>
+          <ows20:Value>http://www.interlis.ch/INTERLIS2.3</ows20:Value>
+          <ows20:Value>http://www.isotc211.org/2005/gmi</ows20:Value>
+          <ows20:Value>http://www.opengis.net/cat/csw/2.0.2</ows20:Value>
+          <ows20:Value>http://www.opengis.net/cat/csw/3.0</ows20:Value>
+          <ows20:Value>http://www.opengis.net/cat/csw/csdgm</ows20:Value>
+          <ows20:Value>http://www.opengis.net/sos/1.0</ows20:Value>
+          <ows20:Value>http://www.opengis.net/sos/2.0</ows20:Value>
+          <ows20:Value>http://www.opengis.net/wcs</ows20:Value>
+          <ows20:Value>http://www.opengis.net/wfs</ows20:Value>
+          <ows20:Value>http://www.opengis.net/wms</ows20:Value>
+          <ows20:Value>http://www.opengis.net/wmts/1.0</ows20:Value>
+          <ows20:Value>http://www.opengis.net/wps/1.0.0</ows20:Value>
+          <ows20:Value>http://www.w3.org/2005/Atom</ows20:Value>
+          <ows20:Value>urn:geoss:waf</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+    </ows20:Operation>
+    <ows20:Parameter name="service">
+      <ows20:AllowedValues>
+        <ows20:Value>CSW</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Parameter>
+    <ows20:Parameter name="version">
+      <ows20:AllowedValues>
+        <ows20:Value>2.0.2</ows20:Value>
+        <ows20:Value>3.0.0</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Parameter>
+    <ows20:Constraint name="CoreQueryables">
+      <ows20:AllowedValues>
+        <ows20:Value>csw:AnyText</ows20:Value>
+        <ows20:Value>dc:contributor</ows20:Value>
+        <ows20:Value>dc:creator</ows20:Value>
+        <ows20:Value>dc:date</ows20:Value>
+        <ows20:Value>dc:format</ows20:Value>
+        <ows20:Value>dc:identifier</ows20:Value>
+        <ows20:Value>dc:language</ows20:Value>
+        <ows20:Value>dc:publisher</ows20:Value>
+        <ows20:Value>dc:relation</ows20:Value>
+        <ows20:Value>dc:rights</ows20:Value>
+        <ows20:Value>dc:source</ows20:Value>
+        <ows20:Value>dc:subject</ows20:Value>
+        <ows20:Value>dc:title</ows20:Value>
+        <ows20:Value>dc:type</ows20:Value>
+        <ows20:Value>dct:abstract</ows20:Value>
+        <ows20:Value>dct:modified</ows20:Value>
+        <ows20:Value>ows:BoundingBox</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="FederatedCatalogues">
+      <ows20:AllowedValues>
+        <ows20:Value>http://geo.data.gov/geoportal/csw/discovery</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="MaxRecordDefault">
+      <ows20:AllowedValues>
+        <ows20:Value>10</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="PostEncoding">
+      <ows20:AllowedValues>
+        <ows20:Value>SOAP</ows20:Value>
+        <ows20:Value>XML</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="XPathQueryables">
+      <ows20:AllowedValues>
+        <ows20:Value>allowed</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/CoreQueryables">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/CoreSortables">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/DefaultSortingAlgorithm">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Filter-CQL">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Filter-FES-KVP-Advanced">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Filter-FES-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetCapabilities-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetDomain-KVP">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetDomain-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetRecordById-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetRecords-Async-KVP">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetRecords-Async-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetRecords-Basic-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetRecords-Distributed-KVP">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetRecords-Distributed-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Harvest-Async-KVP">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Harvest-Async-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Harvest-Basic-KVP">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Harvest-Basic-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Harvest-Periodic-KVP">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Harvest-Periodic-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/OpenSearch">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/SupportedGMLVersions">
+      <ows20:AllowedValues>
+        <ows20:Value>http://www.opengis.net/gml</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Transaction">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+  </ows20:OperationsMetadata>
+</csw30:Capabilities>
diff --git a/tests/expected/suites_cite_get_5ab5db18-c87a-4fbf-a8d8-b7289b09ac81.xml b/tests/expected/suites_cite_get_5ab5db18-c87a-4fbf-a8d8-b7289b09ac81.xml
index 3e2471b..407b97b 100644
--- a/tests/expected/suites_cite_get_5ab5db18-c87a-4fbf-a8d8-b7289b09ac81.xml
+++ b/tests/expected/suites_cite_get_5ab5db18-c87a-4fbf-a8d8-b7289b09ac81.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<ows:ExceptionReport xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ows="http://www.opengis.net/ows" xmlns:fgdc="http://www.opengis.net/cat/csw/csdgm"  [...]
-  <ows:Exception exceptionCode="InvalidParameterValue" locator="service">
-    <ows:ExceptionText>Invalid value for service: FOO.                    Value MUST be CSW</ows:ExceptionText>
-  </ows:Exception>
-</ows:ExceptionReport>
+<ows20:ExceptionReport xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:ows20="http://www.opengis.net/ows/2.0" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="3.0.0" xml:lang="en-US" xsi:schemaLocation="http://www.opengis. [...]
+  <ows20:Exception exceptionCode="InvalidParameterValue" locator="service">
+    <ows20:ExceptionText>Invalid value for service: FOO.                    Value MUST be CSW</ows20:ExceptionText>
+  </ows20:Exception>
+</ows20:ExceptionReport>
diff --git a/tests/expected/suites_cite_get_6a4f57ca-a1bd-4802-89c2-44860dbdb0f0.xml b/tests/expected/suites_cite_get_6a4f57ca-a1bd-4802-89c2-44860dbdb0f0.xml
index b660099..5ef23a7 100644
--- a/tests/expected/suites_cite_get_6a4f57ca-a1bd-4802-89c2-44860dbdb0f0.xml
+++ b/tests/expected/suites_cite_get_6a4f57ca-a1bd-4802-89c2-44860dbdb0f0.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<csw:GetRecordByIdResponse xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ows="http://www.opengis.net/ows" xmlns:fgdc="http://www.opengis.net/cat/csw/c [...]
+<csw:GetRecordByIdResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/cat/csw/2.0.2 http://schemas.opengis.net/csw/2.0.2/CSW-discovery.xsd">
   <csw:SummaryRecord>
     <dc:identifier>urn:uuid:6a3de50b-fa66-4b58-a0e6-ca146fdd18d4</dc:identifier>
     <dc:title>Ut facilisis justo ut lacus</dc:title>
diff --git a/tests/expected/suites_cite_get_6c375703-9c00-4aef-bec7-d2e964f849eb.xml b/tests/expected/suites_cite_get_6c375703-9c00-4aef-bec7-d2e964f849eb.xml
index 6cc4618..6ac7055 100644
--- a/tests/expected/suites_cite_get_6c375703-9c00-4aef-bec7-d2e964f849eb.xml
+++ b/tests/expected/suites_cite_get_6c375703-9c00-4aef-bec7-d2e964f849eb.xml
@@ -1,11 +1,13 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<csw:GetRecordByIdResponse xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ows="http://www.opengis.net/ows" xmlns:fgdc="http://www.opengis.net/cat/csw/c [...]
-  <atom:entry xmlns:georss="http://www.georss.org/georss" xsi:schemaLocation="http://www.w3.org/2005/Atom http://www.kbcafe.com/rss/atom.xsd.xml">
-    <atom:category>Tourism--Greece</atom:category>
+<csw:GetRecordByIdResponse xmlns:atom="http://www.w3.org/2005/Atom" xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/cat/csw/2.0.2 http://schemas. [...]
+  <atom:entry xsi:schemaLocation="http://www.w3.org/2005/Atom http://www.kbcafe.com/rss/atom.xsd.xml">
+    <atom:category term="Tourism--Greece"/>
     <atom:id>urn:uuid:19887a8a-f6b0-4a63-ae56-7fba0e17801f</atom:id>
+    <dc:identifier>urn:uuid:19887a8a-f6b0-4a63-ae56-7fba0e17801f</dc:identifier>
     <atom:link href="http://localhost/pycsw/csw.py?config=tests/suites/cite/default.cfg?service=CSW&version=2.0.2&request=GetRepositoryItem&id=urn:uuid:19887a8a-f6b0-4a63-ae56-7fba0e17801f"/>
-    <atom:summary>Quisque lacus diam, placerat mollis, pharetra in, commodo sed, augue. Duis iaculis arcu vel arcu.</atom:summary>
     <atom:title>Lorem ipsum</atom:title>
+    <atom:updated>PYCSW_TIMESTAMP</atom:updated>
+    <atom:summary>Quisque lacus diam, placerat mollis, pharetra in, commodo sed, augue. Duis iaculis arcu vel arcu.</atom:summary>
   </atom:entry>
 </csw:GetRecordByIdResponse>
diff --git a/tests/expected/suites_cite_get_80f31def-4185-48b9-983a-960566918eae.xml b/tests/expected/suites_cite_get_80f31def-4185-48b9-983a-960566918eae.xml
index 5c5c068..d127684 100644
--- a/tests/expected/suites_cite_get_80f31def-4185-48b9-983a-960566918eae.xml
+++ b/tests/expected/suites_cite_get_80f31def-4185-48b9-983a-960566918eae.xml
@@ -1,287 +1,541 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<csw:Capabilities xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ows="http://www.opengis.net/ows" xmlns:fgdc="http://www.opengis.net/cat/csw/csdgm" xml [...]
-  <ows:ServiceIdentification>
-    <ows:Title>pycsw Geospatial Catalogue</ows:Title>
-    <ows:Abstract>pycsw is an OGC CSW server implementation written in Python</ows:Abstract>
-    <ows:Keywords>
-      <ows:Keyword>catalogue</ows:Keyword>
-      <ows:Keyword>discovery</ows:Keyword>
-      <ows:Type codeSpace="ISOTC211/19115">theme</ows:Type>
-    </ows:Keywords>
-    <ows:ServiceType codeSpace="OGC">CSW</ows:ServiceType>
-    <ows:ServiceTypeVersion>2.0.2</ows:ServiceTypeVersion>
-    <ows:Fees>None</ows:Fees>
-    <ows:AccessConstraints>None</ows:AccessConstraints>
-  </ows:ServiceIdentification>
-  <ows:ServiceProvider>
-    <ows:ProviderName>pycsw</ows:ProviderName>
-    <ows:ProviderSite xlink:type="simple" xlink:href="http://pycsw.org/"/>
-    <ows:ServiceContact>
-      <ows:IndividualName>Kralidis, Tom</ows:IndividualName>
-      <ows:PositionName>Senior Systems Scientist</ows:PositionName>
-      <ows:ContactInfo>
-        <ows:Phone>
-          <ows:Voice>+01-416-xxx-xxxx</ows:Voice>
-          <ows:Facsimile>+01-416-xxx-xxxx</ows:Facsimile>
-        </ows:Phone>
-        <ows:Address>
-          <ows:DeliveryPoint>TBA</ows:DeliveryPoint>
-          <ows:City>Toronto</ows:City>
-          <ows:AdministrativeArea>Ontario</ows:AdministrativeArea>
-          <ows:PostalCode>M9C 3Z9</ows:PostalCode>
-          <ows:Country>Canada</ows:Country>
-          <ows:ElectronicMailAddress>tomkralidis at gmail.com</ows:ElectronicMailAddress>
-        </ows:Address>
-        <ows:OnlineResource xlink:type="simple" xlink:href="http://kralidis.ca/"/>
-        <ows:HoursOfService>0800h - 1600h EST</ows:HoursOfService>
-        <ows:ContactInstructions>During hours of service.  Off on weekends.</ows:ContactInstructions>
-      </ows:ContactInfo>
-      <ows:Role codeSpace="ISOTC211/19115">pointOfContact</ows:Role>
-    </ows:ServiceContact>
-  </ows:ServiceProvider>
-  <ows:OperationsMetadata>
-    <ows:Operation name="GetCapabilities">
-      <ows:DCP>
-        <ows:HTTP>
-          <ows:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/cite/default.cfg"/>
-          <ows:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/cite/default.cfg"/>
-        </ows:HTTP>
-      </ows:DCP>
-      <ows:Parameter name="sections">
-        <ows:Value>ServiceIdentification</ows:Value>
-        <ows:Value>ServiceProvider</ows:Value>
-        <ows:Value>OperationsMetadata</ows:Value>
-        <ows:Value>Filter_Capabilities</ows:Value>
-      </ows:Parameter>
-    </ows:Operation>
-    <ows:Operation name="Transaction">
-      <ows:DCP>
-        <ows:HTTP>
-          <ows:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/cite/default.cfg"/>
-        </ows:HTTP>
-      </ows:DCP>
-    </ows:Operation>
-    <ows:Operation name="GetRepositoryItem">
-      <ows:DCP>
-        <ows:HTTP>
-          <ows:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/cite/default.cfg"/>
-        </ows:HTTP>
-      </ows:DCP>
-    </ows:Operation>
-    <ows:Operation name="DescribeRecord">
-      <ows:DCP>
-        <ows:HTTP>
-          <ows:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/cite/default.cfg"/>
-          <ows:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/cite/default.cfg"/>
-        </ows:HTTP>
-      </ows:DCP>
-      <ows:Parameter name="schemaLanguage">
-        <ows:Value>http://www.w3.org/XML/Schema</ows:Value>
-        <ows:Value>http://www.w3.org/TR/xmlschema-1/</ows:Value>
-        <ows:Value>http://www.w3.org/2001/XMLSchema</ows:Value>
-      </ows:Parameter>
-      <ows:Parameter name="outputFormat">
-        <ows:Value>application/xml</ows:Value>
-        <ows:Value>application/json</ows:Value>
-      </ows:Parameter>
-      <ows:Parameter name="typeName">
-        <ows:Value>csw:Record</ows:Value>
-      </ows:Parameter>
-    </ows:Operation>
-    <ows:Operation name="GetDomain">
-      <ows:DCP>
-        <ows:HTTP>
-          <ows:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/cite/default.cfg"/>
-          <ows:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/cite/default.cfg"/>
-        </ows:HTTP>
-      </ows:DCP>
-      <ows:Parameter name="ParameterName">
-        <ows:Value>GetCapabilities.sections</ows:Value>
-        <ows:Value>DescribeRecord.schemaLanguage</ows:Value>
-        <ows:Value>DescribeRecord.outputFormat</ows:Value>
-        <ows:Value>DescribeRecord.typeName</ows:Value>
-        <ows:Value>GetRecordById.outputFormat</ows:Value>
-        <ows:Value>GetRecordById.outputSchema</ows:Value>
-        <ows:Value>GetRecordById.ElementSetName</ows:Value>
-        <ows:Value>GetRecords.outputFormat</ows:Value>
-        <ows:Value>GetRecords.outputSchema</ows:Value>
-        <ows:Value>GetRecords.CONSTRAINTLANGUAGE</ows:Value>
-        <ows:Value>GetRecords.resultType</ows:Value>
-        <ows:Value>GetRecords.typeNames</ows:Value>
-        <ows:Value>GetRecords.ElementSetName</ows:Value>
-        <ows:Value>Harvest.ResourceType</ows:Value>
-      </ows:Parameter>
-    </ows:Operation>
-    <ows:Operation name="GetRecordById">
-      <ows:DCP>
-        <ows:HTTP>
-          <ows:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/cite/default.cfg"/>
-          <ows:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/cite/default.cfg"/>
-        </ows:HTTP>
-      </ows:DCP>
-      <ows:Parameter name="outputFormat">
-        <ows:Value>application/xml</ows:Value>
-        <ows:Value>application/json</ows:Value>
-      </ows:Parameter>
-      <ows:Parameter name="outputSchema">
-        <ows:Value>http://www.opengis.net/cat/csw/2.0.2</ows:Value>
-        <ows:Value>http://www.w3.org/2005/Atom</ows:Value>
-        <ows:Value>http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/</ows:Value>
-        <ows:Value>http://www.opengis.net/cat/csw/csdgm</ows:Value>
-      </ows:Parameter>
-      <ows:Parameter name="ElementSetName">
-        <ows:Value>brief</ows:Value>
-        <ows:Value>summary</ows:Value>
-        <ows:Value>full</ows:Value>
-      </ows:Parameter>
-    </ows:Operation>
-    <ows:Operation name="GetRecords">
-      <ows:DCP>
-        <ows:HTTP>
-          <ows:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/cite/default.cfg"/>
-          <ows:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/cite/default.cfg"/>
-        </ows:HTTP>
-      </ows:DCP>
-      <ows:Parameter name="outputFormat">
-        <ows:Value>application/xml</ows:Value>
-        <ows:Value>application/json</ows:Value>
-      </ows:Parameter>
-      <ows:Parameter name="outputSchema">
-        <ows:Value>http://www.opengis.net/cat/csw/2.0.2</ows:Value>
-        <ows:Value>http://www.w3.org/2005/Atom</ows:Value>
-        <ows:Value>http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/</ows:Value>
-        <ows:Value>http://www.opengis.net/cat/csw/csdgm</ows:Value>
-      </ows:Parameter>
-      <ows:Parameter name="CONSTRAINTLANGUAGE">
-        <ows:Value>FILTER</ows:Value>
-        <ows:Value>CQL_TEXT</ows:Value>
-      </ows:Parameter>
-      <ows:Parameter name="resultType">
-        <ows:Value>hits</ows:Value>
-        <ows:Value>results</ows:Value>
-        <ows:Value>validate</ows:Value>
-      </ows:Parameter>
-      <ows:Parameter name="typeNames">
-        <ows:Value>csw:Record</ows:Value>
-      </ows:Parameter>
-      <ows:Parameter name="ElementSetName">
-        <ows:Value>brief</ows:Value>
-        <ows:Value>summary</ows:Value>
-        <ows:Value>full</ows:Value>
-      </ows:Parameter>
-      <ows:Constraint name="SupportedDublinCoreQueryables">
-        <ows:Value>dc:contributor</ows:Value>
-        <ows:Value>dc:source</ows:Value>
-        <ows:Value>dc:language</ows:Value>
-        <ows:Value>dc:title</ows:Value>
-        <ows:Value>dc:subject</ows:Value>
-        <ows:Value>dc:creator</ows:Value>
-        <ows:Value>dc:type</ows:Value>
-        <ows:Value>ows:BoundingBox</ows:Value>
-        <ows:Value>dct:modified</ows:Value>
-        <ows:Value>dct:abstract</ows:Value>
-        <ows:Value>dc:relation</ows:Value>
-        <ows:Value>dc:date</ows:Value>
-        <ows:Value>dc:identifier</ows:Value>
-        <ows:Value>dc:publisher</ows:Value>
-        <ows:Value>dc:format</ows:Value>
-        <ows:Value>csw:AnyText</ows:Value>
-        <ows:Value>dc:rights</ows:Value>
-      </ows:Constraint>
-    </ows:Operation>
-    <ows:Operation name="Harvest">
-      <ows:DCP>
-        <ows:HTTP>
-          <ows:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/cite/default.cfg"/>
-        </ows:HTTP>
-      </ows:DCP>
-      <ows:Parameter name="ResourceType">
-        <ows:Value>http://www.opengis.net/cat/csw/2.0.2</ows:Value>
-        <ows:Value>http://www.opengis.net/wms</ows:Value>
-        <ows:Value>http://www.opengis.net/wfs</ows:Value>
-        <ows:Value>http://www.opengis.net/wcs</ows:Value>
-        <ows:Value>http://www.opengis.net/wps/1.0.0</ows:Value>
-        <ows:Value>http://www.opengis.net/sos/1.0</ows:Value>
-        <ows:Value>http://www.opengis.net/sos/2.0</ows:Value>
-        <ows:Value>http://www.isotc211.org/2005/gmi</ows:Value>
-        <ows:Value>urn:geoss:waf</ows:Value>
-        <ows:Value>http://www.w3.org/2005/Atom</ows:Value>
-        <ows:Value>http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/</ows:Value>
-        <ows:Value>http://www.opengis.net/cat/csw/csdgm</ows:Value>
-      </ows:Parameter>
-    </ows:Operation>
-    <ows:Parameter name="version">
-      <ows:Value>2.0.2</ows:Value>
-    </ows:Parameter>
-    <ows:Parameter name="service">
-      <ows:Value>CSW</ows:Value>
-    </ows:Parameter>
-    <ows:Constraint name="XPathQueryables">
-      <ows:Value>allowed</ows:Value>
-    </ows:Constraint>
-    <ows:Constraint name="MaxRecordDefault">
-      <ows:Value>10</ows:Value>
-    </ows:Constraint>
-    <ows:Constraint name="PostEncoding">
-      <ows:Value>XML</ows:Value>
-      <ows:Value>SOAP</ows:Value>
-    </ows:Constraint>
-    <ows:Constraint name="FederatedCatalogues">
-      <ows:Value>http://geo.data.gov/geoportal/csw/discovery</ows:Value>
-    </ows:Constraint>
-  </ows:OperationsMetadata>
-  <ogc:Filter_Capabilities>
-    <ogc:Spatial_Capabilities>
-      <ogc:GeometryOperands>
-        <ogc:GeometryOperand>gml:Point</ogc:GeometryOperand>
-        <ogc:GeometryOperand>gml:LineString</ogc:GeometryOperand>
-        <ogc:GeometryOperand>gml:Polygon</ogc:GeometryOperand>
-        <ogc:GeometryOperand>gml:Envelope</ogc:GeometryOperand>
-      </ogc:GeometryOperands>
-      <ogc:SpatialOperators>
-        <ogc:SpatialOperator name="BBOX"/>
-        <ogc:SpatialOperator name="Beyond"/>
-        <ogc:SpatialOperator name="Contains"/>
-        <ogc:SpatialOperator name="Crosses"/>
-        <ogc:SpatialOperator name="Disjoint"/>
-        <ogc:SpatialOperator name="DWithin"/>
-        <ogc:SpatialOperator name="Equals"/>
-        <ogc:SpatialOperator name="Intersects"/>
-        <ogc:SpatialOperator name="Overlaps"/>
-        <ogc:SpatialOperator name="Touches"/>
-        <ogc:SpatialOperator name="Within"/>
-      </ogc:SpatialOperators>
-    </ogc:Spatial_Capabilities>
-    <ogc:Scalar_Capabilities>
-      <ogc:LogicalOperators/>
-      <ogc:ComparisonOperators>
-        <ogc:ComparisonOperator>Between</ogc:ComparisonOperator>
-        <ogc:ComparisonOperator>EqualTo</ogc:ComparisonOperator>
-        <ogc:ComparisonOperator>LessThanEqualTo</ogc:ComparisonOperator>
-        <ogc:ComparisonOperator>GreaterThan</ogc:ComparisonOperator>
-        <ogc:ComparisonOperator>Like</ogc:ComparisonOperator>
-        <ogc:ComparisonOperator>LessThan</ogc:ComparisonOperator>
-        <ogc:ComparisonOperator>GreaterThanEqualTo</ogc:ComparisonOperator>
-        <ogc:ComparisonOperator>NotEqualTo</ogc:ComparisonOperator>
-        <ogc:ComparisonOperator>NullCheck</ogc:ComparisonOperator>
-      </ogc:ComparisonOperators>
-      <ogc:ArithmeticOperators>
-        <ogc:Functions>
-          <ogc:FunctionNames>
-            <ogc:FunctionName nArgs="1">length</ogc:FunctionName>
-            <ogc:FunctionName nArgs="1">lower</ogc:FunctionName>
-            <ogc:FunctionName nArgs="1">ltrim</ogc:FunctionName>
-            <ogc:FunctionName nArgs="1">rtrim</ogc:FunctionName>
-            <ogc:FunctionName nArgs="1">trim</ogc:FunctionName>
-            <ogc:FunctionName nArgs="1">upper</ogc:FunctionName>
-          </ogc:FunctionNames>
-        </ogc:Functions>
-      </ogc:ArithmeticOperators>
-    </ogc:Scalar_Capabilities>
-    <ogc:Id_Capabilities>
-      <ogc:EID/>
-      <ogc:FID/>
-    </ogc:Id_Capabilities>
-  </ogc:Filter_Capabilities>
-</csw:Capabilities>
+<csw30:Capabilities xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:csw30="http://www.opengis.net/cat/csw/3.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:fes20="http://www.opengis.net/fes/2.0" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:ows11="http://www.opengis.net/ows/1.1" xmlns:ows20="http://www.opengis.net/ows/2.0" xmlns:xlink="http://www.w3.org/199 [...]
+  <ows20:ServiceIdentification>
+    <ows20:Title>pycsw Geospatial Catalogue</ows20:Title>
+    <ows20:Abstract>pycsw is an OGC CSW server implementation written in Python</ows20:Abstract>
+    <ows20:Keywords>
+      <ows20:Keyword>catalogue</ows20:Keyword>
+      <ows20:Keyword>discovery</ows20:Keyword>
+      <ows20:Type codeSpace="ISOTC211/19115">theme</ows20:Type>
+    </ows20:Keywords>
+    <ows20:ServiceType codeSpace="OGC">CSW</ows20:ServiceType>
+    <ows20:ServiceTypeVersion>2.0.2</ows20:ServiceTypeVersion>
+    <ows20:ServiceTypeVersion>3.0.0</ows20:ServiceTypeVersion>
+    <ows20:Fees>None</ows20:Fees>
+    <ows20:AccessConstraints>None</ows20:AccessConstraints>
+  </ows20:ServiceIdentification>
+  <ows20:ServiceProvider>
+    <ows20:ProviderName>pycsw</ows20:ProviderName>
+    <ows20:ProviderSite xlink:type="simple" xlink:href="http://pycsw.org/"/>
+    <ows20:ServiceContact>
+      <ows20:IndividualName>Kralidis, Tom</ows20:IndividualName>
+      <ows20:PositionName>Senior Systems Scientist</ows20:PositionName>
+      <ows20:ContactInfo>
+        <ows20:Phone>
+          <ows20:Voice>+01-416-xxx-xxxx</ows20:Voice>
+          <ows20:Facsimile>+01-416-xxx-xxxx</ows20:Facsimile>
+        </ows20:Phone>
+        <ows20:Address>
+          <ows20:DeliveryPoint>TBA</ows20:DeliveryPoint>
+          <ows20:City>Toronto</ows20:City>
+          <ows20:AdministrativeArea>Ontario</ows20:AdministrativeArea>
+          <ows20:PostalCode>M9C 3Z9</ows20:PostalCode>
+          <ows20:Country>Canada</ows20:Country>
+          <ows20:ElectronicMailAddress>tomkralidis at gmail.com</ows20:ElectronicMailAddress>
+        </ows20:Address>
+        <ows20:OnlineResource xlink:type="simple" xlink:href="http://kralidis.ca/"/>
+        <ows20:HoursOfService>0800h - 1600h EST</ows20:HoursOfService>
+        <ows20:ContactInstructions>During hours of service.  Off on weekends.</ows20:ContactInstructions>
+      </ows20:ContactInfo>
+      <ows20:Role codeSpace="ISOTC211/19115">pointOfContact</ows20:Role>
+    </ows20:ServiceContact>
+  </ows20:ServiceProvider>
+  <ows20:OperationsMetadata>
+    <ows20:Operation name="GetCapabilities">
+      <ows20:DCP>
+        <ows20:HTTP>
+          <ows20:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/cite/default.cfg"/>
+          <ows20:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/cite/default.cfg"/>
+        </ows20:HTTP>
+      </ows20:DCP>
+      <ows20:Parameter name="acceptFormats">
+        <ows20:AllowedValues>
+          <ows20:Value>application/xml</ows20:Value>
+          <ows20:Value>text/xml</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Parameter name="acceptVersions">
+        <ows20:AllowedValues>
+          <ows20:Value>2.0.2</ows20:Value>
+          <ows20:Value>3.0.0</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Parameter name="sections">
+        <ows20:AllowedValues>
+          <ows20:Value>All</ows20:Value>
+          <ows20:Value>Filter_Capabilities</ows20:Value>
+          <ows20:Value>OperationsMetadata</ows20:Value>
+          <ows20:Value>ServiceIdentification</ows20:Value>
+          <ows20:Value>ServiceProvider</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+    </ows20:Operation>
+    <ows20:Operation name="GetDomain">
+      <ows20:DCP>
+        <ows20:HTTP>
+          <ows20:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/cite/default.cfg"/>
+          <ows20:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/cite/default.cfg"/>
+        </ows20:HTTP>
+      </ows20:DCP>
+      <ows20:Parameter name="ParameterName">
+        <ows20:AllowedValues>
+          <ows20:Value>GetCapabilities.acceptFormats</ows20:Value>
+          <ows20:Value>GetCapabilities.acceptVersions</ows20:Value>
+          <ows20:Value>GetCapabilities.sections</ows20:Value>
+          <ows20:Value>GetRecordById.ElementSetName</ows20:Value>
+          <ows20:Value>GetRecordById.outputFormat</ows20:Value>
+          <ows20:Value>GetRecordById.outputSchema</ows20:Value>
+          <ows20:Value>GetRecords.CONSTRAINTLANGUAGE</ows20:Value>
+          <ows20:Value>GetRecords.ElementSetName</ows20:Value>
+          <ows20:Value>GetRecords.outputFormat</ows20:Value>
+          <ows20:Value>GetRecords.outputSchema</ows20:Value>
+          <ows20:Value>GetRecords.typeNames</ows20:Value>
+          <ows20:Value>Harvest.ResourceType</ows20:Value>
+          <ows20:Value>Transaction.TransactionSchemas</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+    </ows20:Operation>
+    <ows20:Operation name="GetRecords">
+      <ows20:DCP>
+        <ows20:HTTP>
+          <ows20:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/cite/default.cfg"/>
+          <ows20:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/cite/default.cfg"/>
+        </ows20:HTTP>
+      </ows20:DCP>
+      <ows20:Parameter name="CONSTRAINTLANGUAGE">
+        <ows20:AllowedValues>
+          <ows20:Value>CQL_TEXT</ows20:Value>
+          <ows20:Value>FILTER</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Parameter name="ElementSetName">
+        <ows20:AllowedValues>
+          <ows20:Value>brief</ows20:Value>
+          <ows20:Value>full</ows20:Value>
+          <ows20:Value>summary</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Parameter name="outputFormat">
+        <ows20:AllowedValues>
+          <ows20:Value>application/atom+xml</ows20:Value>
+          <ows20:Value>application/json</ows20:Value>
+          <ows20:Value>application/xml</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Parameter name="outputSchema">
+        <ows20:AllowedValues>
+          <ows20:Value>http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/</ows20:Value>
+          <ows20:Value>http://www.interlis.ch/INTERLIS2.3</ows20:Value>
+          <ows20:Value>http://www.opengis.net/cat/csw/3.0</ows20:Value>
+          <ows20:Value>http://www.opengis.net/cat/csw/csdgm</ows20:Value>
+          <ows20:Value>http://www.w3.org/2005/Atom</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Parameter name="typeNames">
+        <ows20:AllowedValues>
+          <ows20:Value>csw:Record</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Constraint name="MaxRecordDefault">
+        <ows20:AllowedValues>
+          <ows20:Value>10</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Constraint>
+      <ows20:Constraint name="OpenSearchDescriptionDocument">
+        <ows20:AllowedValues>
+          <ows20:Value>http://localhost/pycsw/csw.py?config=tests/suites/cite/default.cfg?mode=opensearch&service=CSW&version=3.0.0&request=GetCapabilities</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Constraint>
+      <ows20:Constraint name="FederatedCatalogues">
+        <ows20:AllowedValues>
+          <ows20:Value>http://geo.data.gov/geoportal/csw/discovery</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Constraint>
+    </ows20:Operation>
+    <ows20:Operation name="GetRecordById">
+      <ows20:DCP>
+        <ows20:HTTP>
+          <ows20:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/cite/default.cfg"/>
+          <ows20:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/cite/default.cfg"/>
+        </ows20:HTTP>
+      </ows20:DCP>
+      <ows20:Parameter name="ElementSetName">
+        <ows20:AllowedValues>
+          <ows20:Value>brief</ows20:Value>
+          <ows20:Value>full</ows20:Value>
+          <ows20:Value>summary</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Parameter name="outputFormat">
+        <ows20:AllowedValues>
+          <ows20:Value>application/atom+xml</ows20:Value>
+          <ows20:Value>application/json</ows20:Value>
+          <ows20:Value>application/xml</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Parameter name="outputSchema">
+        <ows20:AllowedValues>
+          <ows20:Value>http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/</ows20:Value>
+          <ows20:Value>http://www.interlis.ch/INTERLIS2.3</ows20:Value>
+          <ows20:Value>http://www.opengis.net/cat/csw/3.0</ows20:Value>
+          <ows20:Value>http://www.opengis.net/cat/csw/csdgm</ows20:Value>
+          <ows20:Value>http://www.w3.org/2005/Atom</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+    </ows20:Operation>
+    <ows20:Operation name="GetRepositoryItem">
+      <ows20:DCP>
+        <ows20:HTTP>
+          <ows20:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/cite/default.cfg"/>
+        </ows20:HTTP>
+      </ows20:DCP>
+    </ows20:Operation>
+    <ows20:Operation name="Transaction">
+      <ows20:DCP>
+        <ows20:HTTP>
+          <ows20:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/cite/default.cfg"/>
+        </ows20:HTTP>
+      </ows20:DCP>
+      <ows20:Parameter name="TransactionSchemas">
+        <ows20:AllowedValues>
+          <ows20:Value>http://www.isotc211.org/2005/gmi</ows20:Value>
+          <ows20:Value>http://www.opengis.net/cat/csw/2.0.2</ows20:Value>
+          <ows20:Value>http://www.opengis.net/cat/csw/3.0</ows20:Value>
+          <ows20:Value>http://www.opengis.net/sos/1.0</ows20:Value>
+          <ows20:Value>http://www.opengis.net/sos/2.0</ows20:Value>
+          <ows20:Value>http://www.opengis.net/wcs</ows20:Value>
+          <ows20:Value>http://www.opengis.net/wfs</ows20:Value>
+          <ows20:Value>http://www.opengis.net/wms</ows20:Value>
+          <ows20:Value>http://www.opengis.net/wmts/1.0</ows20:Value>
+          <ows20:Value>http://www.opengis.net/wps/1.0.0</ows20:Value>
+          <ows20:Value>urn:geoss:waf</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+    </ows20:Operation>
+    <ows20:Operation name="Harvest">
+      <ows20:DCP>
+        <ows20:HTTP>
+          <ows20:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/cite/default.cfg"/>
+        </ows20:HTTP>
+      </ows20:DCP>
+      <ows20:Parameter name="ResourceType">
+        <ows20:AllowedValues>
+          <ows20:Value>http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/</ows20:Value>
+          <ows20:Value>http://www.interlis.ch/INTERLIS2.3</ows20:Value>
+          <ows20:Value>http://www.isotc211.org/2005/gmi</ows20:Value>
+          <ows20:Value>http://www.opengis.net/cat/csw/2.0.2</ows20:Value>
+          <ows20:Value>http://www.opengis.net/cat/csw/3.0</ows20:Value>
+          <ows20:Value>http://www.opengis.net/cat/csw/csdgm</ows20:Value>
+          <ows20:Value>http://www.opengis.net/sos/1.0</ows20:Value>
+          <ows20:Value>http://www.opengis.net/sos/2.0</ows20:Value>
+          <ows20:Value>http://www.opengis.net/wcs</ows20:Value>
+          <ows20:Value>http://www.opengis.net/wfs</ows20:Value>
+          <ows20:Value>http://www.opengis.net/wms</ows20:Value>
+          <ows20:Value>http://www.opengis.net/wmts/1.0</ows20:Value>
+          <ows20:Value>http://www.opengis.net/wps/1.0.0</ows20:Value>
+          <ows20:Value>http://www.w3.org/2005/Atom</ows20:Value>
+          <ows20:Value>urn:geoss:waf</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+    </ows20:Operation>
+    <ows20:Parameter name="service">
+      <ows20:AllowedValues>
+        <ows20:Value>CSW</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Parameter>
+    <ows20:Parameter name="version">
+      <ows20:AllowedValues>
+        <ows20:Value>2.0.2</ows20:Value>
+        <ows20:Value>3.0.0</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Parameter>
+    <ows20:Constraint name="CoreQueryables">
+      <ows20:AllowedValues>
+        <ows20:Value>csw:AnyText</ows20:Value>
+        <ows20:Value>dc:contributor</ows20:Value>
+        <ows20:Value>dc:creator</ows20:Value>
+        <ows20:Value>dc:date</ows20:Value>
+        <ows20:Value>dc:format</ows20:Value>
+        <ows20:Value>dc:identifier</ows20:Value>
+        <ows20:Value>dc:language</ows20:Value>
+        <ows20:Value>dc:publisher</ows20:Value>
+        <ows20:Value>dc:relation</ows20:Value>
+        <ows20:Value>dc:rights</ows20:Value>
+        <ows20:Value>dc:source</ows20:Value>
+        <ows20:Value>dc:subject</ows20:Value>
+        <ows20:Value>dc:title</ows20:Value>
+        <ows20:Value>dc:type</ows20:Value>
+        <ows20:Value>dct:abstract</ows20:Value>
+        <ows20:Value>dct:modified</ows20:Value>
+        <ows20:Value>ows:BoundingBox</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="FederatedCatalogues">
+      <ows20:AllowedValues>
+        <ows20:Value>http://geo.data.gov/geoportal/csw/discovery</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="MaxRecordDefault">
+      <ows20:AllowedValues>
+        <ows20:Value>10</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="PostEncoding">
+      <ows20:AllowedValues>
+        <ows20:Value>SOAP</ows20:Value>
+        <ows20:Value>XML</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="XPathQueryables">
+      <ows20:AllowedValues>
+        <ows20:Value>allowed</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/CoreQueryables">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/CoreSortables">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/DefaultSortingAlgorithm">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Filter-CQL">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Filter-FES-KVP-Advanced">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Filter-FES-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetCapabilities-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetDomain-KVP">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetDomain-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetRecordById-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetRecords-Async-KVP">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetRecords-Async-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetRecords-Basic-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetRecords-Distributed-KVP">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetRecords-Distributed-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Harvest-Async-KVP">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Harvest-Async-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Harvest-Basic-KVP">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Harvest-Basic-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Harvest-Periodic-KVP">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Harvest-Periodic-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/OpenSearch">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/SupportedGMLVersions">
+      <ows20:AllowedValues>
+        <ows20:Value>http://www.opengis.net/gml</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Transaction">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+  </ows20:OperationsMetadata>
+  <ows20:Languages>
+    <ows20:Language>en</ows20:Language>
+  </ows20:Languages>
+  <fes20:Filter_Capabilities>
+    <fes20:Conformance>
+      <fes20:Constraint name="ImplementsQuery">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsAdHocQuery">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsFunctions">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsResourceld">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsMinStandardFilter">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsStandardFilter">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsMinSpatialFilter">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsSpatialFilter">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsMinTemporalFilter">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsTemporalFilter">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsVersionNav">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsSorting">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsExtendedOperators">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsMinimumXPath">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsSchemaElementFunc">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+    </fes20:Conformance>
+    <fes20:Id_Capabilities>
+      <fes20:ResourceIdentifier name="csw30:id"/>
+    </fes20:Id_Capabilities>
+    <fes20:Scalar_Capabilities>
+      <fes20:LogicalOperators/>
+      <fes20:ComparisonOperators>
+        <fes20:ComparisonOperator name="PropertyIsBetween"/>
+        <fes20:ComparisonOperator name="PropertyIsEqualTo"/>
+        <fes20:ComparisonOperator name="PropertyIsGreaterThan"/>
+        <fes20:ComparisonOperator name="PropertyIsGreaterThanOrEqualTo"/>
+        <fes20:ComparisonOperator name="PropertyIsLessThan"/>
+        <fes20:ComparisonOperator name="PropertyIsLessThanOrEqualTo"/>
+        <fes20:ComparisonOperator name="PropertyIsLike"/>
+        <fes20:ComparisonOperator name="PropertyIsNotEqualTo"/>
+        <fes20:ComparisonOperator name="PropertyIsNull"/>
+      </fes20:ComparisonOperators>
+    </fes20:Scalar_Capabilities>
+    <fes20:Spatial_Capabilities>
+      <fes20:GeometryOperands>
+        <fes20:GeometryOperand name="gml:Point"/>
+        <fes20:GeometryOperand name="gml:LineString"/>
+        <fes20:GeometryOperand name="gml:Polygon"/>
+        <fes20:GeometryOperand name="gml:Envelope"/>
+      </fes20:GeometryOperands>
+      <fes20:SpatialOperators>
+        <fes20:SpatialOperator name="BBOX"/>
+        <fes20:SpatialOperator name="Beyond"/>
+        <fes20:SpatialOperator name="Contains"/>
+        <fes20:SpatialOperator name="Crosses"/>
+        <fes20:SpatialOperator name="Disjoint"/>
+        <fes20:SpatialOperator name="DWithin"/>
+        <fes20:SpatialOperator name="Equals"/>
+        <fes20:SpatialOperator name="Intersects"/>
+        <fes20:SpatialOperator name="Overlaps"/>
+        <fes20:SpatialOperator name="Touches"/>
+        <fes20:SpatialOperator name="Within"/>
+      </fes20:SpatialOperators>
+    </fes20:Spatial_Capabilities>
+    <fes20:Functions>
+      <fes20:Function name="length">
+        <fes20:Returns>xs:string</fes20:Returns>
+      </fes20:Function>
+      <fes20:Function name="lower">
+        <fes20:Returns>xs:string</fes20:Returns>
+      </fes20:Function>
+      <fes20:Function name="ltrim">
+        <fes20:Returns>xs:string</fes20:Returns>
+      </fes20:Function>
+      <fes20:Function name="rtrim">
+        <fes20:Returns>xs:string</fes20:Returns>
+      </fes20:Function>
+      <fes20:Function name="trim">
+        <fes20:Returns>xs:string</fes20:Returns>
+      </fes20:Function>
+      <fes20:Function name="upper">
+        <fes20:Returns>xs:string</fes20:Returns>
+      </fes20:Function>
+    </fes20:Functions>
+  </fes20:Filter_Capabilities>
+</csw30:Capabilities>
diff --git a/tests/expected/suites_cite_get_8e2232ed-05d9-44ae-8b04-0911cbe6a507.xml b/tests/expected/suites_cite_get_8e2232ed-05d9-44ae-8b04-0911cbe6a507.xml
index 1154d5f..6dd138f 100644
--- a/tests/expected/suites_cite_get_8e2232ed-05d9-44ae-8b04-0911cbe6a507.xml
+++ b/tests/expected/suites_cite_get_8e2232ed-05d9-44ae-8b04-0911cbe6a507.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<ows:ExceptionReport xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ows="http://www.opengis.net/ows" xmlns:fgdc="http://www.opengis.net/cat/csw/csdgm"  [...]
-  <ows:Exception exceptionCode="VersionNegotiationFailed" locator="acceptversions">
-    <ows:ExceptionText>Invalid parameter value in acceptversions:                            2006.10.29. Value MUST be 2.0.2</ows:ExceptionText>
-  </ows:Exception>
-</ows:ExceptionReport>
+<ows20:ExceptionReport xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:ows20="http://www.opengis.net/ows/2.0" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="3.0.0" xml:lang="en-US" xsi:schemaLocation="http://www.opengis. [...]
+  <ows20:Exception exceptionCode="VersionNegotiationFailed" locator="acceptversions">
+    <ows20:ExceptionText>Invalid parameter value in acceptversions: 2006.10.29. Value MUST be 2.0.2 or 3.0.0</ows20:ExceptionText>
+  </ows20:Exception>
+</ows20:ExceptionReport>
diff --git a/tests/expected/suites_cite_get_9697f0aa-3b6a-4125-83a5-61e8826127c4.xml b/tests/expected/suites_cite_get_9697f0aa-3b6a-4125-83a5-61e8826127c4.xml
index 5c5c068..d127684 100644
--- a/tests/expected/suites_cite_get_9697f0aa-3b6a-4125-83a5-61e8826127c4.xml
+++ b/tests/expected/suites_cite_get_9697f0aa-3b6a-4125-83a5-61e8826127c4.xml
@@ -1,287 +1,541 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<csw:Capabilities xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ows="http://www.opengis.net/ows" xmlns:fgdc="http://www.opengis.net/cat/csw/csdgm" xml [...]
-  <ows:ServiceIdentification>
-    <ows:Title>pycsw Geospatial Catalogue</ows:Title>
-    <ows:Abstract>pycsw is an OGC CSW server implementation written in Python</ows:Abstract>
-    <ows:Keywords>
-      <ows:Keyword>catalogue</ows:Keyword>
-      <ows:Keyword>discovery</ows:Keyword>
-      <ows:Type codeSpace="ISOTC211/19115">theme</ows:Type>
-    </ows:Keywords>
-    <ows:ServiceType codeSpace="OGC">CSW</ows:ServiceType>
-    <ows:ServiceTypeVersion>2.0.2</ows:ServiceTypeVersion>
-    <ows:Fees>None</ows:Fees>
-    <ows:AccessConstraints>None</ows:AccessConstraints>
-  </ows:ServiceIdentification>
-  <ows:ServiceProvider>
-    <ows:ProviderName>pycsw</ows:ProviderName>
-    <ows:ProviderSite xlink:type="simple" xlink:href="http://pycsw.org/"/>
-    <ows:ServiceContact>
-      <ows:IndividualName>Kralidis, Tom</ows:IndividualName>
-      <ows:PositionName>Senior Systems Scientist</ows:PositionName>
-      <ows:ContactInfo>
-        <ows:Phone>
-          <ows:Voice>+01-416-xxx-xxxx</ows:Voice>
-          <ows:Facsimile>+01-416-xxx-xxxx</ows:Facsimile>
-        </ows:Phone>
-        <ows:Address>
-          <ows:DeliveryPoint>TBA</ows:DeliveryPoint>
-          <ows:City>Toronto</ows:City>
-          <ows:AdministrativeArea>Ontario</ows:AdministrativeArea>
-          <ows:PostalCode>M9C 3Z9</ows:PostalCode>
-          <ows:Country>Canada</ows:Country>
-          <ows:ElectronicMailAddress>tomkralidis at gmail.com</ows:ElectronicMailAddress>
-        </ows:Address>
-        <ows:OnlineResource xlink:type="simple" xlink:href="http://kralidis.ca/"/>
-        <ows:HoursOfService>0800h - 1600h EST</ows:HoursOfService>
-        <ows:ContactInstructions>During hours of service.  Off on weekends.</ows:ContactInstructions>
-      </ows:ContactInfo>
-      <ows:Role codeSpace="ISOTC211/19115">pointOfContact</ows:Role>
-    </ows:ServiceContact>
-  </ows:ServiceProvider>
-  <ows:OperationsMetadata>
-    <ows:Operation name="GetCapabilities">
-      <ows:DCP>
-        <ows:HTTP>
-          <ows:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/cite/default.cfg"/>
-          <ows:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/cite/default.cfg"/>
-        </ows:HTTP>
-      </ows:DCP>
-      <ows:Parameter name="sections">
-        <ows:Value>ServiceIdentification</ows:Value>
-        <ows:Value>ServiceProvider</ows:Value>
-        <ows:Value>OperationsMetadata</ows:Value>
-        <ows:Value>Filter_Capabilities</ows:Value>
-      </ows:Parameter>
-    </ows:Operation>
-    <ows:Operation name="Transaction">
-      <ows:DCP>
-        <ows:HTTP>
-          <ows:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/cite/default.cfg"/>
-        </ows:HTTP>
-      </ows:DCP>
-    </ows:Operation>
-    <ows:Operation name="GetRepositoryItem">
-      <ows:DCP>
-        <ows:HTTP>
-          <ows:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/cite/default.cfg"/>
-        </ows:HTTP>
-      </ows:DCP>
-    </ows:Operation>
-    <ows:Operation name="DescribeRecord">
-      <ows:DCP>
-        <ows:HTTP>
-          <ows:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/cite/default.cfg"/>
-          <ows:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/cite/default.cfg"/>
-        </ows:HTTP>
-      </ows:DCP>
-      <ows:Parameter name="schemaLanguage">
-        <ows:Value>http://www.w3.org/XML/Schema</ows:Value>
-        <ows:Value>http://www.w3.org/TR/xmlschema-1/</ows:Value>
-        <ows:Value>http://www.w3.org/2001/XMLSchema</ows:Value>
-      </ows:Parameter>
-      <ows:Parameter name="outputFormat">
-        <ows:Value>application/xml</ows:Value>
-        <ows:Value>application/json</ows:Value>
-      </ows:Parameter>
-      <ows:Parameter name="typeName">
-        <ows:Value>csw:Record</ows:Value>
-      </ows:Parameter>
-    </ows:Operation>
-    <ows:Operation name="GetDomain">
-      <ows:DCP>
-        <ows:HTTP>
-          <ows:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/cite/default.cfg"/>
-          <ows:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/cite/default.cfg"/>
-        </ows:HTTP>
-      </ows:DCP>
-      <ows:Parameter name="ParameterName">
-        <ows:Value>GetCapabilities.sections</ows:Value>
-        <ows:Value>DescribeRecord.schemaLanguage</ows:Value>
-        <ows:Value>DescribeRecord.outputFormat</ows:Value>
-        <ows:Value>DescribeRecord.typeName</ows:Value>
-        <ows:Value>GetRecordById.outputFormat</ows:Value>
-        <ows:Value>GetRecordById.outputSchema</ows:Value>
-        <ows:Value>GetRecordById.ElementSetName</ows:Value>
-        <ows:Value>GetRecords.outputFormat</ows:Value>
-        <ows:Value>GetRecords.outputSchema</ows:Value>
-        <ows:Value>GetRecords.CONSTRAINTLANGUAGE</ows:Value>
-        <ows:Value>GetRecords.resultType</ows:Value>
-        <ows:Value>GetRecords.typeNames</ows:Value>
-        <ows:Value>GetRecords.ElementSetName</ows:Value>
-        <ows:Value>Harvest.ResourceType</ows:Value>
-      </ows:Parameter>
-    </ows:Operation>
-    <ows:Operation name="GetRecordById">
-      <ows:DCP>
-        <ows:HTTP>
-          <ows:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/cite/default.cfg"/>
-          <ows:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/cite/default.cfg"/>
-        </ows:HTTP>
-      </ows:DCP>
-      <ows:Parameter name="outputFormat">
-        <ows:Value>application/xml</ows:Value>
-        <ows:Value>application/json</ows:Value>
-      </ows:Parameter>
-      <ows:Parameter name="outputSchema">
-        <ows:Value>http://www.opengis.net/cat/csw/2.0.2</ows:Value>
-        <ows:Value>http://www.w3.org/2005/Atom</ows:Value>
-        <ows:Value>http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/</ows:Value>
-        <ows:Value>http://www.opengis.net/cat/csw/csdgm</ows:Value>
-      </ows:Parameter>
-      <ows:Parameter name="ElementSetName">
-        <ows:Value>brief</ows:Value>
-        <ows:Value>summary</ows:Value>
-        <ows:Value>full</ows:Value>
-      </ows:Parameter>
-    </ows:Operation>
-    <ows:Operation name="GetRecords">
-      <ows:DCP>
-        <ows:HTTP>
-          <ows:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/cite/default.cfg"/>
-          <ows:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/cite/default.cfg"/>
-        </ows:HTTP>
-      </ows:DCP>
-      <ows:Parameter name="outputFormat">
-        <ows:Value>application/xml</ows:Value>
-        <ows:Value>application/json</ows:Value>
-      </ows:Parameter>
-      <ows:Parameter name="outputSchema">
-        <ows:Value>http://www.opengis.net/cat/csw/2.0.2</ows:Value>
-        <ows:Value>http://www.w3.org/2005/Atom</ows:Value>
-        <ows:Value>http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/</ows:Value>
-        <ows:Value>http://www.opengis.net/cat/csw/csdgm</ows:Value>
-      </ows:Parameter>
-      <ows:Parameter name="CONSTRAINTLANGUAGE">
-        <ows:Value>FILTER</ows:Value>
-        <ows:Value>CQL_TEXT</ows:Value>
-      </ows:Parameter>
-      <ows:Parameter name="resultType">
-        <ows:Value>hits</ows:Value>
-        <ows:Value>results</ows:Value>
-        <ows:Value>validate</ows:Value>
-      </ows:Parameter>
-      <ows:Parameter name="typeNames">
-        <ows:Value>csw:Record</ows:Value>
-      </ows:Parameter>
-      <ows:Parameter name="ElementSetName">
-        <ows:Value>brief</ows:Value>
-        <ows:Value>summary</ows:Value>
-        <ows:Value>full</ows:Value>
-      </ows:Parameter>
-      <ows:Constraint name="SupportedDublinCoreQueryables">
-        <ows:Value>dc:contributor</ows:Value>
-        <ows:Value>dc:source</ows:Value>
-        <ows:Value>dc:language</ows:Value>
-        <ows:Value>dc:title</ows:Value>
-        <ows:Value>dc:subject</ows:Value>
-        <ows:Value>dc:creator</ows:Value>
-        <ows:Value>dc:type</ows:Value>
-        <ows:Value>ows:BoundingBox</ows:Value>
-        <ows:Value>dct:modified</ows:Value>
-        <ows:Value>dct:abstract</ows:Value>
-        <ows:Value>dc:relation</ows:Value>
-        <ows:Value>dc:date</ows:Value>
-        <ows:Value>dc:identifier</ows:Value>
-        <ows:Value>dc:publisher</ows:Value>
-        <ows:Value>dc:format</ows:Value>
-        <ows:Value>csw:AnyText</ows:Value>
-        <ows:Value>dc:rights</ows:Value>
-      </ows:Constraint>
-    </ows:Operation>
-    <ows:Operation name="Harvest">
-      <ows:DCP>
-        <ows:HTTP>
-          <ows:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/cite/default.cfg"/>
-        </ows:HTTP>
-      </ows:DCP>
-      <ows:Parameter name="ResourceType">
-        <ows:Value>http://www.opengis.net/cat/csw/2.0.2</ows:Value>
-        <ows:Value>http://www.opengis.net/wms</ows:Value>
-        <ows:Value>http://www.opengis.net/wfs</ows:Value>
-        <ows:Value>http://www.opengis.net/wcs</ows:Value>
-        <ows:Value>http://www.opengis.net/wps/1.0.0</ows:Value>
-        <ows:Value>http://www.opengis.net/sos/1.0</ows:Value>
-        <ows:Value>http://www.opengis.net/sos/2.0</ows:Value>
-        <ows:Value>http://www.isotc211.org/2005/gmi</ows:Value>
-        <ows:Value>urn:geoss:waf</ows:Value>
-        <ows:Value>http://www.w3.org/2005/Atom</ows:Value>
-        <ows:Value>http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/</ows:Value>
-        <ows:Value>http://www.opengis.net/cat/csw/csdgm</ows:Value>
-      </ows:Parameter>
-    </ows:Operation>
-    <ows:Parameter name="version">
-      <ows:Value>2.0.2</ows:Value>
-    </ows:Parameter>
-    <ows:Parameter name="service">
-      <ows:Value>CSW</ows:Value>
-    </ows:Parameter>
-    <ows:Constraint name="XPathQueryables">
-      <ows:Value>allowed</ows:Value>
-    </ows:Constraint>
-    <ows:Constraint name="MaxRecordDefault">
-      <ows:Value>10</ows:Value>
-    </ows:Constraint>
-    <ows:Constraint name="PostEncoding">
-      <ows:Value>XML</ows:Value>
-      <ows:Value>SOAP</ows:Value>
-    </ows:Constraint>
-    <ows:Constraint name="FederatedCatalogues">
-      <ows:Value>http://geo.data.gov/geoportal/csw/discovery</ows:Value>
-    </ows:Constraint>
-  </ows:OperationsMetadata>
-  <ogc:Filter_Capabilities>
-    <ogc:Spatial_Capabilities>
-      <ogc:GeometryOperands>
-        <ogc:GeometryOperand>gml:Point</ogc:GeometryOperand>
-        <ogc:GeometryOperand>gml:LineString</ogc:GeometryOperand>
-        <ogc:GeometryOperand>gml:Polygon</ogc:GeometryOperand>
-        <ogc:GeometryOperand>gml:Envelope</ogc:GeometryOperand>
-      </ogc:GeometryOperands>
-      <ogc:SpatialOperators>
-        <ogc:SpatialOperator name="BBOX"/>
-        <ogc:SpatialOperator name="Beyond"/>
-        <ogc:SpatialOperator name="Contains"/>
-        <ogc:SpatialOperator name="Crosses"/>
-        <ogc:SpatialOperator name="Disjoint"/>
-        <ogc:SpatialOperator name="DWithin"/>
-        <ogc:SpatialOperator name="Equals"/>
-        <ogc:SpatialOperator name="Intersects"/>
-        <ogc:SpatialOperator name="Overlaps"/>
-        <ogc:SpatialOperator name="Touches"/>
-        <ogc:SpatialOperator name="Within"/>
-      </ogc:SpatialOperators>
-    </ogc:Spatial_Capabilities>
-    <ogc:Scalar_Capabilities>
-      <ogc:LogicalOperators/>
-      <ogc:ComparisonOperators>
-        <ogc:ComparisonOperator>Between</ogc:ComparisonOperator>
-        <ogc:ComparisonOperator>EqualTo</ogc:ComparisonOperator>
-        <ogc:ComparisonOperator>LessThanEqualTo</ogc:ComparisonOperator>
-        <ogc:ComparisonOperator>GreaterThan</ogc:ComparisonOperator>
-        <ogc:ComparisonOperator>Like</ogc:ComparisonOperator>
-        <ogc:ComparisonOperator>LessThan</ogc:ComparisonOperator>
-        <ogc:ComparisonOperator>GreaterThanEqualTo</ogc:ComparisonOperator>
-        <ogc:ComparisonOperator>NotEqualTo</ogc:ComparisonOperator>
-        <ogc:ComparisonOperator>NullCheck</ogc:ComparisonOperator>
-      </ogc:ComparisonOperators>
-      <ogc:ArithmeticOperators>
-        <ogc:Functions>
-          <ogc:FunctionNames>
-            <ogc:FunctionName nArgs="1">length</ogc:FunctionName>
-            <ogc:FunctionName nArgs="1">lower</ogc:FunctionName>
-            <ogc:FunctionName nArgs="1">ltrim</ogc:FunctionName>
-            <ogc:FunctionName nArgs="1">rtrim</ogc:FunctionName>
-            <ogc:FunctionName nArgs="1">trim</ogc:FunctionName>
-            <ogc:FunctionName nArgs="1">upper</ogc:FunctionName>
-          </ogc:FunctionNames>
-        </ogc:Functions>
-      </ogc:ArithmeticOperators>
-    </ogc:Scalar_Capabilities>
-    <ogc:Id_Capabilities>
-      <ogc:EID/>
-      <ogc:FID/>
-    </ogc:Id_Capabilities>
-  </ogc:Filter_Capabilities>
-</csw:Capabilities>
+<csw30:Capabilities xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:csw30="http://www.opengis.net/cat/csw/3.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:fes20="http://www.opengis.net/fes/2.0" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:ows11="http://www.opengis.net/ows/1.1" xmlns:ows20="http://www.opengis.net/ows/2.0" xmlns:xlink="http://www.w3.org/199 [...]
+  <ows20:ServiceIdentification>
+    <ows20:Title>pycsw Geospatial Catalogue</ows20:Title>
+    <ows20:Abstract>pycsw is an OGC CSW server implementation written in Python</ows20:Abstract>
+    <ows20:Keywords>
+      <ows20:Keyword>catalogue</ows20:Keyword>
+      <ows20:Keyword>discovery</ows20:Keyword>
+      <ows20:Type codeSpace="ISOTC211/19115">theme</ows20:Type>
+    </ows20:Keywords>
+    <ows20:ServiceType codeSpace="OGC">CSW</ows20:ServiceType>
+    <ows20:ServiceTypeVersion>2.0.2</ows20:ServiceTypeVersion>
+    <ows20:ServiceTypeVersion>3.0.0</ows20:ServiceTypeVersion>
+    <ows20:Fees>None</ows20:Fees>
+    <ows20:AccessConstraints>None</ows20:AccessConstraints>
+  </ows20:ServiceIdentification>
+  <ows20:ServiceProvider>
+    <ows20:ProviderName>pycsw</ows20:ProviderName>
+    <ows20:ProviderSite xlink:type="simple" xlink:href="http://pycsw.org/"/>
+    <ows20:ServiceContact>
+      <ows20:IndividualName>Kralidis, Tom</ows20:IndividualName>
+      <ows20:PositionName>Senior Systems Scientist</ows20:PositionName>
+      <ows20:ContactInfo>
+        <ows20:Phone>
+          <ows20:Voice>+01-416-xxx-xxxx</ows20:Voice>
+          <ows20:Facsimile>+01-416-xxx-xxxx</ows20:Facsimile>
+        </ows20:Phone>
+        <ows20:Address>
+          <ows20:DeliveryPoint>TBA</ows20:DeliveryPoint>
+          <ows20:City>Toronto</ows20:City>
+          <ows20:AdministrativeArea>Ontario</ows20:AdministrativeArea>
+          <ows20:PostalCode>M9C 3Z9</ows20:PostalCode>
+          <ows20:Country>Canada</ows20:Country>
+          <ows20:ElectronicMailAddress>tomkralidis at gmail.com</ows20:ElectronicMailAddress>
+        </ows20:Address>
+        <ows20:OnlineResource xlink:type="simple" xlink:href="http://kralidis.ca/"/>
+        <ows20:HoursOfService>0800h - 1600h EST</ows20:HoursOfService>
+        <ows20:ContactInstructions>During hours of service.  Off on weekends.</ows20:ContactInstructions>
+      </ows20:ContactInfo>
+      <ows20:Role codeSpace="ISOTC211/19115">pointOfContact</ows20:Role>
+    </ows20:ServiceContact>
+  </ows20:ServiceProvider>
+  <ows20:OperationsMetadata>
+    <ows20:Operation name="GetCapabilities">
+      <ows20:DCP>
+        <ows20:HTTP>
+          <ows20:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/cite/default.cfg"/>
+          <ows20:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/cite/default.cfg"/>
+        </ows20:HTTP>
+      </ows20:DCP>
+      <ows20:Parameter name="acceptFormats">
+        <ows20:AllowedValues>
+          <ows20:Value>application/xml</ows20:Value>
+          <ows20:Value>text/xml</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Parameter name="acceptVersions">
+        <ows20:AllowedValues>
+          <ows20:Value>2.0.2</ows20:Value>
+          <ows20:Value>3.0.0</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Parameter name="sections">
+        <ows20:AllowedValues>
+          <ows20:Value>All</ows20:Value>
+          <ows20:Value>Filter_Capabilities</ows20:Value>
+          <ows20:Value>OperationsMetadata</ows20:Value>
+          <ows20:Value>ServiceIdentification</ows20:Value>
+          <ows20:Value>ServiceProvider</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+    </ows20:Operation>
+    <ows20:Operation name="GetDomain">
+      <ows20:DCP>
+        <ows20:HTTP>
+          <ows20:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/cite/default.cfg"/>
+          <ows20:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/cite/default.cfg"/>
+        </ows20:HTTP>
+      </ows20:DCP>
+      <ows20:Parameter name="ParameterName">
+        <ows20:AllowedValues>
+          <ows20:Value>GetCapabilities.acceptFormats</ows20:Value>
+          <ows20:Value>GetCapabilities.acceptVersions</ows20:Value>
+          <ows20:Value>GetCapabilities.sections</ows20:Value>
+          <ows20:Value>GetRecordById.ElementSetName</ows20:Value>
+          <ows20:Value>GetRecordById.outputFormat</ows20:Value>
+          <ows20:Value>GetRecordById.outputSchema</ows20:Value>
+          <ows20:Value>GetRecords.CONSTRAINTLANGUAGE</ows20:Value>
+          <ows20:Value>GetRecords.ElementSetName</ows20:Value>
+          <ows20:Value>GetRecords.outputFormat</ows20:Value>
+          <ows20:Value>GetRecords.outputSchema</ows20:Value>
+          <ows20:Value>GetRecords.typeNames</ows20:Value>
+          <ows20:Value>Harvest.ResourceType</ows20:Value>
+          <ows20:Value>Transaction.TransactionSchemas</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+    </ows20:Operation>
+    <ows20:Operation name="GetRecords">
+      <ows20:DCP>
+        <ows20:HTTP>
+          <ows20:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/cite/default.cfg"/>
+          <ows20:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/cite/default.cfg"/>
+        </ows20:HTTP>
+      </ows20:DCP>
+      <ows20:Parameter name="CONSTRAINTLANGUAGE">
+        <ows20:AllowedValues>
+          <ows20:Value>CQL_TEXT</ows20:Value>
+          <ows20:Value>FILTER</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Parameter name="ElementSetName">
+        <ows20:AllowedValues>
+          <ows20:Value>brief</ows20:Value>
+          <ows20:Value>full</ows20:Value>
+          <ows20:Value>summary</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Parameter name="outputFormat">
+        <ows20:AllowedValues>
+          <ows20:Value>application/atom+xml</ows20:Value>
+          <ows20:Value>application/json</ows20:Value>
+          <ows20:Value>application/xml</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Parameter name="outputSchema">
+        <ows20:AllowedValues>
+          <ows20:Value>http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/</ows20:Value>
+          <ows20:Value>http://www.interlis.ch/INTERLIS2.3</ows20:Value>
+          <ows20:Value>http://www.opengis.net/cat/csw/3.0</ows20:Value>
+          <ows20:Value>http://www.opengis.net/cat/csw/csdgm</ows20:Value>
+          <ows20:Value>http://www.w3.org/2005/Atom</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Parameter name="typeNames">
+        <ows20:AllowedValues>
+          <ows20:Value>csw:Record</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Constraint name="MaxRecordDefault">
+        <ows20:AllowedValues>
+          <ows20:Value>10</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Constraint>
+      <ows20:Constraint name="OpenSearchDescriptionDocument">
+        <ows20:AllowedValues>
+          <ows20:Value>http://localhost/pycsw/csw.py?config=tests/suites/cite/default.cfg?mode=opensearch&service=CSW&version=3.0.0&request=GetCapabilities</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Constraint>
+      <ows20:Constraint name="FederatedCatalogues">
+        <ows20:AllowedValues>
+          <ows20:Value>http://geo.data.gov/geoportal/csw/discovery</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Constraint>
+    </ows20:Operation>
+    <ows20:Operation name="GetRecordById">
+      <ows20:DCP>
+        <ows20:HTTP>
+          <ows20:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/cite/default.cfg"/>
+          <ows20:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/cite/default.cfg"/>
+        </ows20:HTTP>
+      </ows20:DCP>
+      <ows20:Parameter name="ElementSetName">
+        <ows20:AllowedValues>
+          <ows20:Value>brief</ows20:Value>
+          <ows20:Value>full</ows20:Value>
+          <ows20:Value>summary</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Parameter name="outputFormat">
+        <ows20:AllowedValues>
+          <ows20:Value>application/atom+xml</ows20:Value>
+          <ows20:Value>application/json</ows20:Value>
+          <ows20:Value>application/xml</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Parameter name="outputSchema">
+        <ows20:AllowedValues>
+          <ows20:Value>http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/</ows20:Value>
+          <ows20:Value>http://www.interlis.ch/INTERLIS2.3</ows20:Value>
+          <ows20:Value>http://www.opengis.net/cat/csw/3.0</ows20:Value>
+          <ows20:Value>http://www.opengis.net/cat/csw/csdgm</ows20:Value>
+          <ows20:Value>http://www.w3.org/2005/Atom</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+    </ows20:Operation>
+    <ows20:Operation name="GetRepositoryItem">
+      <ows20:DCP>
+        <ows20:HTTP>
+          <ows20:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/cite/default.cfg"/>
+        </ows20:HTTP>
+      </ows20:DCP>
+    </ows20:Operation>
+    <ows20:Operation name="Transaction">
+      <ows20:DCP>
+        <ows20:HTTP>
+          <ows20:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/cite/default.cfg"/>
+        </ows20:HTTP>
+      </ows20:DCP>
+      <ows20:Parameter name="TransactionSchemas">
+        <ows20:AllowedValues>
+          <ows20:Value>http://www.isotc211.org/2005/gmi</ows20:Value>
+          <ows20:Value>http://www.opengis.net/cat/csw/2.0.2</ows20:Value>
+          <ows20:Value>http://www.opengis.net/cat/csw/3.0</ows20:Value>
+          <ows20:Value>http://www.opengis.net/sos/1.0</ows20:Value>
+          <ows20:Value>http://www.opengis.net/sos/2.0</ows20:Value>
+          <ows20:Value>http://www.opengis.net/wcs</ows20:Value>
+          <ows20:Value>http://www.opengis.net/wfs</ows20:Value>
+          <ows20:Value>http://www.opengis.net/wms</ows20:Value>
+          <ows20:Value>http://www.opengis.net/wmts/1.0</ows20:Value>
+          <ows20:Value>http://www.opengis.net/wps/1.0.0</ows20:Value>
+          <ows20:Value>urn:geoss:waf</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+    </ows20:Operation>
+    <ows20:Operation name="Harvest">
+      <ows20:DCP>
+        <ows20:HTTP>
+          <ows20:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/cite/default.cfg"/>
+        </ows20:HTTP>
+      </ows20:DCP>
+      <ows20:Parameter name="ResourceType">
+        <ows20:AllowedValues>
+          <ows20:Value>http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/</ows20:Value>
+          <ows20:Value>http://www.interlis.ch/INTERLIS2.3</ows20:Value>
+          <ows20:Value>http://www.isotc211.org/2005/gmi</ows20:Value>
+          <ows20:Value>http://www.opengis.net/cat/csw/2.0.2</ows20:Value>
+          <ows20:Value>http://www.opengis.net/cat/csw/3.0</ows20:Value>
+          <ows20:Value>http://www.opengis.net/cat/csw/csdgm</ows20:Value>
+          <ows20:Value>http://www.opengis.net/sos/1.0</ows20:Value>
+          <ows20:Value>http://www.opengis.net/sos/2.0</ows20:Value>
+          <ows20:Value>http://www.opengis.net/wcs</ows20:Value>
+          <ows20:Value>http://www.opengis.net/wfs</ows20:Value>
+          <ows20:Value>http://www.opengis.net/wms</ows20:Value>
+          <ows20:Value>http://www.opengis.net/wmts/1.0</ows20:Value>
+          <ows20:Value>http://www.opengis.net/wps/1.0.0</ows20:Value>
+          <ows20:Value>http://www.w3.org/2005/Atom</ows20:Value>
+          <ows20:Value>urn:geoss:waf</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+    </ows20:Operation>
+    <ows20:Parameter name="service">
+      <ows20:AllowedValues>
+        <ows20:Value>CSW</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Parameter>
+    <ows20:Parameter name="version">
+      <ows20:AllowedValues>
+        <ows20:Value>2.0.2</ows20:Value>
+        <ows20:Value>3.0.0</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Parameter>
+    <ows20:Constraint name="CoreQueryables">
+      <ows20:AllowedValues>
+        <ows20:Value>csw:AnyText</ows20:Value>
+        <ows20:Value>dc:contributor</ows20:Value>
+        <ows20:Value>dc:creator</ows20:Value>
+        <ows20:Value>dc:date</ows20:Value>
+        <ows20:Value>dc:format</ows20:Value>
+        <ows20:Value>dc:identifier</ows20:Value>
+        <ows20:Value>dc:language</ows20:Value>
+        <ows20:Value>dc:publisher</ows20:Value>
+        <ows20:Value>dc:relation</ows20:Value>
+        <ows20:Value>dc:rights</ows20:Value>
+        <ows20:Value>dc:source</ows20:Value>
+        <ows20:Value>dc:subject</ows20:Value>
+        <ows20:Value>dc:title</ows20:Value>
+        <ows20:Value>dc:type</ows20:Value>
+        <ows20:Value>dct:abstract</ows20:Value>
+        <ows20:Value>dct:modified</ows20:Value>
+        <ows20:Value>ows:BoundingBox</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="FederatedCatalogues">
+      <ows20:AllowedValues>
+        <ows20:Value>http://geo.data.gov/geoportal/csw/discovery</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="MaxRecordDefault">
+      <ows20:AllowedValues>
+        <ows20:Value>10</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="PostEncoding">
+      <ows20:AllowedValues>
+        <ows20:Value>SOAP</ows20:Value>
+        <ows20:Value>XML</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="XPathQueryables">
+      <ows20:AllowedValues>
+        <ows20:Value>allowed</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/CoreQueryables">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/CoreSortables">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/DefaultSortingAlgorithm">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Filter-CQL">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Filter-FES-KVP-Advanced">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Filter-FES-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetCapabilities-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetDomain-KVP">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetDomain-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetRecordById-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetRecords-Async-KVP">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetRecords-Async-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetRecords-Basic-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetRecords-Distributed-KVP">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetRecords-Distributed-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Harvest-Async-KVP">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Harvest-Async-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Harvest-Basic-KVP">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Harvest-Basic-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Harvest-Periodic-KVP">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Harvest-Periodic-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/OpenSearch">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/SupportedGMLVersions">
+      <ows20:AllowedValues>
+        <ows20:Value>http://www.opengis.net/gml</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Transaction">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+  </ows20:OperationsMetadata>
+  <ows20:Languages>
+    <ows20:Language>en</ows20:Language>
+  </ows20:Languages>
+  <fes20:Filter_Capabilities>
+    <fes20:Conformance>
+      <fes20:Constraint name="ImplementsQuery">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsAdHocQuery">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsFunctions">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsResourceld">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsMinStandardFilter">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsStandardFilter">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsMinSpatialFilter">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsSpatialFilter">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsMinTemporalFilter">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsTemporalFilter">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsVersionNav">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsSorting">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsExtendedOperators">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsMinimumXPath">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsSchemaElementFunc">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+    </fes20:Conformance>
+    <fes20:Id_Capabilities>
+      <fes20:ResourceIdentifier name="csw30:id"/>
+    </fes20:Id_Capabilities>
+    <fes20:Scalar_Capabilities>
+      <fes20:LogicalOperators/>
+      <fes20:ComparisonOperators>
+        <fes20:ComparisonOperator name="PropertyIsBetween"/>
+        <fes20:ComparisonOperator name="PropertyIsEqualTo"/>
+        <fes20:ComparisonOperator name="PropertyIsGreaterThan"/>
+        <fes20:ComparisonOperator name="PropertyIsGreaterThanOrEqualTo"/>
+        <fes20:ComparisonOperator name="PropertyIsLessThan"/>
+        <fes20:ComparisonOperator name="PropertyIsLessThanOrEqualTo"/>
+        <fes20:ComparisonOperator name="PropertyIsLike"/>
+        <fes20:ComparisonOperator name="PropertyIsNotEqualTo"/>
+        <fes20:ComparisonOperator name="PropertyIsNull"/>
+      </fes20:ComparisonOperators>
+    </fes20:Scalar_Capabilities>
+    <fes20:Spatial_Capabilities>
+      <fes20:GeometryOperands>
+        <fes20:GeometryOperand name="gml:Point"/>
+        <fes20:GeometryOperand name="gml:LineString"/>
+        <fes20:GeometryOperand name="gml:Polygon"/>
+        <fes20:GeometryOperand name="gml:Envelope"/>
+      </fes20:GeometryOperands>
+      <fes20:SpatialOperators>
+        <fes20:SpatialOperator name="BBOX"/>
+        <fes20:SpatialOperator name="Beyond"/>
+        <fes20:SpatialOperator name="Contains"/>
+        <fes20:SpatialOperator name="Crosses"/>
+        <fes20:SpatialOperator name="Disjoint"/>
+        <fes20:SpatialOperator name="DWithin"/>
+        <fes20:SpatialOperator name="Equals"/>
+        <fes20:SpatialOperator name="Intersects"/>
+        <fes20:SpatialOperator name="Overlaps"/>
+        <fes20:SpatialOperator name="Touches"/>
+        <fes20:SpatialOperator name="Within"/>
+      </fes20:SpatialOperators>
+    </fes20:Spatial_Capabilities>
+    <fes20:Functions>
+      <fes20:Function name="length">
+        <fes20:Returns>xs:string</fes20:Returns>
+      </fes20:Function>
+      <fes20:Function name="lower">
+        <fes20:Returns>xs:string</fes20:Returns>
+      </fes20:Function>
+      <fes20:Function name="ltrim">
+        <fes20:Returns>xs:string</fes20:Returns>
+      </fes20:Function>
+      <fes20:Function name="rtrim">
+        <fes20:Returns>xs:string</fes20:Returns>
+      </fes20:Function>
+      <fes20:Function name="trim">
+        <fes20:Returns>xs:string</fes20:Returns>
+      </fes20:Function>
+      <fes20:Function name="upper">
+        <fes20:Returns>xs:string</fes20:Returns>
+      </fes20:Function>
+    </fes20:Functions>
+  </fes20:Filter_Capabilities>
+</csw30:Capabilities>
diff --git a/tests/expected/suites_cite_get_9bfd17fa-15dc-4a10-8fa7-b3cff7013dd7.xml b/tests/expected/suites_cite_get_9bfd17fa-15dc-4a10-8fa7-b3cff7013dd7.xml
index df48ff9..3ac2059 100644
--- a/tests/expected/suites_cite_get_9bfd17fa-15dc-4a10-8fa7-b3cff7013dd7.xml
+++ b/tests/expected/suites_cite_get_9bfd17fa-15dc-4a10-8fa7-b3cff7013dd7.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<csw:GetRecordByIdResponse xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ows="http://www.opengis.net/ows" xmlns:fgdc="http://www.opengis.net/cat/csw/c [...]
+<csw:GetRecordByIdResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/cat/csw/2.0.2 http://schemas.opengis.net/csw/2.0.2/CSW-discovery.xsd">
   <csw:Record>
     <dc:identifier>urn:uuid:e9330592-0932-474b-be34-c3a3bb67c7db</dc:identifier>
     <dc:type>http://purl.org/dc/dcmitype/Text</dc:type>
diff --git a/tests/expected/suites_cite_get_b81c3595-06d6-4693-82ea-1ff8650755ac.xml b/tests/expected/suites_cite_get_b81c3595-06d6-4693-82ea-1ff8650755ac.xml
index 15857d5..9bf61df 100644
--- a/tests/expected/suites_cite_get_b81c3595-06d6-4693-82ea-1ff8650755ac.xml
+++ b/tests/expected/suites_cite_get_b81c3595-06d6-4693-82ea-1ff8650755ac.xml
@@ -1,3 +1,3 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<csw:GetRecordByIdResponse xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ows="http://www.opengis.net/ows" xmlns:fgdc="http://www.opengis.net/cat/csw/c [...]
+<csw:GetRecordByIdResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/cat/csw/2.0.2 http://schemas.opengis.net/csw/2.0.2/CSW-discovery.xsd"/>
diff --git a/tests/expected/suites_cite_get_ba5fc729-3b71-47a0-b7d0-42ec565cd185.xml b/tests/expected/suites_cite_get_ba5fc729-3b71-47a0-b7d0-42ec565cd185.xml
index 5c5c068..2d6fc73 100644
--- a/tests/expected/suites_cite_get_ba5fc729-3b71-47a0-b7d0-42ec565cd185.xml
+++ b/tests/expected/suites_cite_get_ba5fc729-3b71-47a0-b7d0-42ec565cd185.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<csw:Capabilities xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ows="http://www.opengis.net/ows" xmlns:fgdc="http://www.opengis.net/cat/csw/csdgm" xml [...]
+<csw:Capabilities xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ogc="http://www.opengis.net/ogc" xmlns:ows="http://www.opengis.net/ows" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" updateSequence="PYCSW_UPDATESEQUENCE" ve [...]
   <ows:ServiceIdentification>
     <ows:Title>pycsw Geospatial Catalogue</ows:Title>
     <ows:Abstract>pycsw is an OGC CSW server implementation written in Python</ows:Abstract>
@@ -11,6 +11,7 @@
     </ows:Keywords>
     <ows:ServiceType codeSpace="OGC">CSW</ows:ServiceType>
     <ows:ServiceTypeVersion>2.0.2</ows:ServiceTypeVersion>
+    <ows:ServiceTypeVersion>3.0.0</ows:ServiceTypeVersion>
     <ows:Fees>None</ows:Fees>
     <ows:AccessConstraints>None</ows:AccessConstraints>
   </ows:ServiceIdentification>
@@ -49,26 +50,12 @@
         </ows:HTTP>
       </ows:DCP>
       <ows:Parameter name="sections">
+        <ows:Value>Filter_Capabilities</ows:Value>
+        <ows:Value>OperationsMetadata</ows:Value>
         <ows:Value>ServiceIdentification</ows:Value>
         <ows:Value>ServiceProvider</ows:Value>
-        <ows:Value>OperationsMetadata</ows:Value>
-        <ows:Value>Filter_Capabilities</ows:Value>
       </ows:Parameter>
     </ows:Operation>
-    <ows:Operation name="Transaction">
-      <ows:DCP>
-        <ows:HTTP>
-          <ows:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/cite/default.cfg"/>
-        </ows:HTTP>
-      </ows:DCP>
-    </ows:Operation>
-    <ows:Operation name="GetRepositoryItem">
-      <ows:DCP>
-        <ows:HTTP>
-          <ows:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/cite/default.cfg"/>
-        </ows:HTTP>
-      </ows:DCP>
-    </ows:Operation>
     <ows:Operation name="DescribeRecord">
       <ows:DCP>
         <ows:HTTP>
@@ -76,14 +63,14 @@
           <ows:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/cite/default.cfg"/>
         </ows:HTTP>
       </ows:DCP>
-      <ows:Parameter name="schemaLanguage">
-        <ows:Value>http://www.w3.org/XML/Schema</ows:Value>
-        <ows:Value>http://www.w3.org/TR/xmlschema-1/</ows:Value>
-        <ows:Value>http://www.w3.org/2001/XMLSchema</ows:Value>
-      </ows:Parameter>
       <ows:Parameter name="outputFormat">
-        <ows:Value>application/xml</ows:Value>
         <ows:Value>application/json</ows:Value>
+        <ows:Value>application/xml</ows:Value>
+      </ows:Parameter>
+      <ows:Parameter name="schemaLanguage">
+        <ows:Value>http://www.w3.org/2001/XMLSchema</ows:Value>
+        <ows:Value>http://www.w3.org/TR/xmlschema-1/</ows:Value>
+        <ows:Value>http://www.w3.org/XML/Schema</ows:Value>
       </ows:Parameter>
       <ows:Parameter name="typeName">
         <ows:Value>csw:Record</ows:Value>
@@ -97,65 +84,49 @@
         </ows:HTTP>
       </ows:DCP>
       <ows:Parameter name="ParameterName">
-        <ows:Value>GetCapabilities.sections</ows:Value>
-        <ows:Value>DescribeRecord.schemaLanguage</ows:Value>
         <ows:Value>DescribeRecord.outputFormat</ows:Value>
+        <ows:Value>DescribeRecord.schemaLanguage</ows:Value>
         <ows:Value>DescribeRecord.typeName</ows:Value>
+        <ows:Value>GetCapabilities.sections</ows:Value>
+        <ows:Value>GetRecordById.ElementSetName</ows:Value>
         <ows:Value>GetRecordById.outputFormat</ows:Value>
         <ows:Value>GetRecordById.outputSchema</ows:Value>
-        <ows:Value>GetRecordById.ElementSetName</ows:Value>
+        <ows:Value>GetRecords.CONSTRAINTLANGUAGE</ows:Value>
+        <ows:Value>GetRecords.ElementSetName</ows:Value>
         <ows:Value>GetRecords.outputFormat</ows:Value>
         <ows:Value>GetRecords.outputSchema</ows:Value>
-        <ows:Value>GetRecords.CONSTRAINTLANGUAGE</ows:Value>
         <ows:Value>GetRecords.resultType</ows:Value>
         <ows:Value>GetRecords.typeNames</ows:Value>
-        <ows:Value>GetRecords.ElementSetName</ows:Value>
         <ows:Value>Harvest.ResourceType</ows:Value>
+        <ows:Value>Transaction.TransactionSchemas</ows:Value>
       </ows:Parameter>
     </ows:Operation>
-    <ows:Operation name="GetRecordById">
+    <ows:Operation name="GetRecords">
       <ows:DCP>
         <ows:HTTP>
           <ows:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/cite/default.cfg"/>
           <ows:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/cite/default.cfg"/>
         </ows:HTTP>
       </ows:DCP>
-      <ows:Parameter name="outputFormat">
-        <ows:Value>application/xml</ows:Value>
-        <ows:Value>application/json</ows:Value>
-      </ows:Parameter>
-      <ows:Parameter name="outputSchema">
-        <ows:Value>http://www.opengis.net/cat/csw/2.0.2</ows:Value>
-        <ows:Value>http://www.w3.org/2005/Atom</ows:Value>
-        <ows:Value>http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/</ows:Value>
-        <ows:Value>http://www.opengis.net/cat/csw/csdgm</ows:Value>
+      <ows:Parameter name="CONSTRAINTLANGUAGE">
+        <ows:Value>CQL_TEXT</ows:Value>
+        <ows:Value>FILTER</ows:Value>
       </ows:Parameter>
       <ows:Parameter name="ElementSetName">
         <ows:Value>brief</ows:Value>
-        <ows:Value>summary</ows:Value>
         <ows:Value>full</ows:Value>
+        <ows:Value>summary</ows:Value>
       </ows:Parameter>
-    </ows:Operation>
-    <ows:Operation name="GetRecords">
-      <ows:DCP>
-        <ows:HTTP>
-          <ows:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/cite/default.cfg"/>
-          <ows:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/cite/default.cfg"/>
-        </ows:HTTP>
-      </ows:DCP>
       <ows:Parameter name="outputFormat">
-        <ows:Value>application/xml</ows:Value>
         <ows:Value>application/json</ows:Value>
+        <ows:Value>application/xml</ows:Value>
       </ows:Parameter>
       <ows:Parameter name="outputSchema">
-        <ows:Value>http://www.opengis.net/cat/csw/2.0.2</ows:Value>
-        <ows:Value>http://www.w3.org/2005/Atom</ows:Value>
         <ows:Value>http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/</ows:Value>
+        <ows:Value>http://www.interlis.ch/INTERLIS2.3</ows:Value>
+        <ows:Value>http://www.opengis.net/cat/csw/2.0.2</ows:Value>
         <ows:Value>http://www.opengis.net/cat/csw/csdgm</ows:Value>
-      </ows:Parameter>
-      <ows:Parameter name="CONSTRAINTLANGUAGE">
-        <ows:Value>FILTER</ows:Value>
-        <ows:Value>CQL_TEXT</ows:Value>
+        <ows:Value>http://www.w3.org/2005/Atom</ows:Value>
       </ows:Parameter>
       <ows:Parameter name="resultType">
         <ows:Value>hits</ows:Value>
@@ -165,60 +136,110 @@
       <ows:Parameter name="typeNames">
         <ows:Value>csw:Record</ows:Value>
       </ows:Parameter>
-      <ows:Parameter name="ElementSetName">
-        <ows:Value>brief</ows:Value>
-        <ows:Value>summary</ows:Value>
-        <ows:Value>full</ows:Value>
-      </ows:Parameter>
       <ows:Constraint name="SupportedDublinCoreQueryables">
+        <ows:Value>csw:AnyText</ows:Value>
         <ows:Value>dc:contributor</ows:Value>
-        <ows:Value>dc:source</ows:Value>
-        <ows:Value>dc:language</ows:Value>
-        <ows:Value>dc:title</ows:Value>
-        <ows:Value>dc:subject</ows:Value>
         <ows:Value>dc:creator</ows:Value>
-        <ows:Value>dc:type</ows:Value>
-        <ows:Value>ows:BoundingBox</ows:Value>
-        <ows:Value>dct:modified</ows:Value>
-        <ows:Value>dct:abstract</ows:Value>
-        <ows:Value>dc:relation</ows:Value>
         <ows:Value>dc:date</ows:Value>
+        <ows:Value>dc:format</ows:Value>
         <ows:Value>dc:identifier</ows:Value>
+        <ows:Value>dc:language</ows:Value>
         <ows:Value>dc:publisher</ows:Value>
-        <ows:Value>dc:format</ows:Value>
-        <ows:Value>csw:AnyText</ows:Value>
+        <ows:Value>dc:relation</ows:Value>
         <ows:Value>dc:rights</ows:Value>
+        <ows:Value>dc:source</ows:Value>
+        <ows:Value>dc:subject</ows:Value>
+        <ows:Value>dc:title</ows:Value>
+        <ows:Value>dc:type</ows:Value>
+        <ows:Value>dct:abstract</ows:Value>
+        <ows:Value>dct:modified</ows:Value>
+        <ows:Value>ows:BoundingBox</ows:Value>
       </ows:Constraint>
     </ows:Operation>
-    <ows:Operation name="Harvest">
+    <ows:Operation name="GetRecordById">
       <ows:DCP>
         <ows:HTTP>
+          <ows:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/cite/default.cfg"/>
           <ows:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/cite/default.cfg"/>
         </ows:HTTP>
       </ows:DCP>
-      <ows:Parameter name="ResourceType">
+      <ows:Parameter name="ElementSetName">
+        <ows:Value>brief</ows:Value>
+        <ows:Value>full</ows:Value>
+        <ows:Value>summary</ows:Value>
+      </ows:Parameter>
+      <ows:Parameter name="outputFormat">
+        <ows:Value>application/json</ows:Value>
+        <ows:Value>application/xml</ows:Value>
+      </ows:Parameter>
+      <ows:Parameter name="outputSchema">
+        <ows:Value>http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/</ows:Value>
+        <ows:Value>http://www.interlis.ch/INTERLIS2.3</ows:Value>
         <ows:Value>http://www.opengis.net/cat/csw/2.0.2</ows:Value>
-        <ows:Value>http://www.opengis.net/wms</ows:Value>
-        <ows:Value>http://www.opengis.net/wfs</ows:Value>
-        <ows:Value>http://www.opengis.net/wcs</ows:Value>
-        <ows:Value>http://www.opengis.net/wps/1.0.0</ows:Value>
+        <ows:Value>http://www.opengis.net/cat/csw/csdgm</ows:Value>
+        <ows:Value>http://www.w3.org/2005/Atom</ows:Value>
+      </ows:Parameter>
+    </ows:Operation>
+    <ows:Operation name="GetRepositoryItem">
+      <ows:DCP>
+        <ows:HTTP>
+          <ows:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/cite/default.cfg"/>
+        </ows:HTTP>
+      </ows:DCP>
+    </ows:Operation>
+    <ows:Operation name="Transaction">
+      <ows:DCP>
+        <ows:HTTP>
+          <ows:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/cite/default.cfg"/>
+        </ows:HTTP>
+      </ows:DCP>
+      <ows:Parameter name="TransactionSchemas">
+        <ows:Value>http://www.isotc211.org/2005/gmi</ows:Value>
+        <ows:Value>http://www.opengis.net/cat/csw/2.0.2</ows:Value>
+        <ows:Value>http://www.opengis.net/cat/csw/3.0</ows:Value>
         <ows:Value>http://www.opengis.net/sos/1.0</ows:Value>
         <ows:Value>http://www.opengis.net/sos/2.0</ows:Value>
-        <ows:Value>http://www.isotc211.org/2005/gmi</ows:Value>
+        <ows:Value>http://www.opengis.net/wcs</ows:Value>
+        <ows:Value>http://www.opengis.net/wfs</ows:Value>
+        <ows:Value>http://www.opengis.net/wms</ows:Value>
+        <ows:Value>http://www.opengis.net/wmts/1.0</ows:Value>
+        <ows:Value>http://www.opengis.net/wps/1.0.0</ows:Value>
         <ows:Value>urn:geoss:waf</ows:Value>
-        <ows:Value>http://www.w3.org/2005/Atom</ows:Value>
+      </ows:Parameter>
+    </ows:Operation>
+    <ows:Operation name="Harvest">
+      <ows:DCP>
+        <ows:HTTP>
+          <ows:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/cite/default.cfg"/>
+        </ows:HTTP>
+      </ows:DCP>
+      <ows:Parameter name="ResourceType">
         <ows:Value>http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/</ows:Value>
+        <ows:Value>http://www.interlis.ch/INTERLIS2.3</ows:Value>
+        <ows:Value>http://www.isotc211.org/2005/gmi</ows:Value>
+        <ows:Value>http://www.opengis.net/cat/csw/2.0.2</ows:Value>
+        <ows:Value>http://www.opengis.net/cat/csw/3.0</ows:Value>
         <ows:Value>http://www.opengis.net/cat/csw/csdgm</ows:Value>
+        <ows:Value>http://www.opengis.net/sos/1.0</ows:Value>
+        <ows:Value>http://www.opengis.net/sos/2.0</ows:Value>
+        <ows:Value>http://www.opengis.net/wcs</ows:Value>
+        <ows:Value>http://www.opengis.net/wfs</ows:Value>
+        <ows:Value>http://www.opengis.net/wms</ows:Value>
+        <ows:Value>http://www.opengis.net/wmts/1.0</ows:Value>
+        <ows:Value>http://www.opengis.net/wps/1.0.0</ows:Value>
+        <ows:Value>http://www.w3.org/2005/Atom</ows:Value>
+        <ows:Value>urn:geoss:waf</ows:Value>
       </ows:Parameter>
     </ows:Operation>
-    <ows:Parameter name="version">
-      <ows:Value>2.0.2</ows:Value>
-    </ows:Parameter>
     <ows:Parameter name="service">
       <ows:Value>CSW</ows:Value>
     </ows:Parameter>
-    <ows:Constraint name="XPathQueryables">
-      <ows:Value>allowed</ows:Value>
+    <ows:Parameter name="version">
+      <ows:Value>2.0.2</ows:Value>
+      <ows:Value>3.0.0</ows:Value>
+    </ows:Parameter>
+    <ows:Constraint name="FederatedCatalogues">
+      <ows:Value>http://geo.data.gov/geoportal/csw/discovery</ows:Value>
     </ows:Constraint>
     <ows:Constraint name="MaxRecordDefault">
       <ows:Value>10</ows:Value>
@@ -227,8 +248,8 @@
       <ows:Value>XML</ows:Value>
       <ows:Value>SOAP</ows:Value>
     </ows:Constraint>
-    <ows:Constraint name="FederatedCatalogues">
-      <ows:Value>http://geo.data.gov/geoportal/csw/discovery</ows:Value>
+    <ows:Constraint name="XPathQueryables">
+      <ows:Value>allowed</ows:Value>
     </ows:Constraint>
   </ows:OperationsMetadata>
   <ogc:Filter_Capabilities>
@@ -258,11 +279,11 @@
       <ogc:ComparisonOperators>
         <ogc:ComparisonOperator>Between</ogc:ComparisonOperator>
         <ogc:ComparisonOperator>EqualTo</ogc:ComparisonOperator>
-        <ogc:ComparisonOperator>LessThanEqualTo</ogc:ComparisonOperator>
         <ogc:ComparisonOperator>GreaterThan</ogc:ComparisonOperator>
-        <ogc:ComparisonOperator>Like</ogc:ComparisonOperator>
-        <ogc:ComparisonOperator>LessThan</ogc:ComparisonOperator>
         <ogc:ComparisonOperator>GreaterThanEqualTo</ogc:ComparisonOperator>
+        <ogc:ComparisonOperator>LessThan</ogc:ComparisonOperator>
+        <ogc:ComparisonOperator>LessThanEqualTo</ogc:ComparisonOperator>
+        <ogc:ComparisonOperator>Like</ogc:ComparisonOperator>
         <ogc:ComparisonOperator>NotEqualTo</ogc:ComparisonOperator>
         <ogc:ComparisonOperator>NullCheck</ogc:ComparisonOperator>
       </ogc:ComparisonOperators>
diff --git a/tests/expected/suites_cite_get_c4ea754f-c158-4d8d-8253-dc8f86021b52.xml b/tests/expected/suites_cite_get_c4ea754f-c158-4d8d-8253-dc8f86021b52.xml
index 48cfa6c..42a76d4 100644
--- a/tests/expected/suites_cite_get_c4ea754f-c158-4d8d-8253-dc8f86021b52.xml
+++ b/tests/expected/suites_cite_get_c4ea754f-c158-4d8d-8253-dc8f86021b52.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<ows:ExceptionReport xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ows="http://www.opengis.net/ows" xmlns:fgdc="http://www.opengis.net/cat/csw/csdgm"  [...]
-  <ows:Exception exceptionCode="MissingParameterValue" locator="service">
-    <ows:ExceptionText>Missing keyword: service</ows:ExceptionText>
-  </ows:Exception>
-</ows:ExceptionReport>
+<ows20:ExceptionReport xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:ows20="http://www.opengis.net/ows/2.0" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="3.0.0" xml:lang="en-US" xsi:schemaLocation="http://www.opengis. [...]
+  <ows20:Exception exceptionCode="MissingParameterValue" locator="service">
+    <ows20:ExceptionText>Missing keyword: service</ows20:ExceptionText>
+  </ows20:Exception>
+</ows20:ExceptionReport>
diff --git a/tests/expected/suites_cite_get_f4692ec5-9547-4a05-88ab-e6154af2640a.xml b/tests/expected/suites_cite_get_f4692ec5-9547-4a05-88ab-e6154af2640a.xml
index 5c5c068..2d6fc73 100644
--- a/tests/expected/suites_cite_get_f4692ec5-9547-4a05-88ab-e6154af2640a.xml
+++ b/tests/expected/suites_cite_get_f4692ec5-9547-4a05-88ab-e6154af2640a.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<csw:Capabilities xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ows="http://www.opengis.net/ows" xmlns:fgdc="http://www.opengis.net/cat/csw/csdgm" xml [...]
+<csw:Capabilities xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ogc="http://www.opengis.net/ogc" xmlns:ows="http://www.opengis.net/ows" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" updateSequence="PYCSW_UPDATESEQUENCE" ve [...]
   <ows:ServiceIdentification>
     <ows:Title>pycsw Geospatial Catalogue</ows:Title>
     <ows:Abstract>pycsw is an OGC CSW server implementation written in Python</ows:Abstract>
@@ -11,6 +11,7 @@
     </ows:Keywords>
     <ows:ServiceType codeSpace="OGC">CSW</ows:ServiceType>
     <ows:ServiceTypeVersion>2.0.2</ows:ServiceTypeVersion>
+    <ows:ServiceTypeVersion>3.0.0</ows:ServiceTypeVersion>
     <ows:Fees>None</ows:Fees>
     <ows:AccessConstraints>None</ows:AccessConstraints>
   </ows:ServiceIdentification>
@@ -49,26 +50,12 @@
         </ows:HTTP>
       </ows:DCP>
       <ows:Parameter name="sections">
+        <ows:Value>Filter_Capabilities</ows:Value>
+        <ows:Value>OperationsMetadata</ows:Value>
         <ows:Value>ServiceIdentification</ows:Value>
         <ows:Value>ServiceProvider</ows:Value>
-        <ows:Value>OperationsMetadata</ows:Value>
-        <ows:Value>Filter_Capabilities</ows:Value>
       </ows:Parameter>
     </ows:Operation>
-    <ows:Operation name="Transaction">
-      <ows:DCP>
-        <ows:HTTP>
-          <ows:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/cite/default.cfg"/>
-        </ows:HTTP>
-      </ows:DCP>
-    </ows:Operation>
-    <ows:Operation name="GetRepositoryItem">
-      <ows:DCP>
-        <ows:HTTP>
-          <ows:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/cite/default.cfg"/>
-        </ows:HTTP>
-      </ows:DCP>
-    </ows:Operation>
     <ows:Operation name="DescribeRecord">
       <ows:DCP>
         <ows:HTTP>
@@ -76,14 +63,14 @@
           <ows:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/cite/default.cfg"/>
         </ows:HTTP>
       </ows:DCP>
-      <ows:Parameter name="schemaLanguage">
-        <ows:Value>http://www.w3.org/XML/Schema</ows:Value>
-        <ows:Value>http://www.w3.org/TR/xmlschema-1/</ows:Value>
-        <ows:Value>http://www.w3.org/2001/XMLSchema</ows:Value>
-      </ows:Parameter>
       <ows:Parameter name="outputFormat">
-        <ows:Value>application/xml</ows:Value>
         <ows:Value>application/json</ows:Value>
+        <ows:Value>application/xml</ows:Value>
+      </ows:Parameter>
+      <ows:Parameter name="schemaLanguage">
+        <ows:Value>http://www.w3.org/2001/XMLSchema</ows:Value>
+        <ows:Value>http://www.w3.org/TR/xmlschema-1/</ows:Value>
+        <ows:Value>http://www.w3.org/XML/Schema</ows:Value>
       </ows:Parameter>
       <ows:Parameter name="typeName">
         <ows:Value>csw:Record</ows:Value>
@@ -97,65 +84,49 @@
         </ows:HTTP>
       </ows:DCP>
       <ows:Parameter name="ParameterName">
-        <ows:Value>GetCapabilities.sections</ows:Value>
-        <ows:Value>DescribeRecord.schemaLanguage</ows:Value>
         <ows:Value>DescribeRecord.outputFormat</ows:Value>
+        <ows:Value>DescribeRecord.schemaLanguage</ows:Value>
         <ows:Value>DescribeRecord.typeName</ows:Value>
+        <ows:Value>GetCapabilities.sections</ows:Value>
+        <ows:Value>GetRecordById.ElementSetName</ows:Value>
         <ows:Value>GetRecordById.outputFormat</ows:Value>
         <ows:Value>GetRecordById.outputSchema</ows:Value>
-        <ows:Value>GetRecordById.ElementSetName</ows:Value>
+        <ows:Value>GetRecords.CONSTRAINTLANGUAGE</ows:Value>
+        <ows:Value>GetRecords.ElementSetName</ows:Value>
         <ows:Value>GetRecords.outputFormat</ows:Value>
         <ows:Value>GetRecords.outputSchema</ows:Value>
-        <ows:Value>GetRecords.CONSTRAINTLANGUAGE</ows:Value>
         <ows:Value>GetRecords.resultType</ows:Value>
         <ows:Value>GetRecords.typeNames</ows:Value>
-        <ows:Value>GetRecords.ElementSetName</ows:Value>
         <ows:Value>Harvest.ResourceType</ows:Value>
+        <ows:Value>Transaction.TransactionSchemas</ows:Value>
       </ows:Parameter>
     </ows:Operation>
-    <ows:Operation name="GetRecordById">
+    <ows:Operation name="GetRecords">
       <ows:DCP>
         <ows:HTTP>
           <ows:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/cite/default.cfg"/>
           <ows:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/cite/default.cfg"/>
         </ows:HTTP>
       </ows:DCP>
-      <ows:Parameter name="outputFormat">
-        <ows:Value>application/xml</ows:Value>
-        <ows:Value>application/json</ows:Value>
-      </ows:Parameter>
-      <ows:Parameter name="outputSchema">
-        <ows:Value>http://www.opengis.net/cat/csw/2.0.2</ows:Value>
-        <ows:Value>http://www.w3.org/2005/Atom</ows:Value>
-        <ows:Value>http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/</ows:Value>
-        <ows:Value>http://www.opengis.net/cat/csw/csdgm</ows:Value>
+      <ows:Parameter name="CONSTRAINTLANGUAGE">
+        <ows:Value>CQL_TEXT</ows:Value>
+        <ows:Value>FILTER</ows:Value>
       </ows:Parameter>
       <ows:Parameter name="ElementSetName">
         <ows:Value>brief</ows:Value>
-        <ows:Value>summary</ows:Value>
         <ows:Value>full</ows:Value>
+        <ows:Value>summary</ows:Value>
       </ows:Parameter>
-    </ows:Operation>
-    <ows:Operation name="GetRecords">
-      <ows:DCP>
-        <ows:HTTP>
-          <ows:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/cite/default.cfg"/>
-          <ows:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/cite/default.cfg"/>
-        </ows:HTTP>
-      </ows:DCP>
       <ows:Parameter name="outputFormat">
-        <ows:Value>application/xml</ows:Value>
         <ows:Value>application/json</ows:Value>
+        <ows:Value>application/xml</ows:Value>
       </ows:Parameter>
       <ows:Parameter name="outputSchema">
-        <ows:Value>http://www.opengis.net/cat/csw/2.0.2</ows:Value>
-        <ows:Value>http://www.w3.org/2005/Atom</ows:Value>
         <ows:Value>http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/</ows:Value>
+        <ows:Value>http://www.interlis.ch/INTERLIS2.3</ows:Value>
+        <ows:Value>http://www.opengis.net/cat/csw/2.0.2</ows:Value>
         <ows:Value>http://www.opengis.net/cat/csw/csdgm</ows:Value>
-      </ows:Parameter>
-      <ows:Parameter name="CONSTRAINTLANGUAGE">
-        <ows:Value>FILTER</ows:Value>
-        <ows:Value>CQL_TEXT</ows:Value>
+        <ows:Value>http://www.w3.org/2005/Atom</ows:Value>
       </ows:Parameter>
       <ows:Parameter name="resultType">
         <ows:Value>hits</ows:Value>
@@ -165,60 +136,110 @@
       <ows:Parameter name="typeNames">
         <ows:Value>csw:Record</ows:Value>
       </ows:Parameter>
-      <ows:Parameter name="ElementSetName">
-        <ows:Value>brief</ows:Value>
-        <ows:Value>summary</ows:Value>
-        <ows:Value>full</ows:Value>
-      </ows:Parameter>
       <ows:Constraint name="SupportedDublinCoreQueryables">
+        <ows:Value>csw:AnyText</ows:Value>
         <ows:Value>dc:contributor</ows:Value>
-        <ows:Value>dc:source</ows:Value>
-        <ows:Value>dc:language</ows:Value>
-        <ows:Value>dc:title</ows:Value>
-        <ows:Value>dc:subject</ows:Value>
         <ows:Value>dc:creator</ows:Value>
-        <ows:Value>dc:type</ows:Value>
-        <ows:Value>ows:BoundingBox</ows:Value>
-        <ows:Value>dct:modified</ows:Value>
-        <ows:Value>dct:abstract</ows:Value>
-        <ows:Value>dc:relation</ows:Value>
         <ows:Value>dc:date</ows:Value>
+        <ows:Value>dc:format</ows:Value>
         <ows:Value>dc:identifier</ows:Value>
+        <ows:Value>dc:language</ows:Value>
         <ows:Value>dc:publisher</ows:Value>
-        <ows:Value>dc:format</ows:Value>
-        <ows:Value>csw:AnyText</ows:Value>
+        <ows:Value>dc:relation</ows:Value>
         <ows:Value>dc:rights</ows:Value>
+        <ows:Value>dc:source</ows:Value>
+        <ows:Value>dc:subject</ows:Value>
+        <ows:Value>dc:title</ows:Value>
+        <ows:Value>dc:type</ows:Value>
+        <ows:Value>dct:abstract</ows:Value>
+        <ows:Value>dct:modified</ows:Value>
+        <ows:Value>ows:BoundingBox</ows:Value>
       </ows:Constraint>
     </ows:Operation>
-    <ows:Operation name="Harvest">
+    <ows:Operation name="GetRecordById">
       <ows:DCP>
         <ows:HTTP>
+          <ows:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/cite/default.cfg"/>
           <ows:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/cite/default.cfg"/>
         </ows:HTTP>
       </ows:DCP>
-      <ows:Parameter name="ResourceType">
+      <ows:Parameter name="ElementSetName">
+        <ows:Value>brief</ows:Value>
+        <ows:Value>full</ows:Value>
+        <ows:Value>summary</ows:Value>
+      </ows:Parameter>
+      <ows:Parameter name="outputFormat">
+        <ows:Value>application/json</ows:Value>
+        <ows:Value>application/xml</ows:Value>
+      </ows:Parameter>
+      <ows:Parameter name="outputSchema">
+        <ows:Value>http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/</ows:Value>
+        <ows:Value>http://www.interlis.ch/INTERLIS2.3</ows:Value>
         <ows:Value>http://www.opengis.net/cat/csw/2.0.2</ows:Value>
-        <ows:Value>http://www.opengis.net/wms</ows:Value>
-        <ows:Value>http://www.opengis.net/wfs</ows:Value>
-        <ows:Value>http://www.opengis.net/wcs</ows:Value>
-        <ows:Value>http://www.opengis.net/wps/1.0.0</ows:Value>
+        <ows:Value>http://www.opengis.net/cat/csw/csdgm</ows:Value>
+        <ows:Value>http://www.w3.org/2005/Atom</ows:Value>
+      </ows:Parameter>
+    </ows:Operation>
+    <ows:Operation name="GetRepositoryItem">
+      <ows:DCP>
+        <ows:HTTP>
+          <ows:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/cite/default.cfg"/>
+        </ows:HTTP>
+      </ows:DCP>
+    </ows:Operation>
+    <ows:Operation name="Transaction">
+      <ows:DCP>
+        <ows:HTTP>
+          <ows:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/cite/default.cfg"/>
+        </ows:HTTP>
+      </ows:DCP>
+      <ows:Parameter name="TransactionSchemas">
+        <ows:Value>http://www.isotc211.org/2005/gmi</ows:Value>
+        <ows:Value>http://www.opengis.net/cat/csw/2.0.2</ows:Value>
+        <ows:Value>http://www.opengis.net/cat/csw/3.0</ows:Value>
         <ows:Value>http://www.opengis.net/sos/1.0</ows:Value>
         <ows:Value>http://www.opengis.net/sos/2.0</ows:Value>
-        <ows:Value>http://www.isotc211.org/2005/gmi</ows:Value>
+        <ows:Value>http://www.opengis.net/wcs</ows:Value>
+        <ows:Value>http://www.opengis.net/wfs</ows:Value>
+        <ows:Value>http://www.opengis.net/wms</ows:Value>
+        <ows:Value>http://www.opengis.net/wmts/1.0</ows:Value>
+        <ows:Value>http://www.opengis.net/wps/1.0.0</ows:Value>
         <ows:Value>urn:geoss:waf</ows:Value>
-        <ows:Value>http://www.w3.org/2005/Atom</ows:Value>
+      </ows:Parameter>
+    </ows:Operation>
+    <ows:Operation name="Harvest">
+      <ows:DCP>
+        <ows:HTTP>
+          <ows:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/cite/default.cfg"/>
+        </ows:HTTP>
+      </ows:DCP>
+      <ows:Parameter name="ResourceType">
         <ows:Value>http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/</ows:Value>
+        <ows:Value>http://www.interlis.ch/INTERLIS2.3</ows:Value>
+        <ows:Value>http://www.isotc211.org/2005/gmi</ows:Value>
+        <ows:Value>http://www.opengis.net/cat/csw/2.0.2</ows:Value>
+        <ows:Value>http://www.opengis.net/cat/csw/3.0</ows:Value>
         <ows:Value>http://www.opengis.net/cat/csw/csdgm</ows:Value>
+        <ows:Value>http://www.opengis.net/sos/1.0</ows:Value>
+        <ows:Value>http://www.opengis.net/sos/2.0</ows:Value>
+        <ows:Value>http://www.opengis.net/wcs</ows:Value>
+        <ows:Value>http://www.opengis.net/wfs</ows:Value>
+        <ows:Value>http://www.opengis.net/wms</ows:Value>
+        <ows:Value>http://www.opengis.net/wmts/1.0</ows:Value>
+        <ows:Value>http://www.opengis.net/wps/1.0.0</ows:Value>
+        <ows:Value>http://www.w3.org/2005/Atom</ows:Value>
+        <ows:Value>urn:geoss:waf</ows:Value>
       </ows:Parameter>
     </ows:Operation>
-    <ows:Parameter name="version">
-      <ows:Value>2.0.2</ows:Value>
-    </ows:Parameter>
     <ows:Parameter name="service">
       <ows:Value>CSW</ows:Value>
     </ows:Parameter>
-    <ows:Constraint name="XPathQueryables">
-      <ows:Value>allowed</ows:Value>
+    <ows:Parameter name="version">
+      <ows:Value>2.0.2</ows:Value>
+      <ows:Value>3.0.0</ows:Value>
+    </ows:Parameter>
+    <ows:Constraint name="FederatedCatalogues">
+      <ows:Value>http://geo.data.gov/geoportal/csw/discovery</ows:Value>
     </ows:Constraint>
     <ows:Constraint name="MaxRecordDefault">
       <ows:Value>10</ows:Value>
@@ -227,8 +248,8 @@
       <ows:Value>XML</ows:Value>
       <ows:Value>SOAP</ows:Value>
     </ows:Constraint>
-    <ows:Constraint name="FederatedCatalogues">
-      <ows:Value>http://geo.data.gov/geoportal/csw/discovery</ows:Value>
+    <ows:Constraint name="XPathQueryables">
+      <ows:Value>allowed</ows:Value>
     </ows:Constraint>
   </ows:OperationsMetadata>
   <ogc:Filter_Capabilities>
@@ -258,11 +279,11 @@
       <ogc:ComparisonOperators>
         <ogc:ComparisonOperator>Between</ogc:ComparisonOperator>
         <ogc:ComparisonOperator>EqualTo</ogc:ComparisonOperator>
-        <ogc:ComparisonOperator>LessThanEqualTo</ogc:ComparisonOperator>
         <ogc:ComparisonOperator>GreaterThan</ogc:ComparisonOperator>
-        <ogc:ComparisonOperator>Like</ogc:ComparisonOperator>
-        <ogc:ComparisonOperator>LessThan</ogc:ComparisonOperator>
         <ogc:ComparisonOperator>GreaterThanEqualTo</ogc:ComparisonOperator>
+        <ogc:ComparisonOperator>LessThan</ogc:ComparisonOperator>
+        <ogc:ComparisonOperator>LessThanEqualTo</ogc:ComparisonOperator>
+        <ogc:ComparisonOperator>Like</ogc:ComparisonOperator>
         <ogc:ComparisonOperator>NotEqualTo</ogc:ComparisonOperator>
         <ogc:ComparisonOperator>NullCheck</ogc:ComparisonOperator>
       </ogc:ComparisonOperators>
diff --git a/tests/expected/suites_cite_get_f997f25e-c865-4d53-a362-0ed1846337f2.xml b/tests/expected/suites_cite_get_f997f25e-c865-4d53-a362-0ed1846337f2.xml
index 2682d35..6cddad9 100644
--- a/tests/expected/suites_cite_get_f997f25e-c865-4d53-a362-0ed1846337f2.xml
+++ b/tests/expected/suites_cite_get_f997f25e-c865-4d53-a362-0ed1846337f2.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<csw:GetRecordByIdResponse xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ows="http://www.opengis.net/ows" xmlns:fgdc="http://www.opengis.net/cat/csw/c [...]
+<csw:GetRecordByIdResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/cat/csw/2.0.2 http://schemas.opengis.net/csw/2.0.2/CSW-discovery.xsd">
   <csw:SummaryRecord>
     <dc:identifier>urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63</dc:identifier>
     <dc:title>Mauris sed neque</dc:title>
diff --git a/tests/expected/suites_cite_post_0c976d98-c896-4b10-b1fe-a22ef50434e7.xml b/tests/expected/suites_cite_post_0c976d98-c896-4b10-b1fe-a22ef50434e7.xml
index 9b6ce30..ce7aca9 100644
--- a/tests/expected/suites_cite_post_0c976d98-c896-4b10-b1fe-a22ef50434e7.xml
+++ b/tests/expected/suites_cite_post_0c976d98-c896-4b10-b1fe-a22ef50434e7.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<csw:GetRecordsResponse xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ows="http://www.opengis.net/ows" xmlns:fgdc="http://www.opengis.net/cat/csw/csdg [...]
+<csw:GetRecordsResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.0.2" xsi:schemaLocation="http://www.opengis.net/cat/csw/2.0.2 http://schemas.opengis.net/csw/2.0.2/CSW-di [...]
   <csw:SearchStatus timestamp="PYCSW_TIMESTAMP"/>
   <csw:SearchResults nextRecord="1" numberOfRecordsMatched="11" numberOfRecordsReturned="0" recordSchema="http://www.opengis.net/cat/csw/2.0.2"/>
 </csw:GetRecordsResponse>
diff --git a/tests/expected/suites_cite_post_19d2a6ed-be28-4866-ae15-e3bb634486cb.xml b/tests/expected/suites_cite_post_19d2a6ed-be28-4866-ae15-e3bb634486cb.xml
index 166c79e..b80c3b5 100644
--- a/tests/expected/suites_cite_post_19d2a6ed-be28-4866-ae15-e3bb634486cb.xml
+++ b/tests/expected/suites_cite_post_19d2a6ed-be28-4866-ae15-e3bb634486cb.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<csw:GetRecordsResponse xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ows="http://www.opengis.net/ows" xmlns:fgdc="http://www.opengis.net/cat/csw/csdg [...]
+<csw:GetRecordsResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.0.2" xsi:schemaLocation="http://www.opengis.net/cat/csw/2.0.2 http://schemas.opengis.net/csw/2.0.2/CSW-di [...]
   <csw:SearchStatus timestamp="PYCSW_TIMESTAMP"/>
   <csw:SearchResults nextRecord="0" numberOfRecordsMatched="8" numberOfRecordsReturned="8" recordSchema="http://www.opengis.net/cat/csw/2.0.2" elementSet="brief">
     <csw:BriefRecord>
diff --git a/tests/expected/suites_cite_post_1ab55aa3-6685-4595-8ecd-45987a7b8b59.xml b/tests/expected/suites_cite_post_1ab55aa3-6685-4595-8ecd-45987a7b8b59.xml
index d908020..a78d68a 100644
--- a/tests/expected/suites_cite_post_1ab55aa3-6685-4595-8ecd-45987a7b8b59.xml
+++ b/tests/expected/suites_cite_post_1ab55aa3-6685-4595-8ecd-45987a7b8b59.xml
@@ -1,8 +1,8 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<csw:Acknowledgement xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ows="http://www.opengis.net/ows" xmlns:fgdc="http://www.opengis.net/cat/csw/csdgm"  [...]
+<csw:Acknowledgement xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ogc="http://www.opengis.net/ogc" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" timeStamp="PYCSW_TIMESTAMP">
   <csw:EchoedRequest>
-    <csw:GetRecords xmlns="http://www.occamlab.com/ctl" xmlns:ctl="http://www.occamlab.com/ctl" xmlns:p="http://teamengine.sourceforge.net/parsers" xmlns:parsers="http://www.occamlab.com/te/parsers" xmlns:saxon="http://saxon.sf.net/" xmlns:te="http://www.occamlab.com/te" xmlns:tec="java:com.occamlab.te.TECore" xmlns:tems="java:com.occamlab.te.web.MonitorServlet" xmlns:xi="http://www.w3.org/2001/XInclude" resultType="validate" service="CSW" version="2.0.2">
+    <csw:GetRecords resultType="validate" service="CSW" version="2.0.2">
   <csw:Query typeNames="csw:Record">
     <csw:ElementSetName>full</csw:ElementSetName>
     <csw:Constraint version="1.1.0">
diff --git a/tests/expected/suites_cite_post_1c958b7a-ca09-4c38-98bd-ef1d1d28cc14.xml b/tests/expected/suites_cite_post_1c958b7a-ca09-4c38-98bd-ef1d1d28cc14.xml
index d9045b7..a1691f4 100644
--- a/tests/expected/suites_cite_post_1c958b7a-ca09-4c38-98bd-ef1d1d28cc14.xml
+++ b/tests/expected/suites_cite_post_1c958b7a-ca09-4c38-98bd-ef1d1d28cc14.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<ows:ExceptionReport xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ows="http://www.opengis.net/ows" xmlns:fgdc="http://www.opengis.net/cat/csw/csdgm"  [...]
+<ows:ExceptionReport xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" language="en-US" version="1.2.0" xsi:schemaLocation="http://www.opengis.net/ows http://schemas.opengis.net/ows/1.0.0/ow [...]
   <ows:Exception exceptionCode="InvalidParameterValue" locator="outputformat">
     <ows:ExceptionText>Invalid outputFormat parameter value: application/xhtml+xml</ows:ExceptionText>
   </ows:Exception>
diff --git a/tests/expected/suites_cite_post_1c97fc1a-61cd-4c1d-8054-933e17a6c5ee.xml b/tests/expected/suites_cite_post_1c97fc1a-61cd-4c1d-8054-933e17a6c5ee.xml
index d68fd69..2b0eebe 100644
--- a/tests/expected/suites_cite_post_1c97fc1a-61cd-4c1d-8054-933e17a6c5ee.xml
+++ b/tests/expected/suites_cite_post_1c97fc1a-61cd-4c1d-8054-933e17a6c5ee.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<ows:ExceptionReport xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ows="http://www.opengis.net/ows" xmlns:fgdc="http://www.opengis.net/cat/csw/csdgm"  [...]
+<ows:ExceptionReport xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" language="en-US" version="1.2.0" xsi:schemaLocation="http://www.opengis.net/ows http://schemas.opengis.net/ows/1.0.0/ow [...]
   <ows:Exception exceptionCode="InvalidParameterValue" locator="service">
     <ows:ExceptionText>Invalid Constraint: Invalid Filter request: Invalid PropertyName: /dc:title.  '/dc:title'</ows:ExceptionText>
   </ows:Exception>
diff --git a/tests/expected/suites_cite_post_2102a460-5d62-465f-9668-d70b3faafbfa.xml b/tests/expected/suites_cite_post_2102a460-5d62-465f-9668-d70b3faafbfa.xml
index 1abe27d..5c7ef39 100644
--- a/tests/expected/suites_cite_post_2102a460-5d62-465f-9668-d70b3faafbfa.xml
+++ b/tests/expected/suites_cite_post_2102a460-5d62-465f-9668-d70b3faafbfa.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<csw:GetRecordsResponse xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ows="http://www.opengis.net/ows" xmlns:fgdc="http://www.opengis.net/cat/csw/csdg [...]
+<csw:GetRecordsResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.0.2" xsi:schemaLocation="http://www.opengis.net/cat/csw/2.0.2 http://schemas.opengis.net/csw/2.0.2/CSW-di [...]
   <csw:SearchStatus timestamp="PYCSW_TIMESTAMP"/>
   <csw:SearchResults nextRecord="0" numberOfRecordsMatched="1" numberOfRecordsReturned="1" recordSchema="http://www.opengis.net/cat/csw/2.0.2" elementSet="brief">
     <csw:BriefRecord>
diff --git a/tests/expected/suites_cite_post_225f455a-0035-486b-a94e-fee7ae881b2b.xml b/tests/expected/suites_cite_post_225f455a-0035-486b-a94e-fee7ae881b2b.xml
index 357e058..a9d06ca 100644
--- a/tests/expected/suites_cite_post_225f455a-0035-486b-a94e-fee7ae881b2b.xml
+++ b/tests/expected/suites_cite_post_225f455a-0035-486b-a94e-fee7ae881b2b.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<csw:GetRecordsResponse xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ows="http://www.opengis.net/ows" xmlns:fgdc="http://www.opengis.net/cat/csw/csdg [...]
+<csw:GetRecordsResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.0.2" xsi:schemaLocation="http://www.opengis.net/cat/csw/2.0.2 http://schemas.opengis.net/csw/2.0.2/CSW-di [...]
   <csw:SearchStatus timestamp="PYCSW_TIMESTAMP"/>
   <csw:SearchResults nextRecord="0" numberOfRecordsMatched="2" numberOfRecordsReturned="2" recordSchema="http://www.opengis.net/cat/csw/2.0.2">
     <csw:Record>
diff --git a/tests/expected/suites_cite_post_2d53ffea-60e4-4652-abf5-36eb23042fd5.xml b/tests/expected/suites_cite_post_2d53ffea-60e4-4652-abf5-36eb23042fd5.xml
index 0f433b6..fb722ad 100644
--- a/tests/expected/suites_cite_post_2d53ffea-60e4-4652-abf5-36eb23042fd5.xml
+++ b/tests/expected/suites_cite_post_2d53ffea-60e4-4652-abf5-36eb23042fd5.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<csw:GetRecordsResponse xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ows="http://www.opengis.net/ows" xmlns:fgdc="http://www.opengis.net/cat/csw/csdg [...]
+<csw:GetRecordsResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.0.2" xsi:schemaLocation="http://www.opengis.net/cat/csw/2.0.2 http://schemas.opengis.net/csw/2.0.2/CSW-di [...]
   <csw:SearchStatus timestamp="PYCSW_TIMESTAMP"/>
   <csw:SearchResults nextRecord="11" numberOfRecordsMatched="12" numberOfRecordsReturned="10" recordSchema="http://www.opengis.net/cat/csw/2.0.2" elementSet="brief">
     <csw:BriefRecord>
diff --git a/tests/expected/suites_cite_post_34a019a9-1581-42cb-9827-fbfdda2773b7.xml b/tests/expected/suites_cite_post_34a019a9-1581-42cb-9827-fbfdda2773b7.xml
index 0a80553..a22dee0 100644
--- a/tests/expected/suites_cite_post_34a019a9-1581-42cb-9827-fbfdda2773b7.xml
+++ b/tests/expected/suites_cite_post_34a019a9-1581-42cb-9827-fbfdda2773b7.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<csw:GetRecordsResponse xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ows="http://www.opengis.net/ows" xmlns:fgdc="http://www.opengis.net/cat/csw/csdg [...]
+<csw:GetRecordsResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.0.2" xsi:schemaLocation="http://www.opengis.net/cat/csw/2.0.2 http://schemas.opengis.net/csw/2.0.2/CSW-di [...]
   <csw:SearchStatus timestamp="PYCSW_TIMESTAMP"/>
   <csw:SearchResults nextRecord="11" numberOfRecordsMatched="12" numberOfRecordsReturned="0" recordSchema="http://www.opengis.net/cat/csw/2.0.2" elementSet="brief"/>
 </csw:GetRecordsResponse>
diff --git a/tests/expected/suites_cite_post_3e76fd38-e035-41c9-83dc-61356f680c97.xml b/tests/expected/suites_cite_post_3e76fd38-e035-41c9-83dc-61356f680c97.xml
index cdf0856..c8ed32a 100644
--- a/tests/expected/suites_cite_post_3e76fd38-e035-41c9-83dc-61356f680c97.xml
+++ b/tests/expected/suites_cite_post_3e76fd38-e035-41c9-83dc-61356f680c97.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<ows:ExceptionReport xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ows="http://www.opengis.net/ows" xmlns:fgdc="http://www.opengis.net/cat/csw/csdgm"  [...]
+<ows:ExceptionReport xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" language="en-US" version="1.2.0" xsi:schemaLocation="http://www.opengis.net/ows http://schemas.opengis.net/ows/1.0.0/ow [...]
   <ows:Exception exceptionCode="InvalidParameterValue" locator="schemalanguage">
     <ows:ExceptionText>Invalid value for schemalanguage: http://purl.oclc.org/dsdl/schematron</ows:ExceptionText>
   </ows:Exception>
diff --git a/tests/expected/suites_cite_post_418a6fb0-a89c-4a94-afc9-3f8168eb2980.xml b/tests/expected/suites_cite_post_418a6fb0-a89c-4a94-afc9-3f8168eb2980.xml
index c3d4faf..a53001d 100644
--- a/tests/expected/suites_cite_post_418a6fb0-a89c-4a94-afc9-3f8168eb2980.xml
+++ b/tests/expected/suites_cite_post_418a6fb0-a89c-4a94-afc9-3f8168eb2980.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<csw:GetRecordsResponse xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ows="http://www.opengis.net/ows" xmlns:fgdc="http://www.opengis.net/cat/csw/csdg [...]
+<csw:GetRecordsResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.0.2" xsi:schemaLocation="http://www.opengis.net/cat/csw/2.0.2 http://schemas.opengis.net/csw/2.0.2/CSW-di [...]
   <csw:SearchStatus timestamp="PYCSW_TIMESTAMP"/>
   <csw:SearchResults nextRecord="0" numberOfRecordsMatched="1" numberOfRecordsReturned="1" recordSchema="http://www.opengis.net/cat/csw/2.0.2">
     <csw:Record>
diff --git a/tests/expected/suites_cite_post_420b745e-0c4b-404e-9f2d-61fa580ff05a.xml b/tests/expected/suites_cite_post_420b745e-0c4b-404e-9f2d-61fa580ff05a.xml
index f0a54b5..2509701 100644
--- a/tests/expected/suites_cite_post_420b745e-0c4b-404e-9f2d-61fa580ff05a.xml
+++ b/tests/expected/suites_cite_post_420b745e-0c4b-404e-9f2d-61fa580ff05a.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<csw:GetRecordsResponse xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ows="http://www.opengis.net/ows" xmlns:fgdc="http://www.opengis.net/cat/csw/csdg [...]
+<csw:GetRecordsResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.0.2" xsi:schemaLocation="http://www.opengis.net/cat/csw/2.0.2 http://schemas.opengis.net/csw/2.0.2/CSW-di [...]
   <csw:SearchStatus timestamp="PYCSW_TIMESTAMP"/>
   <csw:SearchResults nextRecord="0" numberOfRecordsMatched="3" numberOfRecordsReturned="3" recordSchema="http://www.opengis.net/cat/csw/2.0.2">
     <csw:Record>
diff --git a/tests/expected/suites_cite_post_4735d649-a2b1-42fd-a101-14e1d7e4607f.xml b/tests/expected/suites_cite_post_4735d649-a2b1-42fd-a101-14e1d7e4607f.xml
index c2180b4..a707067 100644
--- a/tests/expected/suites_cite_post_4735d649-a2b1-42fd-a101-14e1d7e4607f.xml
+++ b/tests/expected/suites_cite_post_4735d649-a2b1-42fd-a101-14e1d7e4607f.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<csw:GetRecordsResponse xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ows="http://www.opengis.net/ows" xmlns:fgdc="http://www.opengis.net/cat/csw/csdg [...]
+<csw:GetRecordsResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.0.2" xsi:schemaLocation="http://www.opengis.net/cat/csw/2.0.2 http://schemas.opengis.net/csw/2.0.2/CSW-di [...]
   <csw:SearchStatus timestamp="PYCSW_TIMESTAMP"/>
   <csw:SearchResults nextRecord="8" numberOfRecordsMatched="12" numberOfRecordsReturned="5" recordSchema="http://www.opengis.net/cat/csw/2.0.2" elementSet="summary">
     <csw:SummaryRecord>
diff --git a/tests/expected/suites_cite_post_5c5861bc-f742-40a5-9998-5342615d674b.xml b/tests/expected/suites_cite_post_5c5861bc-f742-40a5-9998-5342615d674b.xml
index d99a831..7d1cd62 100644
--- a/tests/expected/suites_cite_post_5c5861bc-f742-40a5-9998-5342615d674b.xml
+++ b/tests/expected/suites_cite_post_5c5861bc-f742-40a5-9998-5342615d674b.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<csw:GetRecordsResponse xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ows="http://www.opengis.net/ows" xmlns:fgdc="http://www.opengis.net/cat/csw/csdg [...]
+<csw:GetRecordsResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.0.2" xsi:schemaLocation="http://www.opengis.net/cat/csw/2.0.2 http://schemas.opengis.net/csw/2.0.2/CSW-di [...]
   <csw:SearchStatus timestamp="PYCSW_TIMESTAMP"/>
   <csw:SearchResults nextRecord="0" numberOfRecordsMatched="5" numberOfRecordsReturned="5" recordSchema="http://www.opengis.net/cat/csw/2.0.2" elementSet="full">
     <csw:Record>
diff --git a/tests/expected/suites_cite_post_6e736fd0-c266-4852-9eb3-0656f5d0f5c4.xml b/tests/expected/suites_cite_post_6e736fd0-c266-4852-9eb3-0656f5d0f5c4.xml
index f704008..e96a023 100644
--- a/tests/expected/suites_cite_post_6e736fd0-c266-4852-9eb3-0656f5d0f5c4.xml
+++ b/tests/expected/suites_cite_post_6e736fd0-c266-4852-9eb3-0656f5d0f5c4.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<csw:GetRecordsResponse xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ows="http://www.opengis.net/ows" xmlns:fgdc="http://www.opengis.net/cat/csw/csdg [...]
+<csw:GetRecordsResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.0.2" xsi:schemaLocation="http://www.opengis.net/cat/csw/2.0.2 http://schemas.opengis.net/csw/2.0.2/CSW-di [...]
   <csw:SearchStatus timestamp="PYCSW_TIMESTAMP"/>
   <csw:SearchResults nextRecord="11" numberOfRecordsMatched="12" numberOfRecordsReturned="10" recordSchema="http://www.opengis.net/cat/csw/2.0.2" elementSet="summary">
     <csw:SummaryRecord>
diff --git a/tests/expected/suites_cite_post_73f1551c-e269-4ef9-9dae-e535b5eebfc7.xml b/tests/expected/suites_cite_post_73f1551c-e269-4ef9-9dae-e535b5eebfc7.xml
index 878206b..4060ee2 100644
--- a/tests/expected/suites_cite_post_73f1551c-e269-4ef9-9dae-e535b5eebfc7.xml
+++ b/tests/expected/suites_cite_post_73f1551c-e269-4ef9-9dae-e535b5eebfc7.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<csw:GetRecordsResponse xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ows="http://www.opengis.net/ows" xmlns:fgdc="http://www.opengis.net/cat/csw/csdg [...]
+<csw:GetRecordsResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.0.2" xsi:schemaLocation="http://www.opengis.net/cat/csw/2.0.2 http://schemas.opengis.net/csw/2.0.2/CSW-di [...]
   <csw:SearchStatus timestamp="PYCSW_TIMESTAMP"/>
   <csw:SearchResults nextRecord="0" numberOfRecordsMatched="1" numberOfRecordsReturned="1" recordSchema="http://www.opengis.net/cat/csw/2.0.2" elementSet="full">
     <csw:Record>
diff --git a/tests/expected/suites_cite_post_78297c88-4850-4927-adc6-511cd9a3d539.xml b/tests/expected/suites_cite_post_78297c88-4850-4927-adc6-511cd9a3d539.xml
index 7ee77c7..76101a6 100644
--- a/tests/expected/suites_cite_post_78297c88-4850-4927-adc6-511cd9a3d539.xml
+++ b/tests/expected/suites_cite_post_78297c88-4850-4927-adc6-511cd9a3d539.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<csw:DescribeRecordResponse xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ows="http://www.opengis.net/ows" xmlns:fgdc="http://www.opengis.net/cat/csw/ [...]
+<csw:DescribeRecordResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/cat/csw/2.0.2 http://schemas.opengis.net/csw/2.0.2/CSW-discovery.xsd">
   <csw:SchemaComponent schemaLanguage="XMLSCHEMA" targetNamespace="http://www.opengis.net/cat/csw/2.0.2">
     <xs:schema id="csw-record" targetNamespace="http://www.opengis.net/cat/csw/2.0.2" elementFormDefault="qualified" version="2.0.2 2010-01-22">
    <xs:annotation>
diff --git a/tests/expected/suites_cite_post_7c89cdf5-0def-4cfb-8c55-2b8ffea5d92f.xml b/tests/expected/suites_cite_post_7c89cdf5-0def-4cfb-8c55-2b8ffea5d92f.xml
index 8adbb25..4d9e1fd 100644
--- a/tests/expected/suites_cite_post_7c89cdf5-0def-4cfb-8c55-2b8ffea5d92f.xml
+++ b/tests/expected/suites_cite_post_7c89cdf5-0def-4cfb-8c55-2b8ffea5d92f.xml
@@ -1,48 +1,56 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<csw:GetRecordsResponse xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ows="http://www.opengis.net/ows" xmlns:fgdc="http://www.opengis.net/cat/csw/csdg [...]
+<csw:GetRecordsResponse xmlns:atom="http://www.w3.org/2005/Atom" xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.0.2" xsi:schemaLocation="http://www.opengis.net/cat/csw/2.0.2 ht [...]
   <csw:SearchStatus timestamp="PYCSW_TIMESTAMP"/>
   <csw:SearchResults nextRecord="6" numberOfRecordsMatched="12" numberOfRecordsReturned="5" recordSchema="http://www.w3.org/2005/Atom" elementSet="summary">
-    <atom:entry xmlns:georss="http://www.georss.org/georss" xsi:schemaLocation="http://www.w3.org/2005/Atom http://www.kbcafe.com/rss/atom.xsd.xml">
-      <atom:category>Tourism--Greece</atom:category>
+    <atom:entry xsi:schemaLocation="http://www.w3.org/2005/Atom http://www.kbcafe.com/rss/atom.xsd.xml">
+      <atom:category term="Tourism--Greece"/>
       <atom:id>urn:uuid:19887a8a-f6b0-4a63-ae56-7fba0e17801f</atom:id>
+      <dc:identifier>urn:uuid:19887a8a-f6b0-4a63-ae56-7fba0e17801f</dc:identifier>
       <atom:link href="http://localhost/pycsw/csw.py?config=tests/suites/cite/default.cfg?service=CSW&version=2.0.2&request=GetRepositoryItem&id=urn:uuid:19887a8a-f6b0-4a63-ae56-7fba0e17801f"/>
-      <atom:summary>Quisque lacus diam, placerat mollis, pharetra in, commodo sed, augue. Duis iaculis arcu vel arcu.</atom:summary>
       <atom:title>Lorem ipsum</atom:title>
+      <atom:updated>PYCSW_TIMESTAMP</atom:updated>
+      <atom:summary>Quisque lacus diam, placerat mollis, pharetra in, commodo sed, augue. Duis iaculis arcu vel arcu.</atom:summary>
     </atom:entry>
     <atom:entry xmlns:georss="http://www.georss.org/georss" xsi:schemaLocation="http://www.w3.org/2005/Atom http://www.kbcafe.com/rss/atom.xsd.xml">
       <atom:id>urn:uuid:1ef30a8b-876d-4828-9246-c37ab4510bbd</atom:id>
+      <dc:identifier>urn:uuid:1ef30a8b-876d-4828-9246-c37ab4510bbd</dc:identifier>
       <atom:link href="http://localhost/pycsw/csw.py?config=tests/suites/cite/default.cfg?service=CSW&version=2.0.2&request=GetRepositoryItem&id=urn:uuid:1ef30a8b-876d-4828-9246-c37ab4510bbd"/>
+      <atom:title/>
+      <atom:updated>PYCSW_TIMESTAMP</atom:updated>
       <atom:summary>Proin sit amet justo. In justo. Aenean adipiscing nulla id tellus.</atom:summary>
       <georss:where>
-        <gml:Polygon srsName="urn:x-ogc:def:crs:EPSG:6.11:4326">
-          <gml:exterior>
-            <gml:LinearRing>
-              <gml:posList>60.04 13.75 68.41 13.75 68.41 17.92 60.04 17.92 60.04 13.75</gml:posList>
-            </gml:LinearRing>
-          </gml:exterior>
-        </gml:Polygon>
+        <gml:Envelope srsName="http://www.opengis.net/def/crs/EPSG/0/4326">
+          <gml:lowerCorner>60.04 13.75</gml:lowerCorner>
+          <gml:upperCorner>68.41 17.92</gml:upperCorner>
+        </gml:Envelope>
       </georss:where>
     </atom:entry>
-    <atom:entry xmlns:georss="http://www.georss.org/georss" xsi:schemaLocation="http://www.w3.org/2005/Atom http://www.kbcafe.com/rss/atom.xsd.xml">
-      <atom:category>Marine sediments</atom:category>
+    <atom:entry xsi:schemaLocation="http://www.w3.org/2005/Atom http://www.kbcafe.com/rss/atom.xsd.xml">
+      <atom:category term="Marine sediments"/>
       <atom:id>urn:uuid:66ae76b7-54ba-489b-a582-0f0633d96493</atom:id>
+      <dc:identifier>urn:uuid:66ae76b7-54ba-489b-a582-0f0633d96493</dc:identifier>
       <atom:link href="http://localhost/pycsw/csw.py?config=tests/suites/cite/default.cfg?service=CSW&version=2.0.2&request=GetRepositoryItem&id=urn:uuid:66ae76b7-54ba-489b-a582-0f0633d96493"/>
-      <atom:summary>Pellentesque tempus magna non sapien fringilla blandit.</atom:summary>
       <atom:title>Maecenas enim</atom:title>
+      <atom:updated>PYCSW_TIMESTAMP</atom:updated>
+      <atom:summary>Pellentesque tempus magna non sapien fringilla blandit.</atom:summary>
     </atom:entry>
-    <atom:entry xmlns:georss="http://www.georss.org/georss" xsi:schemaLocation="http://www.w3.org/2005/Atom http://www.kbcafe.com/rss/atom.xsd.xml">
-      <atom:category>Vegetation</atom:category>
+    <atom:entry xsi:schemaLocation="http://www.w3.org/2005/Atom http://www.kbcafe.com/rss/atom.xsd.xml">
+      <atom:category term="Vegetation"/>
       <atom:id>urn:uuid:6a3de50b-fa66-4b58-a0e6-ca146fdd18d4</atom:id>
+      <dc:identifier>urn:uuid:6a3de50b-fa66-4b58-a0e6-ca146fdd18d4</dc:identifier>
       <atom:link href="http://localhost/pycsw/csw.py?config=tests/suites/cite/default.cfg?service=CSW&version=2.0.2&request=GetRepositoryItem&id=urn:uuid:6a3de50b-fa66-4b58-a0e6-ca146fdd18d4"/>
       <atom:title>Ut facilisis justo ut lacus</atom:title>
+      <atom:updated>PYCSW_TIMESTAMP</atom:updated>
     </atom:entry>
-    <atom:entry xmlns:georss="http://www.georss.org/georss" xsi:schemaLocation="http://www.w3.org/2005/Atom http://www.kbcafe.com/rss/atom.xsd.xml">
-      <atom:category>Hydrography--Dictionaries</atom:category>
+    <atom:entry xsi:schemaLocation="http://www.w3.org/2005/Atom http://www.kbcafe.com/rss/atom.xsd.xml">
+      <atom:category term="Hydrography--Dictionaries"/>
       <atom:id>urn:uuid:784e2afd-a9fd-44a6-9a92-a3848371c8ec</atom:id>
+      <dc:identifier>urn:uuid:784e2afd-a9fd-44a6-9a92-a3848371c8ec</dc:identifier>
       <atom:link href="http://localhost/pycsw/csw.py?config=tests/suites/cite/default.cfg?service=CSW&version=2.0.2&request=GetRepositoryItem&id=urn:uuid:784e2afd-a9fd-44a6-9a92-a3848371c8ec"/>
-      <atom:summary>Vestibulum quis ipsum sit amet metus imperdiet vehicula. Nulla scelerisque cursus mi.</atom:summary>
       <atom:title>Aliquam fermentum purus quis arcu</atom:title>
+      <atom:updated>PYCSW_TIMESTAMP</atom:updated>
+      <atom:summary>Vestibulum quis ipsum sit amet metus imperdiet vehicula. Nulla scelerisque cursus mi.</atom:summary>
     </atom:entry>
   </csw:SearchResults>
 </csw:GetRecordsResponse>
diff --git a/tests/expected/suites_cite_post_7e2cd105-daec-4d25-bc8e-d49d21364912.xml b/tests/expected/suites_cite_post_7e2cd105-daec-4d25-bc8e-d49d21364912.xml
index 04284a4..5f82a7d 100644
--- a/tests/expected/suites_cite_post_7e2cd105-daec-4d25-bc8e-d49d21364912.xml
+++ b/tests/expected/suites_cite_post_7e2cd105-daec-4d25-bc8e-d49d21364912.xml
@@ -1,3 +1,3 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<csw:DescribeRecordResponse xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ows="http://www.opengis.net/ows" xmlns:fgdc="http://www.opengis.net/cat/csw/ [...]
+<csw:DescribeRecordResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/cat/csw/2.0.2 http://schemas.opengis.net/csw/2.0.2/CSW-discovery.xsd"/>
diff --git a/tests/expected/suites_cite_post_87f2f670-9cd6-4907-b82c-1b46a7dd2a78.xml b/tests/expected/suites_cite_post_87f2f670-9cd6-4907-b82c-1b46a7dd2a78.xml
index d42e882..d81b549 100644
--- a/tests/expected/suites_cite_post_87f2f670-9cd6-4907-b82c-1b46a7dd2a78.xml
+++ b/tests/expected/suites_cite_post_87f2f670-9cd6-4907-b82c-1b46a7dd2a78.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<csw:GetRecordsResponse xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ows="http://www.opengis.net/ows" xmlns:fgdc="http://www.opengis.net/cat/csw/csdg [...]
+<csw:GetRecordsResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.0.2" xsi:schemaLocation="http://www.opengis.net/cat/csw/2.0.2 http://schemas.opengis.net/csw/2.0.2/CSW-di [...]
   <csw:SearchStatus timestamp="PYCSW_TIMESTAMP"/>
   <csw:SearchResults nextRecord="11" numberOfRecordsMatched="12" numberOfRecordsReturned="10" recordSchema="http://www.opengis.net/cat/csw/2.0.2">
     <csw:Record>
diff --git a/tests/expected/suites_cite_post_88b4e1ba-3bd4-4cbe-81e5-e004056d6ca3.xml b/tests/expected/suites_cite_post_88b4e1ba-3bd4-4cbe-81e5-e004056d6ca3.xml
index ace747b..ef7576e 100644
--- a/tests/expected/suites_cite_post_88b4e1ba-3bd4-4cbe-81e5-e004056d6ca3.xml
+++ b/tests/expected/suites_cite_post_88b4e1ba-3bd4-4cbe-81e5-e004056d6ca3.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<ows:ExceptionReport xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ows="http://www.opengis.net/ows" xmlns:fgdc="http://www.opengis.net/cat/csw/csdgm"  [...]
+<ows:ExceptionReport xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" language="en-US" version="1.2.0" xsi:schemaLocation="http://www.opengis.net/ows http://schemas.opengis.net/ows/1.0.0/ow [...]
   <ows:Exception exceptionCode="InvalidParameterValue" locator="outputformat">
     <ows:ExceptionText>Invalid value for outputformat: text/sgml</ows:ExceptionText>
   </ows:Exception>
diff --git a/tests/expected/suites_cite_post_898cd63b-2585-4ec0-8720-d554bd324174.xml b/tests/expected/suites_cite_post_898cd63b-2585-4ec0-8720-d554bd324174.xml
index 945dd21..f77acfc 100644
--- a/tests/expected/suites_cite_post_898cd63b-2585-4ec0-8720-d554bd324174.xml
+++ b/tests/expected/suites_cite_post_898cd63b-2585-4ec0-8720-d554bd324174.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<csw:GetRecordsResponse xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ows="http://www.opengis.net/ows" xmlns:fgdc="http://www.opengis.net/cat/csw/csdg [...]
+<csw:GetRecordsResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.0.2" xsi:schemaLocation="http://www.opengis.net/cat/csw/2.0.2 http://schemas.opengis.net/csw/2.0.2/CSW-di [...]
   <csw:SearchStatus timestamp="PYCSW_TIMESTAMP"/>
   <csw:SearchResults nextRecord="0" numberOfRecordsMatched="1" numberOfRecordsReturned="1" recordSchema="http://www.opengis.net/cat/csw/2.0.2" elementSet="summary">
     <csw:SummaryRecord>
diff --git a/tests/expected/suites_cite_post_8fb13dc3-5818-45e2-9e29-46abc16e7d38.xml b/tests/expected/suites_cite_post_8fb13dc3-5818-45e2-9e29-46abc16e7d38.xml
index eed52f8..9c08c60 100644
--- a/tests/expected/suites_cite_post_8fb13dc3-5818-45e2-9e29-46abc16e7d38.xml
+++ b/tests/expected/suites_cite_post_8fb13dc3-5818-45e2-9e29-46abc16e7d38.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<csw:GetRecordsResponse xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ows="http://www.opengis.net/ows" xmlns:fgdc="http://www.opengis.net/cat/csw/csdg [...]
+<csw:GetRecordsResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.0.2" xsi:schemaLocation="http://www.opengis.net/cat/csw/2.0.2 http://schemas.opengis.net/csw/2.0.2/CSW-di [...]
   <csw:SearchStatus timestamp="PYCSW_TIMESTAMP"/>
   <csw:SearchResults nextRecord="0" numberOfRecordsMatched="11" numberOfRecordsReturned="11" recordSchema="http://www.opengis.net/cat/csw/2.0.2">
     <csw:Record>
diff --git a/tests/expected/suites_cite_post_928c1896-52d4-4ac7-9832-f98e3eb65f02.xml b/tests/expected/suites_cite_post_928c1896-52d4-4ac7-9832-f98e3eb65f02.xml
index db055c9..baf37aa 100644
--- a/tests/expected/suites_cite_post_928c1896-52d4-4ac7-9832-f98e3eb65f02.xml
+++ b/tests/expected/suites_cite_post_928c1896-52d4-4ac7-9832-f98e3eb65f02.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<csw:GetRecordsResponse xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ows="http://www.opengis.net/ows" xmlns:fgdc="http://www.opengis.net/cat/csw/csdg [...]
+<csw:GetRecordsResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.0.2" xsi:schemaLocation="http://www.opengis.net/cat/csw/2.0.2 http://schemas.opengis.net/csw/2.0.2/CSW-di [...]
   <csw:SearchStatus timestamp="PYCSW_TIMESTAMP"/>
   <csw:SearchResults nextRecord="0" numberOfRecordsMatched="2" numberOfRecordsReturned="2" recordSchema="http://www.opengis.net/cat/csw/2.0.2">
     <csw:Record>
diff --git a/tests/expected/suites_cite_post_93bdbb9d-2734-4f01-92fb-48634cca41de.xml b/tests/expected/suites_cite_post_93bdbb9d-2734-4f01-92fb-48634cca41de.xml
index 9212c38..9a5d49e 100644
--- a/tests/expected/suites_cite_post_93bdbb9d-2734-4f01-92fb-48634cca41de.xml
+++ b/tests/expected/suites_cite_post_93bdbb9d-2734-4f01-92fb-48634cca41de.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<csw:GetRecordsResponse xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ows="http://www.opengis.net/ows" xmlns:fgdc="http://www.opengis.net/cat/csw/csdg [...]
+<csw:GetRecordsResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.0.2" xsi:schemaLocation="http://www.opengis.net/cat/csw/2.0.2 http://schemas.opengis.net/csw/2.0.2/CSW-di [...]
   <csw:SearchStatus timestamp="PYCSW_TIMESTAMP"/>
   <csw:SearchResults nextRecord="0" numberOfRecordsMatched="2" numberOfRecordsReturned="2" recordSchema="http://www.opengis.net/cat/csw/2.0.2">
     <csw:Record>
diff --git a/tests/expected/suites_cite_post_948b39d5-bb4f-45b8-a8f2-4ff9501aaedd.xml b/tests/expected/suites_cite_post_948b39d5-bb4f-45b8-a8f2-4ff9501aaedd.xml
index e2faa4c..b214975 100644
--- a/tests/expected/suites_cite_post_948b39d5-bb4f-45b8-a8f2-4ff9501aaedd.xml
+++ b/tests/expected/suites_cite_post_948b39d5-bb4f-45b8-a8f2-4ff9501aaedd.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<csw:GetRecordsResponse xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ows="http://www.opengis.net/ows" xmlns:fgdc="http://www.opengis.net/cat/csw/csdg [...]
+<csw:GetRecordsResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.0.2" xsi:schemaLocation="http://www.opengis.net/cat/csw/2.0.2 http://schemas.opengis.net/csw/2.0.2/CSW-di [...]
   <csw:SearchStatus timestamp="PYCSW_TIMESTAMP"/>
   <csw:SearchResults nextRecord="11" numberOfRecordsMatched="12" numberOfRecordsReturned="10" recordSchema="http://www.opengis.net/cat/csw/2.0.2">
     <csw:Record>
diff --git a/tests/expected/suites_cite_post_9fd64fcc-f69c-4626-b72e-5c7776a29aa9.xml b/tests/expected/suites_cite_post_9fd64fcc-f69c-4626-b72e-5c7776a29aa9.xml
index a4a8a5e..214379d 100644
--- a/tests/expected/suites_cite_post_9fd64fcc-f69c-4626-b72e-5c7776a29aa9.xml
+++ b/tests/expected/suites_cite_post_9fd64fcc-f69c-4626-b72e-5c7776a29aa9.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<ows:ExceptionReport xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ows="http://www.opengis.net/ows" xmlns:fgdc="http://www.opengis.net/cat/csw/csdgm"  [...]
+<ows:ExceptionReport xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" language="en-US" version="1.2.0" xsi:schemaLocation="http://www.opengis.net/ows http://schemas.opengis.net/ows/1.0.0/ow [...]
   <ows:Exception exceptionCode="InvalidParameterValue" locator="typename">
     <ows:ExceptionText>Typename not qualified: Record</ows:ExceptionText>
   </ows:Exception>
diff --git a/tests/expected/suites_cite_post_a06d04ab-e0d0-4a86-bfe8-71460f41fe37.xml b/tests/expected/suites_cite_post_a06d04ab-e0d0-4a86-bfe8-71460f41fe37.xml
index 0f433b6..fb722ad 100644
--- a/tests/expected/suites_cite_post_a06d04ab-e0d0-4a86-bfe8-71460f41fe37.xml
+++ b/tests/expected/suites_cite_post_a06d04ab-e0d0-4a86-bfe8-71460f41fe37.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<csw:GetRecordsResponse xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ows="http://www.opengis.net/ows" xmlns:fgdc="http://www.opengis.net/cat/csw/csdg [...]
+<csw:GetRecordsResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.0.2" xsi:schemaLocation="http://www.opengis.net/cat/csw/2.0.2 http://schemas.opengis.net/csw/2.0.2/CSW-di [...]
   <csw:SearchStatus timestamp="PYCSW_TIMESTAMP"/>
   <csw:SearchResults nextRecord="11" numberOfRecordsMatched="12" numberOfRecordsReturned="10" recordSchema="http://www.opengis.net/cat/csw/2.0.2" elementSet="brief">
     <csw:BriefRecord>
diff --git a/tests/expected/suites_cite_post_ad61686c-d304-42d1-b845-8c1f3070c83e.xml b/tests/expected/suites_cite_post_ad61686c-d304-42d1-b845-8c1f3070c83e.xml
index 1585217..71d14fa 100644
--- a/tests/expected/suites_cite_post_ad61686c-d304-42d1-b845-8c1f3070c83e.xml
+++ b/tests/expected/suites_cite_post_ad61686c-d304-42d1-b845-8c1f3070c83e.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<ows:ExceptionReport xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ows="http://www.opengis.net/ows" xmlns:fgdc="http://www.opengis.net/cat/csw/csdgm"  [...]
+<ows:ExceptionReport xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" language="en-US" version="1.2.0" xsi:schemaLocation="http://www.opengis.net/ows http://schemas.opengis.net/ows/1.0.0/ow [...]
   <ows:Exception exceptionCode="NoApplicableCode" locator="service">
     <ows:ExceptionText>Exception: the document is not valid.
 Error: Element '{http://www.opengis.net/foo}Filter': This element is not expected. Expected is one of ( {http://www.opengis.net/ogc}Filter, {http://www.opengis.net/cat/csw/2.0.2}CqlText ).</ows:ExceptionText>
diff --git a/tests/expected/suites_cite_post_af39c020-7b1d-429c-b474-f45c3164cb79.xml b/tests/expected/suites_cite_post_af39c020-7b1d-429c-b474-f45c3164cb79.xml
index 3ea1e55..960d5f5 100644
--- a/tests/expected/suites_cite_post_af39c020-7b1d-429c-b474-f45c3164cb79.xml
+++ b/tests/expected/suites_cite_post_af39c020-7b1d-429c-b474-f45c3164cb79.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<csw:GetRecordsResponse xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ows="http://www.opengis.net/ows" xmlns:fgdc="http://www.opengis.net/cat/csw/csdg [...]
+<csw:GetRecordsResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.0.2" xsi:schemaLocation="http://www.opengis.net/cat/csw/2.0.2 http://schemas.opengis.net/csw/2.0.2/CSW-di [...]
   <csw:SearchStatus timestamp="PYCSW_TIMESTAMP"/>
   <csw:SearchResults nextRecord="0" numberOfRecordsMatched="2" numberOfRecordsReturned="2" recordSchema="http://www.opengis.net/cat/csw/2.0.2" elementSet="summary">
     <csw:SummaryRecord>
diff --git a/tests/expected/suites_cite_post_b90e2de6-3d25-4298-a13e-dc9492a8fc73.xml b/tests/expected/suites_cite_post_b90e2de6-3d25-4298-a13e-dc9492a8fc73.xml
index ef6ded2..0c5581f 100644
--- a/tests/expected/suites_cite_post_b90e2de6-3d25-4298-a13e-dc9492a8fc73.xml
+++ b/tests/expected/suites_cite_post_b90e2de6-3d25-4298-a13e-dc9492a8fc73.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<csw:GetRecordsResponse xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ows="http://www.opengis.net/ows" xmlns:fgdc="http://www.opengis.net/cat/csw/csdg [...]
+<csw:GetRecordsResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.0.2" xsi:schemaLocation="http://www.opengis.net/cat/csw/2.0.2 http://schemas.opengis.net/csw/2.0.2/CSW-di [...]
   <csw:SearchStatus timestamp="PYCSW_TIMESTAMP"/>
   <csw:SearchResults nextRecord="0" numberOfRecordsMatched="10" numberOfRecordsReturned="10" recordSchema="http://www.opengis.net/cat/csw/2.0.2" elementSet="summary">
     <csw:SummaryRecord>
diff --git a/tests/expected/suites_cite_post_ba9b0107-dcee-46ef-823a-a2e25a911a96.xml b/tests/expected/suites_cite_post_ba9b0107-dcee-46ef-823a-a2e25a911a96.xml
index 0b769a8..98e2c78 100644
--- a/tests/expected/suites_cite_post_ba9b0107-dcee-46ef-823a-a2e25a911a96.xml
+++ b/tests/expected/suites_cite_post_ba9b0107-dcee-46ef-823a-a2e25a911a96.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<csw:GetRecordsResponse xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ows="http://www.opengis.net/ows" xmlns:fgdc="http://www.opengis.net/cat/csw/csdg [...]
+<csw:GetRecordsResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.0.2" xsi:schemaLocation="http://www.opengis.net/cat/csw/2.0.2 http://schemas.opengis.net/csw/2.0.2/CSW-di [...]
   <csw:SearchStatus timestamp="PYCSW_TIMESTAMP"/>
   <csw:SearchResults nextRecord="0" numberOfRecordsMatched="4" numberOfRecordsReturned="4" recordSchema="http://www.opengis.net/cat/csw/2.0.2" elementSet="summary">
     <csw:SummaryRecord>
diff --git a/tests/expected/suites_cite_post_bb66ebc5-7121-48b5-9f53-b56537d9561b.xml b/tests/expected/suites_cite_post_bb66ebc5-7121-48b5-9f53-b56537d9561b.xml
index 01e95f5..0a392cb 100644
--- a/tests/expected/suites_cite_post_bb66ebc5-7121-48b5-9f53-b56537d9561b.xml
+++ b/tests/expected/suites_cite_post_bb66ebc5-7121-48b5-9f53-b56537d9561b.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<csw:GetRecordsResponse xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ows="http://www.opengis.net/ows" xmlns:fgdc="http://www.opengis.net/cat/csw/csdg [...]
+<csw:GetRecordsResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.0.2" xsi:schemaLocation="http://www.opengis.net/cat/csw/2.0.2 http://schemas.opengis.net/csw/2.0.2/CSW-di [...]
   <csw:SearchStatus timestamp="PYCSW_TIMESTAMP"/>
   <csw:SearchResults nextRecord="0" numberOfRecordsMatched="2" numberOfRecordsReturned="2" recordSchema="http://www.opengis.net/cat/csw/2.0.2">
     <csw:Record>
diff --git a/tests/expected/suites_cite_post_c02d1c85-df9f-45ee-bea7-345c35e02a98.xml b/tests/expected/suites_cite_post_c02d1c85-df9f-45ee-bea7-345c35e02a98.xml
index da4f933..26bfbf2 100644
--- a/tests/expected/suites_cite_post_c02d1c85-df9f-45ee-bea7-345c35e02a98.xml
+++ b/tests/expected/suites_cite_post_c02d1c85-df9f-45ee-bea7-345c35e02a98.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<ows:ExceptionReport xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ows="http://www.opengis.net/ows" xmlns:fgdc="http://www.opengis.net/cat/csw/csdgm"  [...]
+<ows:ExceptionReport xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" language="en-US" version="1.2.0" xsi:schemaLocation="http://www.opengis.net/ows http://schemas.opengis.net/ows/1.0.0/ow [...]
   <ows:Exception exceptionCode="InvalidParameterValue" locator="service">
     <ows:ExceptionText>Invalid Constraint: Invalid Filter request: 'NoneType' object has no attribute 'text'</ows:ExceptionText>
   </ows:Exception>
diff --git a/tests/expected/suites_cite_post_c311a342-72e3-4983-be39-868e6ed9740f.xml b/tests/expected/suites_cite_post_c311a342-72e3-4983-be39-868e6ed9740f.xml
index 7ee77c7..76101a6 100644
--- a/tests/expected/suites_cite_post_c311a342-72e3-4983-be39-868e6ed9740f.xml
+++ b/tests/expected/suites_cite_post_c311a342-72e3-4983-be39-868e6ed9740f.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<csw:DescribeRecordResponse xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ows="http://www.opengis.net/ows" xmlns:fgdc="http://www.opengis.net/cat/csw/ [...]
+<csw:DescribeRecordResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/cat/csw/2.0.2 http://schemas.opengis.net/csw/2.0.2/CSW-discovery.xsd">
   <csw:SchemaComponent schemaLanguage="XMLSCHEMA" targetNamespace="http://www.opengis.net/cat/csw/2.0.2">
     <xs:schema id="csw-record" targetNamespace="http://www.opengis.net/cat/csw/2.0.2" elementFormDefault="qualified" version="2.0.2 2010-01-22">
    <xs:annotation>
diff --git a/tests/expected/suites_cite_post_c38916c2-4bc6-446d-b7aa-ab006d6ba31c.xml b/tests/expected/suites_cite_post_c38916c2-4bc6-446d-b7aa-ab006d6ba31c.xml
index 4f6e4af..d9c18a0 100644
--- a/tests/expected/suites_cite_post_c38916c2-4bc6-446d-b7aa-ab006d6ba31c.xml
+++ b/tests/expected/suites_cite_post_c38916c2-4bc6-446d-b7aa-ab006d6ba31c.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<csw:GetRecordsResponse xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ows="http://www.opengis.net/ows" xmlns:fgdc="http://www.opengis.net/cat/csw/csdg [...]
+<csw:GetRecordsResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.0.2" xsi:schemaLocation="http://www.opengis.net/cat/csw/2.0.2 http://schemas.opengis.net/csw/2.0.2/CSW-di [...]
   <csw:SearchStatus timestamp="PYCSW_TIMESTAMP"/>
   <csw:SearchResults nextRecord="0" numberOfRecordsMatched="3" numberOfRecordsReturned="3" recordSchema="http://www.opengis.net/cat/csw/2.0.2">
     <csw:Record>
diff --git a/tests/expected/suites_cite_post_c8588f47-8e65-45f5-ad34-ff4524cad84d.xml b/tests/expected/suites_cite_post_c8588f47-8e65-45f5-ad34-ff4524cad84d.xml
index 8f3d3dc..12342af 100644
--- a/tests/expected/suites_cite_post_c8588f47-8e65-45f5-ad34-ff4524cad84d.xml
+++ b/tests/expected/suites_cite_post_c8588f47-8e65-45f5-ad34-ff4524cad84d.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<ows:ExceptionReport xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ows="http://www.opengis.net/ows" xmlns:fgdc="http://www.opengis.net/cat/csw/csdgm"  [...]
+<ows:ExceptionReport xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" language="en-US" version="1.2.0" xsi:schemaLocation="http://www.opengis.net/ows http://schemas.opengis.net/ows/1.0.0/ow [...]
   <ows:Exception exceptionCode="InvalidParameterValue" locator="service">
     <ows:ExceptionText>Invalid Constraint: Invalid Filter request: Invalid ogc:PropertyName in spatial filter: dct:spatial</ows:ExceptionText>
   </ows:Exception>
diff --git a/tests/expected/suites_cite_post_da228d4c-e1be-43d7-9ccb-c3f27ee32541.xml b/tests/expected/suites_cite_post_da228d4c-e1be-43d7-9ccb-c3f27ee32541.xml
index d68fd69..2b0eebe 100644
--- a/tests/expected/suites_cite_post_da228d4c-e1be-43d7-9ccb-c3f27ee32541.xml
+++ b/tests/expected/suites_cite_post_da228d4c-e1be-43d7-9ccb-c3f27ee32541.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<ows:ExceptionReport xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ows="http://www.opengis.net/ows" xmlns:fgdc="http://www.opengis.net/cat/csw/csdgm"  [...]
+<ows:ExceptionReport xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" language="en-US" version="1.2.0" xsi:schemaLocation="http://www.opengis.net/ows http://schemas.opengis.net/ows/1.0.0/ow [...]
   <ows:Exception exceptionCode="InvalidParameterValue" locator="service">
     <ows:ExceptionText>Invalid Constraint: Invalid Filter request: Invalid PropertyName: /dc:title.  '/dc:title'</ows:ExceptionText>
   </ows:Exception>
diff --git a/tests/expected/suites_cite_post_dc92c2c4-87d8-4a13-964e-ff9b0e0c27b3.xml b/tests/expected/suites_cite_post_dc92c2c4-87d8-4a13-964e-ff9b0e0c27b3.xml
index 1135a17..371b26a 100644
--- a/tests/expected/suites_cite_post_dc92c2c4-87d8-4a13-964e-ff9b0e0c27b3.xml
+++ b/tests/expected/suites_cite_post_dc92c2c4-87d8-4a13-964e-ff9b0e0c27b3.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<csw:GetRecordsResponse xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ows="http://www.opengis.net/ows" xmlns:fgdc="http://www.opengis.net/cat/csw/csdg [...]
+<csw:GetRecordsResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.0.2" xsi:schemaLocation="http://www.opengis.net/cat/csw/2.0.2 http://schemas.opengis.net/csw/2.0.2/CSW-di [...]
   <csw:SearchStatus timestamp="PYCSW_TIMESTAMP"/>
   <csw:SearchResults nextRecord="0" numberOfRecordsMatched="3" numberOfRecordsReturned="3" recordSchema="http://www.opengis.net/cat/csw/2.0.2">
     <csw:Record>
diff --git a/tests/expected/suites_cite_post_dcb13791-379e-4739-bcd4-dbaa69f0efdb.xml b/tests/expected/suites_cite_post_dcb13791-379e-4739-bcd4-dbaa69f0efdb.xml
index 0f433b6..fb722ad 100644
--- a/tests/expected/suites_cite_post_dcb13791-379e-4739-bcd4-dbaa69f0efdb.xml
+++ b/tests/expected/suites_cite_post_dcb13791-379e-4739-bcd4-dbaa69f0efdb.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<csw:GetRecordsResponse xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ows="http://www.opengis.net/ows" xmlns:fgdc="http://www.opengis.net/cat/csw/csdg [...]
+<csw:GetRecordsResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.0.2" xsi:schemaLocation="http://www.opengis.net/cat/csw/2.0.2 http://schemas.opengis.net/csw/2.0.2/CSW-di [...]
   <csw:SearchStatus timestamp="PYCSW_TIMESTAMP"/>
   <csw:SearchResults nextRecord="11" numberOfRecordsMatched="12" numberOfRecordsReturned="10" recordSchema="http://www.opengis.net/cat/csw/2.0.2" elementSet="brief">
     <csw:BriefRecord>
diff --git a/tests/expected/suites_cite_post_e308f030-c097-4036-a838-44bad74c9ef7.xml b/tests/expected/suites_cite_post_e308f030-c097-4036-a838-44bad74c9ef7.xml
index 0f433b6..fb722ad 100644
--- a/tests/expected/suites_cite_post_e308f030-c097-4036-a838-44bad74c9ef7.xml
+++ b/tests/expected/suites_cite_post_e308f030-c097-4036-a838-44bad74c9ef7.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<csw:GetRecordsResponse xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ows="http://www.opengis.net/ows" xmlns:fgdc="http://www.opengis.net/cat/csw/csdg [...]
+<csw:GetRecordsResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.0.2" xsi:schemaLocation="http://www.opengis.net/cat/csw/2.0.2 http://schemas.opengis.net/csw/2.0.2/CSW-di [...]
   <csw:SearchStatus timestamp="PYCSW_TIMESTAMP"/>
   <csw:SearchResults nextRecord="11" numberOfRecordsMatched="12" numberOfRecordsReturned="10" recordSchema="http://www.opengis.net/cat/csw/2.0.2" elementSet="brief">
     <csw:BriefRecord>
diff --git a/tests/expected/suites_cite_post_e6e9efb2-e2b7-4b0a-a3a2-7deea3f9b8e2.xml b/tests/expected/suites_cite_post_e6e9efb2-e2b7-4b0a-a3a2-7deea3f9b8e2.xml
index 0f433b6..fb722ad 100644
--- a/tests/expected/suites_cite_post_e6e9efb2-e2b7-4b0a-a3a2-7deea3f9b8e2.xml
+++ b/tests/expected/suites_cite_post_e6e9efb2-e2b7-4b0a-a3a2-7deea3f9b8e2.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<csw:GetRecordsResponse xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ows="http://www.opengis.net/ows" xmlns:fgdc="http://www.opengis.net/cat/csw/csdg [...]
+<csw:GetRecordsResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.0.2" xsi:schemaLocation="http://www.opengis.net/cat/csw/2.0.2 http://schemas.opengis.net/csw/2.0.2/CSW-di [...]
   <csw:SearchStatus timestamp="PYCSW_TIMESTAMP"/>
   <csw:SearchResults nextRecord="11" numberOfRecordsMatched="12" numberOfRecordsReturned="10" recordSchema="http://www.opengis.net/cat/csw/2.0.2" elementSet="brief">
     <csw:BriefRecord>
diff --git a/tests/expected/suites_cite_post_f7976c55-a156-4421-8199-bc0487da4b0f.xml b/tests/expected/suites_cite_post_f7976c55-a156-4421-8199-bc0487da4b0f.xml
index 7ee77c7..76101a6 100644
--- a/tests/expected/suites_cite_post_f7976c55-a156-4421-8199-bc0487da4b0f.xml
+++ b/tests/expected/suites_cite_post_f7976c55-a156-4421-8199-bc0487da4b0f.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<csw:DescribeRecordResponse xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ows="http://www.opengis.net/ows" xmlns:fgdc="http://www.opengis.net/cat/csw/ [...]
+<csw:DescribeRecordResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/cat/csw/2.0.2 http://schemas.opengis.net/csw/2.0.2/CSW-discovery.xsd">
   <csw:SchemaComponent schemaLanguage="XMLSCHEMA" targetNamespace="http://www.opengis.net/cat/csw/2.0.2">
     <xs:schema id="csw-record" targetNamespace="http://www.opengis.net/cat/csw/2.0.2" elementFormDefault="qualified" version="2.0.2 2010-01-22">
    <xs:annotation>
diff --git a/tests/expected/suites_cite_post_f7d79701-f10b-4087-a33c-f62df0a04fd1.xml b/tests/expected/suites_cite_post_f7d79701-f10b-4087-a33c-f62df0a04fd1.xml
index 0f433b6..fb722ad 100644
--- a/tests/expected/suites_cite_post_f7d79701-f10b-4087-a33c-f62df0a04fd1.xml
+++ b/tests/expected/suites_cite_post_f7d79701-f10b-4087-a33c-f62df0a04fd1.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<csw:GetRecordsResponse xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ows="http://www.opengis.net/ows" xmlns:fgdc="http://www.opengis.net/cat/csw/csdg [...]
+<csw:GetRecordsResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.0.2" xsi:schemaLocation="http://www.opengis.net/cat/csw/2.0.2 http://schemas.opengis.net/csw/2.0.2/CSW-di [...]
   <csw:SearchStatus timestamp="PYCSW_TIMESTAMP"/>
   <csw:SearchResults nextRecord="11" numberOfRecordsMatched="12" numberOfRecordsReturned="10" recordSchema="http://www.opengis.net/cat/csw/2.0.2" elementSet="brief">
     <csw:BriefRecord>
diff --git a/tests/expected/suites_cite_post_fc1bc094-88f1-4851-bc2b-dfc56be9f3c7.xml b/tests/expected/suites_cite_post_fc1bc094-88f1-4851-bc2b-dfc56be9f3c7.xml
index d3bad8b..b3eb8b2 100644
--- a/tests/expected/suites_cite_post_fc1bc094-88f1-4851-bc2b-dfc56be9f3c7.xml
+++ b/tests/expected/suites_cite_post_fc1bc094-88f1-4851-bc2b-dfc56be9f3c7.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<csw:GetRecordsResponse xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ows="http://www.opengis.net/ows" xmlns:fgdc="http://www.opengis.net/cat/csw/csdg [...]
+<csw:GetRecordsResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.0.2" xsi:schemaLocation="http://www.opengis.net/cat/csw/2.0.2 http://schemas.opengis.net/csw/2.0.2/CSW-di [...]
   <csw:SearchStatus timestamp="PYCSW_TIMESTAMP"/>
   <csw:SearchResults nextRecord="0" numberOfRecordsMatched="1" numberOfRecordsReturned="1" recordSchema="http://www.opengis.net/cat/csw/2.0.2" elementSet="brief">
     <csw:BriefRecord>
diff --git a/tests/expected/suites_cite_post_fe20960f-a26c-4f13-852d-470a0d3233f9.xml b/tests/expected/suites_cite_post_fe20960f-a26c-4f13-852d-470a0d3233f9.xml
index 1abe27d..5c7ef39 100644
--- a/tests/expected/suites_cite_post_fe20960f-a26c-4f13-852d-470a0d3233f9.xml
+++ b/tests/expected/suites_cite_post_fe20960f-a26c-4f13-852d-470a0d3233f9.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<csw:GetRecordsResponse xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ows="http://www.opengis.net/ows" xmlns:fgdc="http://www.opengis.net/cat/csw/csdg [...]
+<csw:GetRecordsResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.0.2" xsi:schemaLocation="http://www.opengis.net/cat/csw/2.0.2 http://schemas.opengis.net/csw/2.0.2/CSW-di [...]
   <csw:SearchStatus timestamp="PYCSW_TIMESTAMP"/>
   <csw:SearchResults nextRecord="0" numberOfRecordsMatched="1" numberOfRecordsReturned="1" recordSchema="http://www.opengis.net/cat/csw/2.0.2" elementSet="brief">
     <csw:BriefRecord>
diff --git a/tests/expected/suites_csw30_get_002258f0-627f-457f-b2ad-025777c77ac8.xml b/tests/expected/suites_csw30_get_002258f0-627f-457f-b2ad-025777c77ac8.xml
new file mode 100644
index 0000000..5aac092
--- /dev/null
+++ b/tests/expected/suites_csw30_get_002258f0-627f-457f-b2ad-025777c77ac8.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- PYCSW_VERSION -->
+<os:OpenSearchDescription xmlns:geo="http://a9.com/-/opensearch/extensions/geo/1.0/" xmlns:os="http://a9.com/-/spec/opensearch/1.1/">
+  <os:ShortName>pycsw Geospatial</os:ShortName>
+  <os:LongName>pycsw Geospatial Catalogue</os:LongName>
+  <os:Description>pycsw is an OGC CSW server implementation written in Python</os:Description>
+  <os:Tags>catalogue discovery</os:Tags>
+  <os:Url type="application/xml" template="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg&service=CSW&version=3.0.0&request=GetRecords&elementsetname=full&typenames=csw:Record&resulttype=results&q={searchTerms?}&bbox={geo:box?}&time={time:start?}/{time:end?}&outputformat=application/xml&outputschema=http://www.opengis.net/cat/csw/3.0&startposition={startIndex?}&maxrecords={count?}&recordids={geo:uid}"/>
+  <os:Url type="application/atom+xml" template="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg&mode=opensearch&service=CSW&version=3.0.0&request=GetRecords&elementsetname=full&typenames=csw:Record&resulttype=results&q={searchTerms?}&bbox={geo:box?}&time={time:start?}/{time:end?}&outputformat=application/atom+xml&&startposition={startIndex?}&maxrecords={count?}&recordids={geo:uid}"/>
+  <os:Image type="image/vnd.microsoft.icon" width="16" height="16">http://pycsw.org/img/favicon.ico</os:Image>
+  <os:Query role="example" geo:box="-180,-90,180,90"/>
+  <os:Developer>Kralidis, Tom</os:Developer>
+  <os:Contact>tomkralidis at gmail.com</os:Contact>
+  <os:Attribution>pycsw</os:Attribution>
+</os:OpenSearchDescription>
diff --git a/tests/expected/suites_csw30_get_045c600d-973d-41eb-9f60-eba1b717b720.xml b/tests/expected/suites_csw30_get_045c600d-973d-41eb-9f60-eba1b717b720.xml
new file mode 100644
index 0000000..5caeab5
--- /dev/null
+++ b/tests/expected/suites_csw30_get_045c600d-973d-41eb-9f60-eba1b717b720.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- PYCSW_VERSION -->
+<atom:feed xmlns:atom="http://www.w3.org/2005/Atom" xmlns:os="http://a9.com/-/spec/opensearch/1.1/">
+  <atom:id>http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg</atom:id>
+  <atom:title>pycsw Geospatial Catalogue</atom:title>
+  <atom:author>
+    <atom:name>pycsw</atom:name>
+  </atom:author>
+  <atom:link href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg&mode=opensearch&service=CSW&version=3.0.0&request=GetCapabilities" rel="search" type="application/opensearchdescription+xml"/>
+  <atom:updated>PYCSW_TIMESTAMP</atom:updated>
+  <os:Query role="request"/>
+  <os:totalResults>1</os:totalResults>
+  <os:startIndex>1</os:startIndex>
+  <os:itemsPerPage>1</os:itemsPerPage>
+  <atom:entry xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dc="http://purl.org/dc/elements/1.1/" xsi:schemaLocation="http://www.w3.org/2005/Atom http://www.kbcafe.com/rss/atom.xsd.xml">
+    <atom:category term="Land titles"/>
+    <atom:id>urn:uuid:e9330592-0932-474b-be34-c3a3bb67c7db</atom:id>
+    <dc:identifier>urn:uuid:e9330592-0932-474b-be34-c3a3bb67c7db</dc:identifier>
+    <atom:link href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg?service=CSW&version=2.0.2&request=GetRepositoryItem&id=urn:uuid:e9330592-0932-474b-be34-c3a3bb67c7db"/>
+    <atom:title>Fuscé vitae ligulä</atom:title>
+    <atom:updated>PYCSW_TIMESTAMP</atom:updated>
+    <atom:summary>Morbi ultriçes, dui suscipit vestibulum prètium, velit ante pretium tortor, egët tincidunt pede odio ac nulla.</atom:summary>
+  </atom:entry>
+</atom:feed>
diff --git a/tests/expected/suites_csw30_get_0bbcf862-5211-4351-9988-63f8bec49c98.xml b/tests/expected/suites_csw30_get_0bbcf862-5211-4351-9988-63f8bec49c98.xml
new file mode 100644
index 0000000..c1b6660
--- /dev/null
+++ b/tests/expected/suites_csw30_get_0bbcf862-5211-4351-9988-63f8bec49c98.xml
@@ -0,0 +1,116 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- PYCSW_VERSION -->
+<atom:feed xmlns:atom="http://www.w3.org/2005/Atom" xmlns:os="http://a9.com/-/spec/opensearch/1.1/">
+  <atom:id>http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg</atom:id>
+  <atom:title>pycsw Geospatial Catalogue</atom:title>
+  <atom:author>
+    <atom:name>pycsw</atom:name>
+  </atom:author>
+  <atom:link href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg&mode=opensearch&service=CSW&version=3.0.0&request=GetCapabilities" rel="search" type="application/opensearchdescription+xml"/>
+  <atom:updated>PYCSW_TIMESTAMP</atom:updated>
+  <os:Query role="request"/>
+  <os:totalResults>12</os:totalResults>
+  <os:startIndex>1</os:startIndex>
+  <os:itemsPerPage>10</os:itemsPerPage>
+  <atom:entry xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dc="http://purl.org/dc/elements/1.1/" xsi:schemaLocation="http://www.w3.org/2005/Atom http://www.kbcafe.com/rss/atom.xsd.xml">
+    <atom:category term="Tourism--Greece"/>
+    <atom:id>urn:uuid:19887a8a-f6b0-4a63-ae56-7fba0e17801f</atom:id>
+    <dc:identifier>urn:uuid:19887a8a-f6b0-4a63-ae56-7fba0e17801f</dc:identifier>
+    <atom:link href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg?service=CSW&version=2.0.2&request=GetRepositoryItem&id=urn:uuid:19887a8a-f6b0-4a63-ae56-7fba0e17801f"/>
+    <atom:title>Lorem ipsum</atom:title>
+    <atom:updated>PYCSW_TIMESTAMP</atom:updated>
+    <atom:summary>Quisque lacus diam, placerat mollis, pharetra in, commodo sed, augue. Duis iaculis arcu vel arcu.</atom:summary>
+  </atom:entry>
+  <atom:entry xmlns:georss="http://www.georss.org/georss" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:gml="http://www.opengis.net/gml" xsi:schemaLocation="http://www.w3.org/2005/Atom http://www.kbcafe.com/rss/atom.xsd.xml">
+    <atom:id>urn:uuid:1ef30a8b-876d-4828-9246-c37ab4510bbd</atom:id>
+    <dc:identifier>urn:uuid:1ef30a8b-876d-4828-9246-c37ab4510bbd</dc:identifier>
+    <atom:link href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg?service=CSW&version=2.0.2&request=GetRepositoryItem&id=urn:uuid:1ef30a8b-876d-4828-9246-c37ab4510bbd"/>
+    <atom:title/>
+    <atom:updated>PYCSW_TIMESTAMP</atom:updated>
+    <atom:summary>Proin sit amet justo. In justo. Aenean adipiscing nulla id tellus.</atom:summary>
+    <georss:where>
+      <gml:Envelope srsName="http://www.opengis.net/def/crs/EPSG/0/4326">
+        <gml:lowerCorner>60.04 13.75</gml:lowerCorner>
+        <gml:upperCorner>68.41 17.92</gml:upperCorner>
+      </gml:Envelope>
+    </georss:where>
+  </atom:entry>
+  <atom:entry xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dc="http://purl.org/dc/elements/1.1/" xsi:schemaLocation="http://www.w3.org/2005/Atom http://www.kbcafe.com/rss/atom.xsd.xml">
+    <atom:category term="Marine sediments"/>
+    <atom:id>urn:uuid:66ae76b7-54ba-489b-a582-0f0633d96493</atom:id>
+    <dc:identifier>urn:uuid:66ae76b7-54ba-489b-a582-0f0633d96493</dc:identifier>
+    <atom:link href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg?service=CSW&version=2.0.2&request=GetRepositoryItem&id=urn:uuid:66ae76b7-54ba-489b-a582-0f0633d96493"/>
+    <atom:title>Maecenas enim</atom:title>
+    <atom:updated>PYCSW_TIMESTAMP</atom:updated>
+    <atom:summary>Pellentesque tempus magna non sapien fringilla blandit.</atom:summary>
+  </atom:entry>
+  <atom:entry xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dc="http://purl.org/dc/elements/1.1/" xsi:schemaLocation="http://www.w3.org/2005/Atom http://www.kbcafe.com/rss/atom.xsd.xml">
+    <atom:category term="Vegetation"/>
+    <atom:id>urn:uuid:6a3de50b-fa66-4b58-a0e6-ca146fdd18d4</atom:id>
+    <dc:identifier>urn:uuid:6a3de50b-fa66-4b58-a0e6-ca146fdd18d4</dc:identifier>
+    <atom:link href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg?service=CSW&version=2.0.2&request=GetRepositoryItem&id=urn:uuid:6a3de50b-fa66-4b58-a0e6-ca146fdd18d4"/>
+    <atom:title>Ut facilisis justo ut lacus</atom:title>
+    <atom:updated>PYCSW_TIMESTAMP</atom:updated>
+  </atom:entry>
+  <atom:entry xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dc="http://purl.org/dc/elements/1.1/" xsi:schemaLocation="http://www.w3.org/2005/Atom http://www.kbcafe.com/rss/atom.xsd.xml">
+    <atom:category term="Hydrography--Dictionaries"/>
+    <atom:id>urn:uuid:784e2afd-a9fd-44a6-9a92-a3848371c8ec</atom:id>
+    <dc:identifier>urn:uuid:784e2afd-a9fd-44a6-9a92-a3848371c8ec</dc:identifier>
+    <atom:link href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg?service=CSW&version=2.0.2&request=GetRepositoryItem&id=urn:uuid:784e2afd-a9fd-44a6-9a92-a3848371c8ec"/>
+    <atom:title>Aliquam fermentum purus quis arcu</atom:title>
+    <atom:updated>PYCSW_TIMESTAMP</atom:updated>
+    <atom:summary>Vestibulum quis ipsum sit amet metus imperdiet vehicula. Nulla scelerisque cursus mi.</atom:summary>
+  </atom:entry>
+  <atom:entry xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dc="http://purl.org/dc/elements/1.1/" xsi:schemaLocation="http://www.w3.org/2005/Atom http://www.kbcafe.com/rss/atom.xsd.xml">
+    <atom:id>urn:uuid:829babb0-b2f1-49e1-8cd5-7b489fe71a1e</atom:id>
+    <dc:identifier>urn:uuid:829babb0-b2f1-49e1-8cd5-7b489fe71a1e</dc:identifier>
+    <atom:link href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg?service=CSW&version=2.0.2&request=GetRepositoryItem&id=urn:uuid:829babb0-b2f1-49e1-8cd5-7b489fe71a1e"/>
+    <atom:title>Vestibulum massa purus</atom:title>
+    <atom:updated>PYCSW_TIMESTAMP</atom:updated>
+  </atom:entry>
+  <atom:entry xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dc="http://purl.org/dc/elements/1.1/" xsi:schemaLocation="http://www.w3.org/2005/Atom http://www.kbcafe.com/rss/atom.xsd.xml">
+    <atom:category term="Physiography-Landforms"/>
+    <atom:id>urn:uuid:88247b56-4cbc-4df9-9860-db3f8042e357</atom:id>
+    <dc:identifier>urn:uuid:88247b56-4cbc-4df9-9860-db3f8042e357</dc:identifier>
+    <atom:link href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg?service=CSW&version=2.0.2&request=GetRepositoryItem&id=urn:uuid:88247b56-4cbc-4df9-9860-db3f8042e357"/>
+    <atom:title/>
+    <atom:updated>PYCSW_TIMESTAMP</atom:updated>
+    <atom:summary>Donec scelerisque pede ut nisl luctus accumsan. Quisque ultrices, lorem eget feugiat fringilla, lorem dui porttitor ante, cursus ultrices magna odio eu neque.</atom:summary>
+  </atom:entry>
+  <atom:entry xmlns:georss="http://www.georss.org/georss" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:gml="http://www.opengis.net/gml" xsi:schemaLocation="http://www.w3.org/2005/Atom http://www.kbcafe.com/rss/atom.xsd.xml">
+    <atom:category term="Vegetation-Cropland"/>
+    <atom:id>urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63</atom:id>
+    <dc:identifier>urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63</dc:identifier>
+    <atom:link href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg?service=CSW&version=2.0.2&request=GetRepositoryItem&id=urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63"/>
+    <atom:title>Mauris sed neque</atom:title>
+    <atom:updated>PYCSW_TIMESTAMP</atom:updated>
+    <atom:summary>Curabitur lacinia, ante non porta tempus, mi lorem feugiat odio, eget suscipit eros pede ac velit.</atom:summary>
+    <georss:where>
+      <gml:Envelope srsName="http://www.opengis.net/def/crs/EPSG/0/4326">
+        <gml:lowerCorner>47.59 -4.1</gml:lowerCorner>
+        <gml:upperCorner>51.22 0.89</gml:upperCorner>
+      </gml:Envelope>
+    </georss:where>
+  </atom:entry>
+  <atom:entry xmlns:georss="http://www.georss.org/georss" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:gml="http://www.opengis.net/gml" xsi:schemaLocation="http://www.w3.org/2005/Atom http://www.kbcafe.com/rss/atom.xsd.xml">
+    <atom:category term="Hydrography-Oceanographic"/>
+    <atom:id>urn:uuid:9a669547-b69b-469f-a11f-2d875366bbdc</atom:id>
+    <dc:identifier>urn:uuid:9a669547-b69b-469f-a11f-2d875366bbdc</dc:identifier>
+    <atom:link href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg?service=CSW&version=2.0.2&request=GetRepositoryItem&id=urn:uuid:9a669547-b69b-469f-a11f-2d875366bbdc"/>
+    <atom:title>Ñunç elementum</atom:title>
+    <atom:updated>PYCSW_TIMESTAMP</atom:updated>
+    <georss:where>
+      <gml:Envelope srsName="http://www.opengis.net/def/crs/EPSG/0/4326">
+        <gml:lowerCorner>44.79 -6.17</gml:lowerCorner>
+        <gml:upperCorner>51.13 -2.23</gml:upperCorner>
+      </gml:Envelope>
+    </georss:where>
+  </atom:entry>
+  <atom:entry xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dc="http://purl.org/dc/elements/1.1/" xsi:schemaLocation="http://www.w3.org/2005/Atom http://www.kbcafe.com/rss/atom.xsd.xml">
+    <atom:id>urn:uuid:a06af396-3105-442d-8b40-22b57a90d2f2</atom:id>
+    <dc:identifier>urn:uuid:a06af396-3105-442d-8b40-22b57a90d2f2</dc:identifier>
+    <atom:link href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg?service=CSW&version=2.0.2&request=GetRepositoryItem&id=urn:uuid:a06af396-3105-442d-8b40-22b57a90d2f2"/>
+    <atom:title>Lorem ipsum dolor sit amet</atom:title>
+    <atom:updated>PYCSW_TIMESTAMP</atom:updated>
+  </atom:entry>
+</atom:feed>
diff --git a/tests/expected/suites_csw30_get_0bdf8457-971e-4ed1-be4a-5feca4dcd8fa.xml b/tests/expected/suites_csw30_get_0bdf8457-971e-4ed1-be4a-5feca4dcd8fa.xml
new file mode 100644
index 0000000..ce9c935
--- /dev/null
+++ b/tests/expected/suites_csw30_get_0bdf8457-971e-4ed1-be4a-5feca4dcd8fa.xml
@@ -0,0 +1,491 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- PYCSW_VERSION -->
+<csw30:Capabilities xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:csw30="http://www.opengis.net/cat/csw/3.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:fes20="http://www.opengis.net/fes/2.0" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:ows11="http://www.opengis.net/ows/1.1" xmlns:ows20="http://www.opengis.net/ows/2.0" xmlns:xlink="http://www.w3.org/199 [...]
+  <ows20:ServiceIdentification>
+    <ows20:Title>pycsw Geospatial Catalogue</ows20:Title>
+    <ows20:Abstract>pycsw is an OGC CSW server implementation written in Python</ows20:Abstract>
+    <ows20:Keywords>
+      <ows20:Keyword>catalogue</ows20:Keyword>
+      <ows20:Keyword>discovery</ows20:Keyword>
+      <ows20:Type codeSpace="ISOTC211/19115">theme</ows20:Type>
+    </ows20:Keywords>
+    <ows20:ServiceType codeSpace="OGC">CSW</ows20:ServiceType>
+    <ows20:ServiceTypeVersion>2.0.2</ows20:ServiceTypeVersion>
+    <ows20:ServiceTypeVersion>3.0.0</ows20:ServiceTypeVersion>
+    <ows20:Fees>None</ows20:Fees>
+    <ows20:AccessConstraints>None</ows20:AccessConstraints>
+  </ows20:ServiceIdentification>
+  <ows20:ServiceProvider>
+    <ows20:ProviderName>pycsw</ows20:ProviderName>
+    <ows20:ProviderSite xlink:type="simple" xlink:href="http://pycsw.org/"/>
+    <ows20:ServiceContact>
+      <ows20:IndividualName>Kralidis, Tom</ows20:IndividualName>
+      <ows20:PositionName>Senior Systems Scientist</ows20:PositionName>
+      <ows20:ContactInfo>
+        <ows20:Phone>
+          <ows20:Voice>+01-416-xxx-xxxx</ows20:Voice>
+          <ows20:Facsimile>+01-416-xxx-xxxx</ows20:Facsimile>
+        </ows20:Phone>
+        <ows20:Address>
+          <ows20:DeliveryPoint>TBA</ows20:DeliveryPoint>
+          <ows20:City>Toronto</ows20:City>
+          <ows20:AdministrativeArea>Ontario</ows20:AdministrativeArea>
+          <ows20:PostalCode>M9C 3Z9</ows20:PostalCode>
+          <ows20:Country>Canada</ows20:Country>
+          <ows20:ElectronicMailAddress>tomkralidis at gmail.com</ows20:ElectronicMailAddress>
+        </ows20:Address>
+        <ows20:OnlineResource xlink:type="simple" xlink:href="http://kralidis.ca/"/>
+        <ows20:HoursOfService>0800h - 1600h EST</ows20:HoursOfService>
+        <ows20:ContactInstructions>During hours of service.  Off on weekends.</ows20:ContactInstructions>
+      </ows20:ContactInfo>
+      <ows20:Role codeSpace="ISOTC211/19115">pointOfContact</ows20:Role>
+    </ows20:ServiceContact>
+  </ows20:ServiceProvider>
+  <ows20:OperationsMetadata>
+    <ows20:Operation name="GetCapabilities">
+      <ows20:DCP>
+        <ows20:HTTP>
+          <ows20:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg"/>
+          <ows20:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg"/>
+        </ows20:HTTP>
+      </ows20:DCP>
+      <ows20:Parameter name="acceptFormats">
+        <ows20:AllowedValues>
+          <ows20:Value>application/xml</ows20:Value>
+          <ows20:Value>text/xml</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Parameter name="acceptVersions">
+        <ows20:AllowedValues>
+          <ows20:Value>2.0.2</ows20:Value>
+          <ows20:Value>3.0.0</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Parameter name="sections">
+        <ows20:AllowedValues>
+          <ows20:Value>All</ows20:Value>
+          <ows20:Value>Filter_Capabilities</ows20:Value>
+          <ows20:Value>OperationsMetadata</ows20:Value>
+          <ows20:Value>ServiceIdentification</ows20:Value>
+          <ows20:Value>ServiceProvider</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+    </ows20:Operation>
+    <ows20:Operation name="GetDomain">
+      <ows20:DCP>
+        <ows20:HTTP>
+          <ows20:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg"/>
+          <ows20:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg"/>
+        </ows20:HTTP>
+      </ows20:DCP>
+      <ows20:Parameter name="ParameterName">
+        <ows20:AllowedValues>
+          <ows20:Value>GetCapabilities.acceptFormats</ows20:Value>
+          <ows20:Value>GetCapabilities.acceptVersions</ows20:Value>
+          <ows20:Value>GetCapabilities.sections</ows20:Value>
+          <ows20:Value>GetRecordById.ElementSetName</ows20:Value>
+          <ows20:Value>GetRecordById.outputFormat</ows20:Value>
+          <ows20:Value>GetRecordById.outputSchema</ows20:Value>
+          <ows20:Value>GetRecords.CONSTRAINTLANGUAGE</ows20:Value>
+          <ows20:Value>GetRecords.ElementSetName</ows20:Value>
+          <ows20:Value>GetRecords.outputFormat</ows20:Value>
+          <ows20:Value>GetRecords.outputSchema</ows20:Value>
+          <ows20:Value>GetRecords.typeNames</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+    </ows20:Operation>
+    <ows20:Operation name="GetRecords">
+      <ows20:DCP>
+        <ows20:HTTP>
+          <ows20:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg"/>
+          <ows20:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg"/>
+        </ows20:HTTP>
+      </ows20:DCP>
+      <ows20:Parameter name="CONSTRAINTLANGUAGE">
+        <ows20:AllowedValues>
+          <ows20:Value>CQL_TEXT</ows20:Value>
+          <ows20:Value>FILTER</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Parameter name="ElementSetName">
+        <ows20:AllowedValues>
+          <ows20:Value>brief</ows20:Value>
+          <ows20:Value>full</ows20:Value>
+          <ows20:Value>summary</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Parameter name="outputFormat">
+        <ows20:AllowedValues>
+          <ows20:Value>application/atom+xml</ows20:Value>
+          <ows20:Value>application/json</ows20:Value>
+          <ows20:Value>application/xml</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Parameter name="outputSchema">
+        <ows20:AllowedValues>
+          <ows20:Value>http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/</ows20:Value>
+          <ows20:Value>http://www.interlis.ch/INTERLIS2.3</ows20:Value>
+          <ows20:Value>http://www.opengis.net/cat/csw/3.0</ows20:Value>
+          <ows20:Value>http://www.opengis.net/cat/csw/csdgm</ows20:Value>
+          <ows20:Value>http://www.w3.org/2005/Atom</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Parameter name="typeNames">
+        <ows20:AllowedValues>
+          <ows20:Value>csw:Record</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Constraint name="MaxRecordDefault">
+        <ows20:AllowedValues>
+          <ows20:Value>10</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Constraint>
+      <ows20:Constraint name="OpenSearchDescriptionDocument">
+        <ows20:AllowedValues>
+          <ows20:Value>http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg?mode=opensearch&service=CSW&version=3.0.0&request=GetCapabilities</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Constraint>
+      <ows20:Constraint name="FederatedCatalogues">
+        <ows20:AllowedValues>
+          <ows20:Value>http://demo.pycsw.org/gisdata/csw</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Constraint>
+    </ows20:Operation>
+    <ows20:Operation name="GetRecordById">
+      <ows20:DCP>
+        <ows20:HTTP>
+          <ows20:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg"/>
+          <ows20:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg"/>
+        </ows20:HTTP>
+      </ows20:DCP>
+      <ows20:Parameter name="ElementSetName">
+        <ows20:AllowedValues>
+          <ows20:Value>brief</ows20:Value>
+          <ows20:Value>full</ows20:Value>
+          <ows20:Value>summary</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Parameter name="outputFormat">
+        <ows20:AllowedValues>
+          <ows20:Value>application/atom+xml</ows20:Value>
+          <ows20:Value>application/json</ows20:Value>
+          <ows20:Value>application/xml</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Parameter name="outputSchema">
+        <ows20:AllowedValues>
+          <ows20:Value>http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/</ows20:Value>
+          <ows20:Value>http://www.interlis.ch/INTERLIS2.3</ows20:Value>
+          <ows20:Value>http://www.opengis.net/cat/csw/3.0</ows20:Value>
+          <ows20:Value>http://www.opengis.net/cat/csw/csdgm</ows20:Value>
+          <ows20:Value>http://www.w3.org/2005/Atom</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+    </ows20:Operation>
+    <ows20:Operation name="GetRepositoryItem">
+      <ows20:DCP>
+        <ows20:HTTP>
+          <ows20:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg"/>
+        </ows20:HTTP>
+      </ows20:DCP>
+    </ows20:Operation>
+    <ows20:Parameter name="service">
+      <ows20:AllowedValues>
+        <ows20:Value>CSW</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Parameter>
+    <ows20:Parameter name="version">
+      <ows20:AllowedValues>
+        <ows20:Value>2.0.2</ows20:Value>
+        <ows20:Value>3.0.0</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Parameter>
+    <ows20:Constraint name="CoreQueryables">
+      <ows20:AllowedValues>
+        <ows20:Value>csw:AnyText</ows20:Value>
+        <ows20:Value>dc:contributor</ows20:Value>
+        <ows20:Value>dc:creator</ows20:Value>
+        <ows20:Value>dc:date</ows20:Value>
+        <ows20:Value>dc:format</ows20:Value>
+        <ows20:Value>dc:identifier</ows20:Value>
+        <ows20:Value>dc:language</ows20:Value>
+        <ows20:Value>dc:publisher</ows20:Value>
+        <ows20:Value>dc:relation</ows20:Value>
+        <ows20:Value>dc:rights</ows20:Value>
+        <ows20:Value>dc:source</ows20:Value>
+        <ows20:Value>dc:subject</ows20:Value>
+        <ows20:Value>dc:title</ows20:Value>
+        <ows20:Value>dc:type</ows20:Value>
+        <ows20:Value>dct:abstract</ows20:Value>
+        <ows20:Value>dct:modified</ows20:Value>
+        <ows20:Value>ows:BoundingBox</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="FederatedCatalogues">
+      <ows20:AllowedValues>
+        <ows20:Value>http://demo.pycsw.org/gisdata/csw</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="MaxRecordDefault">
+      <ows20:AllowedValues>
+        <ows20:Value>10</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="PostEncoding">
+      <ows20:AllowedValues>
+        <ows20:Value>SOAP</ows20:Value>
+        <ows20:Value>XML</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="XPathQueryables">
+      <ows20:AllowedValues>
+        <ows20:Value>allowed</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/CoreQueryables">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/CoreSortables">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/DefaultSortingAlgorithm">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Filter-CQL">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Filter-FES-KVP-Advanced">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Filter-FES-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetCapabilities-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetDomain-KVP">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetDomain-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetRecordById-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetRecords-Async-KVP">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetRecords-Async-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetRecords-Basic-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetRecords-Distributed-KVP">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetRecords-Distributed-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Harvest-Async-KVP">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Harvest-Async-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Harvest-Basic-KVP">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Harvest-Basic-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Harvest-Periodic-KVP">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Harvest-Periodic-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/OpenSearch">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/SupportedGMLVersions">
+      <ows20:AllowedValues>
+        <ows20:Value>http://www.opengis.net/gml</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Transaction">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+  </ows20:OperationsMetadata>
+  <ows20:Languages>
+    <ows20:Language>en</ows20:Language>
+  </ows20:Languages>
+  <fes20:Filter_Capabilities>
+    <fes20:Conformance>
+      <fes20:Constraint name="ImplementsQuery">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsAdHocQuery">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsFunctions">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsResourceld">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsMinStandardFilter">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsStandardFilter">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsMinSpatialFilter">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsSpatialFilter">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsMinTemporalFilter">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsTemporalFilter">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsVersionNav">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsSorting">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsExtendedOperators">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsMinimumXPath">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsSchemaElementFunc">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+    </fes20:Conformance>
+    <fes20:Id_Capabilities>
+      <fes20:ResourceIdentifier name="csw30:id"/>
+    </fes20:Id_Capabilities>
+    <fes20:Scalar_Capabilities>
+      <fes20:LogicalOperators/>
+      <fes20:ComparisonOperators>
+        <fes20:ComparisonOperator name="PropertyIsBetween"/>
+        <fes20:ComparisonOperator name="PropertyIsEqualTo"/>
+        <fes20:ComparisonOperator name="PropertyIsGreaterThan"/>
+        <fes20:ComparisonOperator name="PropertyIsGreaterThanOrEqualTo"/>
+        <fes20:ComparisonOperator name="PropertyIsLessThan"/>
+        <fes20:ComparisonOperator name="PropertyIsLessThanOrEqualTo"/>
+        <fes20:ComparisonOperator name="PropertyIsLike"/>
+        <fes20:ComparisonOperator name="PropertyIsNotEqualTo"/>
+        <fes20:ComparisonOperator name="PropertyIsNull"/>
+      </fes20:ComparisonOperators>
+    </fes20:Scalar_Capabilities>
+    <fes20:Spatial_Capabilities>
+      <fes20:GeometryOperands>
+        <fes20:GeometryOperand name="gml:Point"/>
+        <fes20:GeometryOperand name="gml:LineString"/>
+        <fes20:GeometryOperand name="gml:Polygon"/>
+        <fes20:GeometryOperand name="gml:Envelope"/>
+      </fes20:GeometryOperands>
+      <fes20:SpatialOperators>
+        <fes20:SpatialOperator name="BBOX"/>
+        <fes20:SpatialOperator name="Beyond"/>
+        <fes20:SpatialOperator name="Contains"/>
+        <fes20:SpatialOperator name="Crosses"/>
+        <fes20:SpatialOperator name="Disjoint"/>
+        <fes20:SpatialOperator name="DWithin"/>
+        <fes20:SpatialOperator name="Equals"/>
+        <fes20:SpatialOperator name="Intersects"/>
+        <fes20:SpatialOperator name="Overlaps"/>
+        <fes20:SpatialOperator name="Touches"/>
+        <fes20:SpatialOperator name="Within"/>
+      </fes20:SpatialOperators>
+    </fes20:Spatial_Capabilities>
+    <fes20:Functions>
+      <fes20:Function name="length">
+        <fes20:Returns>xs:string</fes20:Returns>
+      </fes20:Function>
+      <fes20:Function name="lower">
+        <fes20:Returns>xs:string</fes20:Returns>
+      </fes20:Function>
+      <fes20:Function name="ltrim">
+        <fes20:Returns>xs:string</fes20:Returns>
+      </fes20:Function>
+      <fes20:Function name="rtrim">
+        <fes20:Returns>xs:string</fes20:Returns>
+      </fes20:Function>
+      <fes20:Function name="trim">
+        <fes20:Returns>xs:string</fes20:Returns>
+      </fes20:Function>
+      <fes20:Function name="upper">
+        <fes20:Returns>xs:string</fes20:Returns>
+      </fes20:Function>
+    </fes20:Functions>
+  </fes20:Filter_Capabilities>
+</csw30:Capabilities>
diff --git a/tests/expected/suites_csw30_get_0d8bbdec-0846-42ca-8dc8-b7f4cba41d67.xml b/tests/expected/suites_csw30_get_0d8bbdec-0846-42ca-8dc8-b7f4cba41d67.xml
new file mode 100644
index 0000000..21edd26
--- /dev/null
+++ b/tests/expected/suites_csw30_get_0d8bbdec-0846-42ca-8dc8-b7f4cba41d67.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- PYCSW_VERSION -->
+<csw30:GetRecordsResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:csw30="http://www.opengis.net/cat/csw/3.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="3.0.0" xsi:schemaLocation="http://www.opengis.net/cat/cs [...]
+  <csw30:SearchStatus timestamp="PYCSW_TIMESTAMP"/>
+  <csw30:SearchResults expires="PYCSW_EXPIRES" nextRecord="11" numberOfRecordsMatched="12" numberOfRecordsReturned="10" recordSchema="http://www.opengis.net/cat/csw/3.0" status="subset" elementSet="summary" elapsedTime="PYCSW_ELAPSED_TIME">
+    <csw30:SummaryRecord>
+      <dc:identifier>urn:uuid:19887a8a-f6b0-4a63-ae56-7fba0e17801f</dc:identifier>
+      <dc:title>Lorem ipsum</dc:title>
+    </csw30:SummaryRecord>
+    <csw30:SummaryRecord>
+      <dc:identifier>urn:uuid:1ef30a8b-876d-4828-9246-c37ab4510bbd</dc:identifier>
+      <dc:title/>
+    </csw30:SummaryRecord>
+    <csw30:SummaryRecord>
+      <dc:identifier>urn:uuid:66ae76b7-54ba-489b-a582-0f0633d96493</dc:identifier>
+      <dc:title>Maecenas enim</dc:title>
+    </csw30:SummaryRecord>
+    <csw30:SummaryRecord>
+      <dc:identifier>urn:uuid:6a3de50b-fa66-4b58-a0e6-ca146fdd18d4</dc:identifier>
+      <dc:title>Ut facilisis justo ut lacus</dc:title>
+    </csw30:SummaryRecord>
+    <csw30:SummaryRecord>
+      <dc:identifier>urn:uuid:784e2afd-a9fd-44a6-9a92-a3848371c8ec</dc:identifier>
+      <dc:title>Aliquam fermentum purus quis arcu</dc:title>
+    </csw30:SummaryRecord>
+    <csw30:SummaryRecord>
+      <dc:identifier>urn:uuid:829babb0-b2f1-49e1-8cd5-7b489fe71a1e</dc:identifier>
+      <dc:title>Vestibulum massa purus</dc:title>
+    </csw30:SummaryRecord>
+    <csw30:SummaryRecord>
+      <dc:identifier>urn:uuid:88247b56-4cbc-4df9-9860-db3f8042e357</dc:identifier>
+      <dc:title/>
+    </csw30:SummaryRecord>
+    <csw30:SummaryRecord>
+      <dc:identifier>urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63</dc:identifier>
+      <dc:title>Mauris sed neque</dc:title>
+    </csw30:SummaryRecord>
+    <csw30:SummaryRecord>
+      <dc:identifier>urn:uuid:9a669547-b69b-469f-a11f-2d875366bbdc</dc:identifier>
+      <dc:title>Ñunç elementum</dc:title>
+    </csw30:SummaryRecord>
+    <csw30:SummaryRecord>
+      <dc:identifier>urn:uuid:a06af396-3105-442d-8b40-22b57a90d2f2</dc:identifier>
+      <dc:title>Lorem ipsum dolor sit amet</dc:title>
+    </csw30:SummaryRecord>
+  </csw30:SearchResults>
+</csw30:GetRecordsResponse>
diff --git a/tests/expected/suites_csw30_get_0e1dca37-477a-4060-99fe-7799b52d656c.xml b/tests/expected/suites_csw30_get_0e1dca37-477a-4060-99fe-7799b52d656c.xml
new file mode 100644
index 0000000..b6869d8
--- /dev/null
+++ b/tests/expected/suites_csw30_get_0e1dca37-477a-4060-99fe-7799b52d656c.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- PYCSW_VERSION -->
+<atom:feed xmlns:atom="http://www.w3.org/2005/Atom" xmlns:os="http://a9.com/-/spec/opensearch/1.1/">
+  <atom:id>http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg</atom:id>
+  <atom:title>pycsw Geospatial Catalogue</atom:title>
+  <atom:author>
+    <atom:name>pycsw</atom:name>
+  </atom:author>
+  <atom:link href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg&mode=opensearch&service=CSW&version=3.0.0&request=GetCapabilities" rel="search" type="application/opensearchdescription+xml"/>
+  <atom:updated>PYCSW_TIMESTAMP</atom:updated>
+  <os:Query role="request"/>
+  <os:totalResults>0</os:totalResults>
+  <os:startIndex>1</os:startIndex>
+  <os:itemsPerPage>0</os:itemsPerPage>
+</atom:feed>
diff --git a/tests/expected/suites_cite_post_6e736fd0-c266-4852-9eb3-0656f5d0f5c4.xml b/tests/expected/suites_csw30_get_13c87956-51a4-4780-a8e9-6e0b5c0bb473.xml
similarity index 59%
copy from tests/expected/suites_cite_post_6e736fd0-c266-4852-9eb3-0656f5d0f5c4.xml
copy to tests/expected/suites_csw30_get_13c87956-51a4-4780-a8e9-6e0b5c0bb473.xml
index f704008..3ce950b 100644
--- a/tests/expected/suites_cite_post_6e736fd0-c266-4852-9eb3-0656f5d0f5c4.xml
+++ b/tests/expected/suites_csw30_get_13c87956-51a4-4780-a8e9-6e0b5c0bb473.xml
@@ -1,89 +1,92 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<csw:GetRecordsResponse xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ows="http://www.opengis.net/ows" xmlns:fgdc="http://www.opengis.net/cat/csw/csdg [...]
-  <csw:SearchStatus timestamp="PYCSW_TIMESTAMP"/>
-  <csw:SearchResults nextRecord="11" numberOfRecordsMatched="12" numberOfRecordsReturned="10" recordSchema="http://www.opengis.net/cat/csw/2.0.2" elementSet="summary">
-    <csw:SummaryRecord>
+<csw30:GetRecordsResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:csw30="http://www.opengis.net/cat/csw/3.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:ows20="http://www.opengis.net/ows/2.0" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="3.0.0" xsi: [...]
+  <csw30:SearchStatus timestamp="PYCSW_TIMESTAMP"/>
+  <csw30:SearchResults expires="PYCSW_EXPIRES" nextRecord="11" numberOfRecordsMatched="12" numberOfRecordsReturned="10" recordSchema="http://www.opengis.net/cat/csw/3.0" status="subset" elementSet="full" elapsedTime="PYCSW_ELAPSED_TIME">
+    <csw30:Record>
       <dc:identifier>urn:uuid:19887a8a-f6b0-4a63-ae56-7fba0e17801f</dc:identifier>
       <dc:title>Lorem ipsum</dc:title>
       <dc:type>http://purl.org/dc/dcmitype/Image</dc:type>
       <dc:subject>Tourism--Greece</dc:subject>
       <dc:format>image/svg+xml</dc:format>
       <dct:abstract>Quisque lacus diam, placerat mollis, pharetra in, commodo sed, augue. Duis iaculis arcu vel arcu.</dct:abstract>
-    </csw:SummaryRecord>
-    <csw:SummaryRecord>
+    </csw30:Record>
+    <csw30:Record>
       <dc:identifier>urn:uuid:1ef30a8b-876d-4828-9246-c37ab4510bbd</dc:identifier>
       <dc:title></dc:title>
       <dc:type>http://purl.org/dc/dcmitype/Service</dc:type>
       <dct:abstract>Proin sit amet justo. In justo. Aenean adipiscing nulla id tellus.</dct:abstract>
-      <ows:BoundingBox crs="urn:x-ogc:def:crs:EPSG:6.11:4326" dimensions="2">
-        <ows:LowerCorner>60.04 13.75</ows:LowerCorner>
-        <ows:UpperCorner>68.41 17.92</ows:UpperCorner>
-      </ows:BoundingBox>
-    </csw:SummaryRecord>
-    <csw:SummaryRecord>
+      <ows20:BoundingBox crs="http://www.opengis.net/def/crs/EPSG/0/4326" dimensions="2">
+        <ows20:LowerCorner>60.04 13.75</ows20:LowerCorner>
+        <ows20:UpperCorner>68.41 17.92</ows20:UpperCorner>
+      </ows20:BoundingBox>
+    </csw30:Record>
+    <csw30:Record>
       <dc:identifier>urn:uuid:66ae76b7-54ba-489b-a582-0f0633d96493</dc:identifier>
       <dc:title>Maecenas enim</dc:title>
       <dc:type>http://purl.org/dc/dcmitype/Text</dc:type>
       <dc:subject>Marine sediments</dc:subject>
       <dc:format>application/xhtml+xml</dc:format>
       <dct:abstract>Pellentesque tempus magna non sapien fringilla blandit.</dct:abstract>
-    </csw:SummaryRecord>
-    <csw:SummaryRecord>
+    </csw30:Record>
+    <csw30:Record>
       <dc:identifier>urn:uuid:6a3de50b-fa66-4b58-a0e6-ca146fdd18d4</dc:identifier>
       <dc:title>Ut facilisis justo ut lacus</dc:title>
       <dc:type>http://purl.org/dc/dcmitype/Service</dc:type>
       <dc:subject>Vegetation</dc:subject>
       <dc:relation>urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63</dc:relation>
-    </csw:SummaryRecord>
-    <csw:SummaryRecord>
+    </csw30:Record>
+    <csw30:Record>
       <dc:identifier>urn:uuid:784e2afd-a9fd-44a6-9a92-a3848371c8ec</dc:identifier>
       <dc:title>Aliquam fermentum purus quis arcu</dc:title>
       <dc:type>http://purl.org/dc/dcmitype/Text</dc:type>
       <dc:subject>Hydrography--Dictionaries</dc:subject>
       <dc:format>application/pdf</dc:format>
       <dct:abstract>Vestibulum quis ipsum sit amet metus imperdiet vehicula. Nulla scelerisque cursus mi.</dct:abstract>
-    </csw:SummaryRecord>
-    <csw:SummaryRecord>
+      <dc:date>2006-05-12</dc:date>
+    </csw30:Record>
+    <csw30:Record>
       <dc:identifier>urn:uuid:829babb0-b2f1-49e1-8cd5-7b489fe71a1e</dc:identifier>
       <dc:title>Vestibulum massa purus</dc:title>
       <dc:type>http://purl.org/dc/dcmitype/Image</dc:type>
       <dc:format>image/jp2</dc:format>
       <dc:relation>urn:uuid:9a669547-b69b-469f-a11f-2d875366bbdc</dc:relation>
-    </csw:SummaryRecord>
-    <csw:SummaryRecord>
+    </csw30:Record>
+    <csw30:Record>
       <dc:identifier>urn:uuid:88247b56-4cbc-4df9-9860-db3f8042e357</dc:identifier>
       <dc:title></dc:title>
       <dc:type>http://purl.org/dc/dcmitype/Dataset</dc:type>
       <dc:subject>Physiography-Landforms</dc:subject>
       <dct:abstract>Donec scelerisque pede ut nisl luctus accumsan. Quisque ultrices, lorem eget feugiat fringilla, lorem dui porttitor ante, cursus ultrices magna odio eu neque.</dct:abstract>
-    </csw:SummaryRecord>
-    <csw:SummaryRecord>
+    </csw30:Record>
+    <csw30:Record>
       <dc:identifier>urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63</dc:identifier>
       <dc:title>Mauris sed neque</dc:title>
       <dc:type>http://purl.org/dc/dcmitype/Dataset</dc:type>
       <dc:subject>Vegetation-Cropland</dc:subject>
       <dct:abstract>Curabitur lacinia, ante non porta tempus, mi lorem feugiat odio, eget suscipit eros pede ac velit.</dct:abstract>
-      <ows:BoundingBox crs="urn:x-ogc:def:crs:EPSG:6.11:4326" dimensions="2">
-        <ows:LowerCorner>47.59 -4.1</ows:LowerCorner>
-        <ows:UpperCorner>51.22 0.89</ows:UpperCorner>
-      </ows:BoundingBox>
-    </csw:SummaryRecord>
-    <csw:SummaryRecord>
+      <dc:date>2006-03-26</dc:date>
+      <ows20:BoundingBox crs="http://www.opengis.net/def/crs/EPSG/0/4326" dimensions="2">
+        <ows20:LowerCorner>47.59 -4.1</ows20:LowerCorner>
+        <ows20:UpperCorner>51.22 0.89</ows20:UpperCorner>
+      </ows20:BoundingBox>
+    </csw30:Record>
+    <csw30:Record>
       <dc:identifier>urn:uuid:9a669547-b69b-469f-a11f-2d875366bbdc</dc:identifier>
       <dc:title>Ñunç elementum</dc:title>
       <dc:type>http://purl.org/dc/dcmitype/Dataset</dc:type>
       <dc:subject>Hydrography-Oceanographic</dc:subject>
-      <ows:BoundingBox crs="urn:x-ogc:def:crs:EPSG:6.11:4326" dimensions="2">
-        <ows:LowerCorner>44.79 -6.17</ows:LowerCorner>
-        <ows:UpperCorner>51.13 -2.23</ows:UpperCorner>
-      </ows:BoundingBox>
-    </csw:SummaryRecord>
-    <csw:SummaryRecord>
+      <dc:date>2005-10-24</dc:date>
+      <ows20:BoundingBox crs="http://www.opengis.net/def/crs/EPSG/0/4326" dimensions="2">
+        <ows20:LowerCorner>44.79 -6.17</ows20:LowerCorner>
+        <ows20:UpperCorner>51.13 -2.23</ows20:UpperCorner>
+      </ows20:BoundingBox>
+    </csw30:Record>
+    <csw30:Record>
       <dc:identifier>urn:uuid:a06af396-3105-442d-8b40-22b57a90d2f2</dc:identifier>
       <dc:title>Lorem ipsum dolor sit amet</dc:title>
       <dc:type>http://purl.org/dc/dcmitype/Image</dc:type>
       <dc:format>image/jpeg</dc:format>
-    </csw:SummaryRecord>
-  </csw:SearchResults>
-</csw:GetRecordsResponse>
+    </csw30:Record>
+  </csw30:SearchResults>
+</csw30:GetRecordsResponse>
diff --git a/tests/expected/suites_csw30_get_151d982f-ebd3-4cb2-b507-a667713a1e92.xml b/tests/expected/suites_csw30_get_151d982f-ebd3-4cb2-b507-a667713a1e92.xml
new file mode 100644
index 0000000..633f7c9
--- /dev/null
+++ b/tests/expected/suites_csw30_get_151d982f-ebd3-4cb2-b507-a667713a1e92.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- PYCSW_VERSION -->
+<ows20:ExceptionReport xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:ows20="http://www.opengis.net/ows/2.0" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="3.0.0" xml:lang="en-US" xsi:schemaLocation="http://www.opengis. [...]
+  <ows20:Exception exceptionCode="InvalidParameterValue" locator="acceptformats">
+    <ows20:ExceptionText>Invalid acceptFormats parameter value: model/x3d+xml</ows20:ExceptionText>
+  </ows20:Exception>
+</ows20:ExceptionReport>
diff --git a/tests/expected/suites_csw30_get_1869e495-1a61-4713-8285-76d1336ee1a6.xml b/tests/expected/suites_csw30_get_1869e495-1a61-4713-8285-76d1336ee1a6.xml
new file mode 100644
index 0000000..42a76d4
--- /dev/null
+++ b/tests/expected/suites_csw30_get_1869e495-1a61-4713-8285-76d1336ee1a6.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- PYCSW_VERSION -->
+<ows20:ExceptionReport xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:ows20="http://www.opengis.net/ows/2.0" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="3.0.0" xml:lang="en-US" xsi:schemaLocation="http://www.opengis. [...]
+  <ows20:Exception exceptionCode="MissingParameterValue" locator="service">
+    <ows20:ExceptionText>Missing keyword: service</ows20:ExceptionText>
+  </ows20:Exception>
+</ows20:ExceptionReport>
diff --git a/tests/expected/suites_csw30_get_1bcb42a9-538c-4f0a-9d4c-d6f10b720aa6.xml b/tests/expected/suites_csw30_get_1bcb42a9-538c-4f0a-9d4c-d6f10b720aa6.xml
new file mode 100644
index 0000000..dd5dfc6
--- /dev/null
+++ b/tests/expected/suites_csw30_get_1bcb42a9-538c-4f0a-9d4c-d6f10b720aa6.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- PYCSW_VERSION -->
+<ows20:ExceptionReport xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:ows20="http://www.opengis.net/ows/2.0" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="3.0.0" xml:lang="en-US" xsi:schemaLocation="http://www.opengis. [...]
+  <ows20:Exception exceptionCode="MissingParameterValue" locator="id">
+    <ows20:ExceptionText>Missing id parameter</ows20:ExceptionText>
+  </ows20:Exception>
+</ows20:ExceptionReport>
diff --git a/tests/expected/suites_csw30_get_22f44168-2ccf-4801-ad96-204212566d56.xml b/tests/expected/suites_csw30_get_22f44168-2ccf-4801-ad96-204212566d56.xml
new file mode 100644
index 0000000..ce9c935
--- /dev/null
+++ b/tests/expected/suites_csw30_get_22f44168-2ccf-4801-ad96-204212566d56.xml
@@ -0,0 +1,491 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- PYCSW_VERSION -->
+<csw30:Capabilities xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:csw30="http://www.opengis.net/cat/csw/3.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:fes20="http://www.opengis.net/fes/2.0" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:ows11="http://www.opengis.net/ows/1.1" xmlns:ows20="http://www.opengis.net/ows/2.0" xmlns:xlink="http://www.w3.org/199 [...]
+  <ows20:ServiceIdentification>
+    <ows20:Title>pycsw Geospatial Catalogue</ows20:Title>
+    <ows20:Abstract>pycsw is an OGC CSW server implementation written in Python</ows20:Abstract>
+    <ows20:Keywords>
+      <ows20:Keyword>catalogue</ows20:Keyword>
+      <ows20:Keyword>discovery</ows20:Keyword>
+      <ows20:Type codeSpace="ISOTC211/19115">theme</ows20:Type>
+    </ows20:Keywords>
+    <ows20:ServiceType codeSpace="OGC">CSW</ows20:ServiceType>
+    <ows20:ServiceTypeVersion>2.0.2</ows20:ServiceTypeVersion>
+    <ows20:ServiceTypeVersion>3.0.0</ows20:ServiceTypeVersion>
+    <ows20:Fees>None</ows20:Fees>
+    <ows20:AccessConstraints>None</ows20:AccessConstraints>
+  </ows20:ServiceIdentification>
+  <ows20:ServiceProvider>
+    <ows20:ProviderName>pycsw</ows20:ProviderName>
+    <ows20:ProviderSite xlink:type="simple" xlink:href="http://pycsw.org/"/>
+    <ows20:ServiceContact>
+      <ows20:IndividualName>Kralidis, Tom</ows20:IndividualName>
+      <ows20:PositionName>Senior Systems Scientist</ows20:PositionName>
+      <ows20:ContactInfo>
+        <ows20:Phone>
+          <ows20:Voice>+01-416-xxx-xxxx</ows20:Voice>
+          <ows20:Facsimile>+01-416-xxx-xxxx</ows20:Facsimile>
+        </ows20:Phone>
+        <ows20:Address>
+          <ows20:DeliveryPoint>TBA</ows20:DeliveryPoint>
+          <ows20:City>Toronto</ows20:City>
+          <ows20:AdministrativeArea>Ontario</ows20:AdministrativeArea>
+          <ows20:PostalCode>M9C 3Z9</ows20:PostalCode>
+          <ows20:Country>Canada</ows20:Country>
+          <ows20:ElectronicMailAddress>tomkralidis at gmail.com</ows20:ElectronicMailAddress>
+        </ows20:Address>
+        <ows20:OnlineResource xlink:type="simple" xlink:href="http://kralidis.ca/"/>
+        <ows20:HoursOfService>0800h - 1600h EST</ows20:HoursOfService>
+        <ows20:ContactInstructions>During hours of service.  Off on weekends.</ows20:ContactInstructions>
+      </ows20:ContactInfo>
+      <ows20:Role codeSpace="ISOTC211/19115">pointOfContact</ows20:Role>
+    </ows20:ServiceContact>
+  </ows20:ServiceProvider>
+  <ows20:OperationsMetadata>
+    <ows20:Operation name="GetCapabilities">
+      <ows20:DCP>
+        <ows20:HTTP>
+          <ows20:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg"/>
+          <ows20:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg"/>
+        </ows20:HTTP>
+      </ows20:DCP>
+      <ows20:Parameter name="acceptFormats">
+        <ows20:AllowedValues>
+          <ows20:Value>application/xml</ows20:Value>
+          <ows20:Value>text/xml</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Parameter name="acceptVersions">
+        <ows20:AllowedValues>
+          <ows20:Value>2.0.2</ows20:Value>
+          <ows20:Value>3.0.0</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Parameter name="sections">
+        <ows20:AllowedValues>
+          <ows20:Value>All</ows20:Value>
+          <ows20:Value>Filter_Capabilities</ows20:Value>
+          <ows20:Value>OperationsMetadata</ows20:Value>
+          <ows20:Value>ServiceIdentification</ows20:Value>
+          <ows20:Value>ServiceProvider</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+    </ows20:Operation>
+    <ows20:Operation name="GetDomain">
+      <ows20:DCP>
+        <ows20:HTTP>
+          <ows20:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg"/>
+          <ows20:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg"/>
+        </ows20:HTTP>
+      </ows20:DCP>
+      <ows20:Parameter name="ParameterName">
+        <ows20:AllowedValues>
+          <ows20:Value>GetCapabilities.acceptFormats</ows20:Value>
+          <ows20:Value>GetCapabilities.acceptVersions</ows20:Value>
+          <ows20:Value>GetCapabilities.sections</ows20:Value>
+          <ows20:Value>GetRecordById.ElementSetName</ows20:Value>
+          <ows20:Value>GetRecordById.outputFormat</ows20:Value>
+          <ows20:Value>GetRecordById.outputSchema</ows20:Value>
+          <ows20:Value>GetRecords.CONSTRAINTLANGUAGE</ows20:Value>
+          <ows20:Value>GetRecords.ElementSetName</ows20:Value>
+          <ows20:Value>GetRecords.outputFormat</ows20:Value>
+          <ows20:Value>GetRecords.outputSchema</ows20:Value>
+          <ows20:Value>GetRecords.typeNames</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+    </ows20:Operation>
+    <ows20:Operation name="GetRecords">
+      <ows20:DCP>
+        <ows20:HTTP>
+          <ows20:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg"/>
+          <ows20:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg"/>
+        </ows20:HTTP>
+      </ows20:DCP>
+      <ows20:Parameter name="CONSTRAINTLANGUAGE">
+        <ows20:AllowedValues>
+          <ows20:Value>CQL_TEXT</ows20:Value>
+          <ows20:Value>FILTER</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Parameter name="ElementSetName">
+        <ows20:AllowedValues>
+          <ows20:Value>brief</ows20:Value>
+          <ows20:Value>full</ows20:Value>
+          <ows20:Value>summary</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Parameter name="outputFormat">
+        <ows20:AllowedValues>
+          <ows20:Value>application/atom+xml</ows20:Value>
+          <ows20:Value>application/json</ows20:Value>
+          <ows20:Value>application/xml</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Parameter name="outputSchema">
+        <ows20:AllowedValues>
+          <ows20:Value>http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/</ows20:Value>
+          <ows20:Value>http://www.interlis.ch/INTERLIS2.3</ows20:Value>
+          <ows20:Value>http://www.opengis.net/cat/csw/3.0</ows20:Value>
+          <ows20:Value>http://www.opengis.net/cat/csw/csdgm</ows20:Value>
+          <ows20:Value>http://www.w3.org/2005/Atom</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Parameter name="typeNames">
+        <ows20:AllowedValues>
+          <ows20:Value>csw:Record</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Constraint name="MaxRecordDefault">
+        <ows20:AllowedValues>
+          <ows20:Value>10</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Constraint>
+      <ows20:Constraint name="OpenSearchDescriptionDocument">
+        <ows20:AllowedValues>
+          <ows20:Value>http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg?mode=opensearch&service=CSW&version=3.0.0&request=GetCapabilities</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Constraint>
+      <ows20:Constraint name="FederatedCatalogues">
+        <ows20:AllowedValues>
+          <ows20:Value>http://demo.pycsw.org/gisdata/csw</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Constraint>
+    </ows20:Operation>
+    <ows20:Operation name="GetRecordById">
+      <ows20:DCP>
+        <ows20:HTTP>
+          <ows20:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg"/>
+          <ows20:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg"/>
+        </ows20:HTTP>
+      </ows20:DCP>
+      <ows20:Parameter name="ElementSetName">
+        <ows20:AllowedValues>
+          <ows20:Value>brief</ows20:Value>
+          <ows20:Value>full</ows20:Value>
+          <ows20:Value>summary</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Parameter name="outputFormat">
+        <ows20:AllowedValues>
+          <ows20:Value>application/atom+xml</ows20:Value>
+          <ows20:Value>application/json</ows20:Value>
+          <ows20:Value>application/xml</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Parameter name="outputSchema">
+        <ows20:AllowedValues>
+          <ows20:Value>http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/</ows20:Value>
+          <ows20:Value>http://www.interlis.ch/INTERLIS2.3</ows20:Value>
+          <ows20:Value>http://www.opengis.net/cat/csw/3.0</ows20:Value>
+          <ows20:Value>http://www.opengis.net/cat/csw/csdgm</ows20:Value>
+          <ows20:Value>http://www.w3.org/2005/Atom</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+    </ows20:Operation>
+    <ows20:Operation name="GetRepositoryItem">
+      <ows20:DCP>
+        <ows20:HTTP>
+          <ows20:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg"/>
+        </ows20:HTTP>
+      </ows20:DCP>
+    </ows20:Operation>
+    <ows20:Parameter name="service">
+      <ows20:AllowedValues>
+        <ows20:Value>CSW</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Parameter>
+    <ows20:Parameter name="version">
+      <ows20:AllowedValues>
+        <ows20:Value>2.0.2</ows20:Value>
+        <ows20:Value>3.0.0</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Parameter>
+    <ows20:Constraint name="CoreQueryables">
+      <ows20:AllowedValues>
+        <ows20:Value>csw:AnyText</ows20:Value>
+        <ows20:Value>dc:contributor</ows20:Value>
+        <ows20:Value>dc:creator</ows20:Value>
+        <ows20:Value>dc:date</ows20:Value>
+        <ows20:Value>dc:format</ows20:Value>
+        <ows20:Value>dc:identifier</ows20:Value>
+        <ows20:Value>dc:language</ows20:Value>
+        <ows20:Value>dc:publisher</ows20:Value>
+        <ows20:Value>dc:relation</ows20:Value>
+        <ows20:Value>dc:rights</ows20:Value>
+        <ows20:Value>dc:source</ows20:Value>
+        <ows20:Value>dc:subject</ows20:Value>
+        <ows20:Value>dc:title</ows20:Value>
+        <ows20:Value>dc:type</ows20:Value>
+        <ows20:Value>dct:abstract</ows20:Value>
+        <ows20:Value>dct:modified</ows20:Value>
+        <ows20:Value>ows:BoundingBox</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="FederatedCatalogues">
+      <ows20:AllowedValues>
+        <ows20:Value>http://demo.pycsw.org/gisdata/csw</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="MaxRecordDefault">
+      <ows20:AllowedValues>
+        <ows20:Value>10</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="PostEncoding">
+      <ows20:AllowedValues>
+        <ows20:Value>SOAP</ows20:Value>
+        <ows20:Value>XML</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="XPathQueryables">
+      <ows20:AllowedValues>
+        <ows20:Value>allowed</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/CoreQueryables">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/CoreSortables">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/DefaultSortingAlgorithm">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Filter-CQL">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Filter-FES-KVP-Advanced">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Filter-FES-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetCapabilities-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetDomain-KVP">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetDomain-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetRecordById-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetRecords-Async-KVP">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetRecords-Async-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetRecords-Basic-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetRecords-Distributed-KVP">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetRecords-Distributed-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Harvest-Async-KVP">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Harvest-Async-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Harvest-Basic-KVP">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Harvest-Basic-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Harvest-Periodic-KVP">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Harvest-Periodic-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/OpenSearch">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/SupportedGMLVersions">
+      <ows20:AllowedValues>
+        <ows20:Value>http://www.opengis.net/gml</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Transaction">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+  </ows20:OperationsMetadata>
+  <ows20:Languages>
+    <ows20:Language>en</ows20:Language>
+  </ows20:Languages>
+  <fes20:Filter_Capabilities>
+    <fes20:Conformance>
+      <fes20:Constraint name="ImplementsQuery">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsAdHocQuery">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsFunctions">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsResourceld">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsMinStandardFilter">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsStandardFilter">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsMinSpatialFilter">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsSpatialFilter">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsMinTemporalFilter">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsTemporalFilter">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsVersionNav">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsSorting">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsExtendedOperators">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsMinimumXPath">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsSchemaElementFunc">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+    </fes20:Conformance>
+    <fes20:Id_Capabilities>
+      <fes20:ResourceIdentifier name="csw30:id"/>
+    </fes20:Id_Capabilities>
+    <fes20:Scalar_Capabilities>
+      <fes20:LogicalOperators/>
+      <fes20:ComparisonOperators>
+        <fes20:ComparisonOperator name="PropertyIsBetween"/>
+        <fes20:ComparisonOperator name="PropertyIsEqualTo"/>
+        <fes20:ComparisonOperator name="PropertyIsGreaterThan"/>
+        <fes20:ComparisonOperator name="PropertyIsGreaterThanOrEqualTo"/>
+        <fes20:ComparisonOperator name="PropertyIsLessThan"/>
+        <fes20:ComparisonOperator name="PropertyIsLessThanOrEqualTo"/>
+        <fes20:ComparisonOperator name="PropertyIsLike"/>
+        <fes20:ComparisonOperator name="PropertyIsNotEqualTo"/>
+        <fes20:ComparisonOperator name="PropertyIsNull"/>
+      </fes20:ComparisonOperators>
+    </fes20:Scalar_Capabilities>
+    <fes20:Spatial_Capabilities>
+      <fes20:GeometryOperands>
+        <fes20:GeometryOperand name="gml:Point"/>
+        <fes20:GeometryOperand name="gml:LineString"/>
+        <fes20:GeometryOperand name="gml:Polygon"/>
+        <fes20:GeometryOperand name="gml:Envelope"/>
+      </fes20:GeometryOperands>
+      <fes20:SpatialOperators>
+        <fes20:SpatialOperator name="BBOX"/>
+        <fes20:SpatialOperator name="Beyond"/>
+        <fes20:SpatialOperator name="Contains"/>
+        <fes20:SpatialOperator name="Crosses"/>
+        <fes20:SpatialOperator name="Disjoint"/>
+        <fes20:SpatialOperator name="DWithin"/>
+        <fes20:SpatialOperator name="Equals"/>
+        <fes20:SpatialOperator name="Intersects"/>
+        <fes20:SpatialOperator name="Overlaps"/>
+        <fes20:SpatialOperator name="Touches"/>
+        <fes20:SpatialOperator name="Within"/>
+      </fes20:SpatialOperators>
+    </fes20:Spatial_Capabilities>
+    <fes20:Functions>
+      <fes20:Function name="length">
+        <fes20:Returns>xs:string</fes20:Returns>
+      </fes20:Function>
+      <fes20:Function name="lower">
+        <fes20:Returns>xs:string</fes20:Returns>
+      </fes20:Function>
+      <fes20:Function name="ltrim">
+        <fes20:Returns>xs:string</fes20:Returns>
+      </fes20:Function>
+      <fes20:Function name="rtrim">
+        <fes20:Returns>xs:string</fes20:Returns>
+      </fes20:Function>
+      <fes20:Function name="trim">
+        <fes20:Returns>xs:string</fes20:Returns>
+      </fes20:Function>
+      <fes20:Function name="upper">
+        <fes20:Returns>xs:string</fes20:Returns>
+      </fes20:Function>
+    </fes20:Functions>
+  </fes20:Filter_Capabilities>
+</csw30:Capabilities>
diff --git a/tests/expected/suites_csw30_get_2499a9c9-8d33-449c-bc92-d494adfcc84d.xml b/tests/expected/suites_csw30_get_2499a9c9-8d33-449c-bc92-d494adfcc84d.xml
new file mode 100644
index 0000000..ce9c935
--- /dev/null
+++ b/tests/expected/suites_csw30_get_2499a9c9-8d33-449c-bc92-d494adfcc84d.xml
@@ -0,0 +1,491 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- PYCSW_VERSION -->
+<csw30:Capabilities xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:csw30="http://www.opengis.net/cat/csw/3.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:fes20="http://www.opengis.net/fes/2.0" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:ows11="http://www.opengis.net/ows/1.1" xmlns:ows20="http://www.opengis.net/ows/2.0" xmlns:xlink="http://www.w3.org/199 [...]
+  <ows20:ServiceIdentification>
+    <ows20:Title>pycsw Geospatial Catalogue</ows20:Title>
+    <ows20:Abstract>pycsw is an OGC CSW server implementation written in Python</ows20:Abstract>
+    <ows20:Keywords>
+      <ows20:Keyword>catalogue</ows20:Keyword>
+      <ows20:Keyword>discovery</ows20:Keyword>
+      <ows20:Type codeSpace="ISOTC211/19115">theme</ows20:Type>
+    </ows20:Keywords>
+    <ows20:ServiceType codeSpace="OGC">CSW</ows20:ServiceType>
+    <ows20:ServiceTypeVersion>2.0.2</ows20:ServiceTypeVersion>
+    <ows20:ServiceTypeVersion>3.0.0</ows20:ServiceTypeVersion>
+    <ows20:Fees>None</ows20:Fees>
+    <ows20:AccessConstraints>None</ows20:AccessConstraints>
+  </ows20:ServiceIdentification>
+  <ows20:ServiceProvider>
+    <ows20:ProviderName>pycsw</ows20:ProviderName>
+    <ows20:ProviderSite xlink:type="simple" xlink:href="http://pycsw.org/"/>
+    <ows20:ServiceContact>
+      <ows20:IndividualName>Kralidis, Tom</ows20:IndividualName>
+      <ows20:PositionName>Senior Systems Scientist</ows20:PositionName>
+      <ows20:ContactInfo>
+        <ows20:Phone>
+          <ows20:Voice>+01-416-xxx-xxxx</ows20:Voice>
+          <ows20:Facsimile>+01-416-xxx-xxxx</ows20:Facsimile>
+        </ows20:Phone>
+        <ows20:Address>
+          <ows20:DeliveryPoint>TBA</ows20:DeliveryPoint>
+          <ows20:City>Toronto</ows20:City>
+          <ows20:AdministrativeArea>Ontario</ows20:AdministrativeArea>
+          <ows20:PostalCode>M9C 3Z9</ows20:PostalCode>
+          <ows20:Country>Canada</ows20:Country>
+          <ows20:ElectronicMailAddress>tomkralidis at gmail.com</ows20:ElectronicMailAddress>
+        </ows20:Address>
+        <ows20:OnlineResource xlink:type="simple" xlink:href="http://kralidis.ca/"/>
+        <ows20:HoursOfService>0800h - 1600h EST</ows20:HoursOfService>
+        <ows20:ContactInstructions>During hours of service.  Off on weekends.</ows20:ContactInstructions>
+      </ows20:ContactInfo>
+      <ows20:Role codeSpace="ISOTC211/19115">pointOfContact</ows20:Role>
+    </ows20:ServiceContact>
+  </ows20:ServiceProvider>
+  <ows20:OperationsMetadata>
+    <ows20:Operation name="GetCapabilities">
+      <ows20:DCP>
+        <ows20:HTTP>
+          <ows20:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg"/>
+          <ows20:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg"/>
+        </ows20:HTTP>
+      </ows20:DCP>
+      <ows20:Parameter name="acceptFormats">
+        <ows20:AllowedValues>
+          <ows20:Value>application/xml</ows20:Value>
+          <ows20:Value>text/xml</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Parameter name="acceptVersions">
+        <ows20:AllowedValues>
+          <ows20:Value>2.0.2</ows20:Value>
+          <ows20:Value>3.0.0</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Parameter name="sections">
+        <ows20:AllowedValues>
+          <ows20:Value>All</ows20:Value>
+          <ows20:Value>Filter_Capabilities</ows20:Value>
+          <ows20:Value>OperationsMetadata</ows20:Value>
+          <ows20:Value>ServiceIdentification</ows20:Value>
+          <ows20:Value>ServiceProvider</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+    </ows20:Operation>
+    <ows20:Operation name="GetDomain">
+      <ows20:DCP>
+        <ows20:HTTP>
+          <ows20:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg"/>
+          <ows20:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg"/>
+        </ows20:HTTP>
+      </ows20:DCP>
+      <ows20:Parameter name="ParameterName">
+        <ows20:AllowedValues>
+          <ows20:Value>GetCapabilities.acceptFormats</ows20:Value>
+          <ows20:Value>GetCapabilities.acceptVersions</ows20:Value>
+          <ows20:Value>GetCapabilities.sections</ows20:Value>
+          <ows20:Value>GetRecordById.ElementSetName</ows20:Value>
+          <ows20:Value>GetRecordById.outputFormat</ows20:Value>
+          <ows20:Value>GetRecordById.outputSchema</ows20:Value>
+          <ows20:Value>GetRecords.CONSTRAINTLANGUAGE</ows20:Value>
+          <ows20:Value>GetRecords.ElementSetName</ows20:Value>
+          <ows20:Value>GetRecords.outputFormat</ows20:Value>
+          <ows20:Value>GetRecords.outputSchema</ows20:Value>
+          <ows20:Value>GetRecords.typeNames</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+    </ows20:Operation>
+    <ows20:Operation name="GetRecords">
+      <ows20:DCP>
+        <ows20:HTTP>
+          <ows20:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg"/>
+          <ows20:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg"/>
+        </ows20:HTTP>
+      </ows20:DCP>
+      <ows20:Parameter name="CONSTRAINTLANGUAGE">
+        <ows20:AllowedValues>
+          <ows20:Value>CQL_TEXT</ows20:Value>
+          <ows20:Value>FILTER</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Parameter name="ElementSetName">
+        <ows20:AllowedValues>
+          <ows20:Value>brief</ows20:Value>
+          <ows20:Value>full</ows20:Value>
+          <ows20:Value>summary</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Parameter name="outputFormat">
+        <ows20:AllowedValues>
+          <ows20:Value>application/atom+xml</ows20:Value>
+          <ows20:Value>application/json</ows20:Value>
+          <ows20:Value>application/xml</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Parameter name="outputSchema">
+        <ows20:AllowedValues>
+          <ows20:Value>http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/</ows20:Value>
+          <ows20:Value>http://www.interlis.ch/INTERLIS2.3</ows20:Value>
+          <ows20:Value>http://www.opengis.net/cat/csw/3.0</ows20:Value>
+          <ows20:Value>http://www.opengis.net/cat/csw/csdgm</ows20:Value>
+          <ows20:Value>http://www.w3.org/2005/Atom</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Parameter name="typeNames">
+        <ows20:AllowedValues>
+          <ows20:Value>csw:Record</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Constraint name="MaxRecordDefault">
+        <ows20:AllowedValues>
+          <ows20:Value>10</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Constraint>
+      <ows20:Constraint name="OpenSearchDescriptionDocument">
+        <ows20:AllowedValues>
+          <ows20:Value>http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg?mode=opensearch&service=CSW&version=3.0.0&request=GetCapabilities</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Constraint>
+      <ows20:Constraint name="FederatedCatalogues">
+        <ows20:AllowedValues>
+          <ows20:Value>http://demo.pycsw.org/gisdata/csw</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Constraint>
+    </ows20:Operation>
+    <ows20:Operation name="GetRecordById">
+      <ows20:DCP>
+        <ows20:HTTP>
+          <ows20:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg"/>
+          <ows20:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg"/>
+        </ows20:HTTP>
+      </ows20:DCP>
+      <ows20:Parameter name="ElementSetName">
+        <ows20:AllowedValues>
+          <ows20:Value>brief</ows20:Value>
+          <ows20:Value>full</ows20:Value>
+          <ows20:Value>summary</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Parameter name="outputFormat">
+        <ows20:AllowedValues>
+          <ows20:Value>application/atom+xml</ows20:Value>
+          <ows20:Value>application/json</ows20:Value>
+          <ows20:Value>application/xml</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Parameter name="outputSchema">
+        <ows20:AllowedValues>
+          <ows20:Value>http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/</ows20:Value>
+          <ows20:Value>http://www.interlis.ch/INTERLIS2.3</ows20:Value>
+          <ows20:Value>http://www.opengis.net/cat/csw/3.0</ows20:Value>
+          <ows20:Value>http://www.opengis.net/cat/csw/csdgm</ows20:Value>
+          <ows20:Value>http://www.w3.org/2005/Atom</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+    </ows20:Operation>
+    <ows20:Operation name="GetRepositoryItem">
+      <ows20:DCP>
+        <ows20:HTTP>
+          <ows20:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg"/>
+        </ows20:HTTP>
+      </ows20:DCP>
+    </ows20:Operation>
+    <ows20:Parameter name="service">
+      <ows20:AllowedValues>
+        <ows20:Value>CSW</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Parameter>
+    <ows20:Parameter name="version">
+      <ows20:AllowedValues>
+        <ows20:Value>2.0.2</ows20:Value>
+        <ows20:Value>3.0.0</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Parameter>
+    <ows20:Constraint name="CoreQueryables">
+      <ows20:AllowedValues>
+        <ows20:Value>csw:AnyText</ows20:Value>
+        <ows20:Value>dc:contributor</ows20:Value>
+        <ows20:Value>dc:creator</ows20:Value>
+        <ows20:Value>dc:date</ows20:Value>
+        <ows20:Value>dc:format</ows20:Value>
+        <ows20:Value>dc:identifier</ows20:Value>
+        <ows20:Value>dc:language</ows20:Value>
+        <ows20:Value>dc:publisher</ows20:Value>
+        <ows20:Value>dc:relation</ows20:Value>
+        <ows20:Value>dc:rights</ows20:Value>
+        <ows20:Value>dc:source</ows20:Value>
+        <ows20:Value>dc:subject</ows20:Value>
+        <ows20:Value>dc:title</ows20:Value>
+        <ows20:Value>dc:type</ows20:Value>
+        <ows20:Value>dct:abstract</ows20:Value>
+        <ows20:Value>dct:modified</ows20:Value>
+        <ows20:Value>ows:BoundingBox</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="FederatedCatalogues">
+      <ows20:AllowedValues>
+        <ows20:Value>http://demo.pycsw.org/gisdata/csw</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="MaxRecordDefault">
+      <ows20:AllowedValues>
+        <ows20:Value>10</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="PostEncoding">
+      <ows20:AllowedValues>
+        <ows20:Value>SOAP</ows20:Value>
+        <ows20:Value>XML</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="XPathQueryables">
+      <ows20:AllowedValues>
+        <ows20:Value>allowed</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/CoreQueryables">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/CoreSortables">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/DefaultSortingAlgorithm">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Filter-CQL">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Filter-FES-KVP-Advanced">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Filter-FES-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetCapabilities-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetDomain-KVP">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetDomain-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetRecordById-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetRecords-Async-KVP">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetRecords-Async-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetRecords-Basic-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetRecords-Distributed-KVP">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetRecords-Distributed-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Harvest-Async-KVP">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Harvest-Async-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Harvest-Basic-KVP">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Harvest-Basic-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Harvest-Periodic-KVP">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Harvest-Periodic-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/OpenSearch">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/SupportedGMLVersions">
+      <ows20:AllowedValues>
+        <ows20:Value>http://www.opengis.net/gml</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Transaction">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+  </ows20:OperationsMetadata>
+  <ows20:Languages>
+    <ows20:Language>en</ows20:Language>
+  </ows20:Languages>
+  <fes20:Filter_Capabilities>
+    <fes20:Conformance>
+      <fes20:Constraint name="ImplementsQuery">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsAdHocQuery">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsFunctions">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsResourceld">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsMinStandardFilter">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsStandardFilter">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsMinSpatialFilter">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsSpatialFilter">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsMinTemporalFilter">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsTemporalFilter">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsVersionNav">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsSorting">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsExtendedOperators">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsMinimumXPath">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsSchemaElementFunc">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+    </fes20:Conformance>
+    <fes20:Id_Capabilities>
+      <fes20:ResourceIdentifier name="csw30:id"/>
+    </fes20:Id_Capabilities>
+    <fes20:Scalar_Capabilities>
+      <fes20:LogicalOperators/>
+      <fes20:ComparisonOperators>
+        <fes20:ComparisonOperator name="PropertyIsBetween"/>
+        <fes20:ComparisonOperator name="PropertyIsEqualTo"/>
+        <fes20:ComparisonOperator name="PropertyIsGreaterThan"/>
+        <fes20:ComparisonOperator name="PropertyIsGreaterThanOrEqualTo"/>
+        <fes20:ComparisonOperator name="PropertyIsLessThan"/>
+        <fes20:ComparisonOperator name="PropertyIsLessThanOrEqualTo"/>
+        <fes20:ComparisonOperator name="PropertyIsLike"/>
+        <fes20:ComparisonOperator name="PropertyIsNotEqualTo"/>
+        <fes20:ComparisonOperator name="PropertyIsNull"/>
+      </fes20:ComparisonOperators>
+    </fes20:Scalar_Capabilities>
+    <fes20:Spatial_Capabilities>
+      <fes20:GeometryOperands>
+        <fes20:GeometryOperand name="gml:Point"/>
+        <fes20:GeometryOperand name="gml:LineString"/>
+        <fes20:GeometryOperand name="gml:Polygon"/>
+        <fes20:GeometryOperand name="gml:Envelope"/>
+      </fes20:GeometryOperands>
+      <fes20:SpatialOperators>
+        <fes20:SpatialOperator name="BBOX"/>
+        <fes20:SpatialOperator name="Beyond"/>
+        <fes20:SpatialOperator name="Contains"/>
+        <fes20:SpatialOperator name="Crosses"/>
+        <fes20:SpatialOperator name="Disjoint"/>
+        <fes20:SpatialOperator name="DWithin"/>
+        <fes20:SpatialOperator name="Equals"/>
+        <fes20:SpatialOperator name="Intersects"/>
+        <fes20:SpatialOperator name="Overlaps"/>
+        <fes20:SpatialOperator name="Touches"/>
+        <fes20:SpatialOperator name="Within"/>
+      </fes20:SpatialOperators>
+    </fes20:Spatial_Capabilities>
+    <fes20:Functions>
+      <fes20:Function name="length">
+        <fes20:Returns>xs:string</fes20:Returns>
+      </fes20:Function>
+      <fes20:Function name="lower">
+        <fes20:Returns>xs:string</fes20:Returns>
+      </fes20:Function>
+      <fes20:Function name="ltrim">
+        <fes20:Returns>xs:string</fes20:Returns>
+      </fes20:Function>
+      <fes20:Function name="rtrim">
+        <fes20:Returns>xs:string</fes20:Returns>
+      </fes20:Function>
+      <fes20:Function name="trim">
+        <fes20:Returns>xs:string</fes20:Returns>
+      </fes20:Function>
+      <fes20:Function name="upper">
+        <fes20:Returns>xs:string</fes20:Returns>
+      </fes20:Function>
+    </fes20:Functions>
+  </fes20:Filter_Capabilities>
+</csw30:Capabilities>
diff --git a/tests/expected/suites_csw30_get_27f4f39c-d92a-4e3c-b961-c6aa8c24e513.xml b/tests/expected/suites_csw30_get_27f4f39c-d92a-4e3c-b961-c6aa8c24e513.xml
new file mode 100644
index 0000000..ce9c935
--- /dev/null
+++ b/tests/expected/suites_csw30_get_27f4f39c-d92a-4e3c-b961-c6aa8c24e513.xml
@@ -0,0 +1,491 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- PYCSW_VERSION -->
+<csw30:Capabilities xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:csw30="http://www.opengis.net/cat/csw/3.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:fes20="http://www.opengis.net/fes/2.0" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:ows11="http://www.opengis.net/ows/1.1" xmlns:ows20="http://www.opengis.net/ows/2.0" xmlns:xlink="http://www.w3.org/199 [...]
+  <ows20:ServiceIdentification>
+    <ows20:Title>pycsw Geospatial Catalogue</ows20:Title>
+    <ows20:Abstract>pycsw is an OGC CSW server implementation written in Python</ows20:Abstract>
+    <ows20:Keywords>
+      <ows20:Keyword>catalogue</ows20:Keyword>
+      <ows20:Keyword>discovery</ows20:Keyword>
+      <ows20:Type codeSpace="ISOTC211/19115">theme</ows20:Type>
+    </ows20:Keywords>
+    <ows20:ServiceType codeSpace="OGC">CSW</ows20:ServiceType>
+    <ows20:ServiceTypeVersion>2.0.2</ows20:ServiceTypeVersion>
+    <ows20:ServiceTypeVersion>3.0.0</ows20:ServiceTypeVersion>
+    <ows20:Fees>None</ows20:Fees>
+    <ows20:AccessConstraints>None</ows20:AccessConstraints>
+  </ows20:ServiceIdentification>
+  <ows20:ServiceProvider>
+    <ows20:ProviderName>pycsw</ows20:ProviderName>
+    <ows20:ProviderSite xlink:type="simple" xlink:href="http://pycsw.org/"/>
+    <ows20:ServiceContact>
+      <ows20:IndividualName>Kralidis, Tom</ows20:IndividualName>
+      <ows20:PositionName>Senior Systems Scientist</ows20:PositionName>
+      <ows20:ContactInfo>
+        <ows20:Phone>
+          <ows20:Voice>+01-416-xxx-xxxx</ows20:Voice>
+          <ows20:Facsimile>+01-416-xxx-xxxx</ows20:Facsimile>
+        </ows20:Phone>
+        <ows20:Address>
+          <ows20:DeliveryPoint>TBA</ows20:DeliveryPoint>
+          <ows20:City>Toronto</ows20:City>
+          <ows20:AdministrativeArea>Ontario</ows20:AdministrativeArea>
+          <ows20:PostalCode>M9C 3Z9</ows20:PostalCode>
+          <ows20:Country>Canada</ows20:Country>
+          <ows20:ElectronicMailAddress>tomkralidis at gmail.com</ows20:ElectronicMailAddress>
+        </ows20:Address>
+        <ows20:OnlineResource xlink:type="simple" xlink:href="http://kralidis.ca/"/>
+        <ows20:HoursOfService>0800h - 1600h EST</ows20:HoursOfService>
+        <ows20:ContactInstructions>During hours of service.  Off on weekends.</ows20:ContactInstructions>
+      </ows20:ContactInfo>
+      <ows20:Role codeSpace="ISOTC211/19115">pointOfContact</ows20:Role>
+    </ows20:ServiceContact>
+  </ows20:ServiceProvider>
+  <ows20:OperationsMetadata>
+    <ows20:Operation name="GetCapabilities">
+      <ows20:DCP>
+        <ows20:HTTP>
+          <ows20:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg"/>
+          <ows20:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg"/>
+        </ows20:HTTP>
+      </ows20:DCP>
+      <ows20:Parameter name="acceptFormats">
+        <ows20:AllowedValues>
+          <ows20:Value>application/xml</ows20:Value>
+          <ows20:Value>text/xml</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Parameter name="acceptVersions">
+        <ows20:AllowedValues>
+          <ows20:Value>2.0.2</ows20:Value>
+          <ows20:Value>3.0.0</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Parameter name="sections">
+        <ows20:AllowedValues>
+          <ows20:Value>All</ows20:Value>
+          <ows20:Value>Filter_Capabilities</ows20:Value>
+          <ows20:Value>OperationsMetadata</ows20:Value>
+          <ows20:Value>ServiceIdentification</ows20:Value>
+          <ows20:Value>ServiceProvider</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+    </ows20:Operation>
+    <ows20:Operation name="GetDomain">
+      <ows20:DCP>
+        <ows20:HTTP>
+          <ows20:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg"/>
+          <ows20:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg"/>
+        </ows20:HTTP>
+      </ows20:DCP>
+      <ows20:Parameter name="ParameterName">
+        <ows20:AllowedValues>
+          <ows20:Value>GetCapabilities.acceptFormats</ows20:Value>
+          <ows20:Value>GetCapabilities.acceptVersions</ows20:Value>
+          <ows20:Value>GetCapabilities.sections</ows20:Value>
+          <ows20:Value>GetRecordById.ElementSetName</ows20:Value>
+          <ows20:Value>GetRecordById.outputFormat</ows20:Value>
+          <ows20:Value>GetRecordById.outputSchema</ows20:Value>
+          <ows20:Value>GetRecords.CONSTRAINTLANGUAGE</ows20:Value>
+          <ows20:Value>GetRecords.ElementSetName</ows20:Value>
+          <ows20:Value>GetRecords.outputFormat</ows20:Value>
+          <ows20:Value>GetRecords.outputSchema</ows20:Value>
+          <ows20:Value>GetRecords.typeNames</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+    </ows20:Operation>
+    <ows20:Operation name="GetRecords">
+      <ows20:DCP>
+        <ows20:HTTP>
+          <ows20:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg"/>
+          <ows20:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg"/>
+        </ows20:HTTP>
+      </ows20:DCP>
+      <ows20:Parameter name="CONSTRAINTLANGUAGE">
+        <ows20:AllowedValues>
+          <ows20:Value>CQL_TEXT</ows20:Value>
+          <ows20:Value>FILTER</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Parameter name="ElementSetName">
+        <ows20:AllowedValues>
+          <ows20:Value>brief</ows20:Value>
+          <ows20:Value>full</ows20:Value>
+          <ows20:Value>summary</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Parameter name="outputFormat">
+        <ows20:AllowedValues>
+          <ows20:Value>application/atom+xml</ows20:Value>
+          <ows20:Value>application/json</ows20:Value>
+          <ows20:Value>application/xml</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Parameter name="outputSchema">
+        <ows20:AllowedValues>
+          <ows20:Value>http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/</ows20:Value>
+          <ows20:Value>http://www.interlis.ch/INTERLIS2.3</ows20:Value>
+          <ows20:Value>http://www.opengis.net/cat/csw/3.0</ows20:Value>
+          <ows20:Value>http://www.opengis.net/cat/csw/csdgm</ows20:Value>
+          <ows20:Value>http://www.w3.org/2005/Atom</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Parameter name="typeNames">
+        <ows20:AllowedValues>
+          <ows20:Value>csw:Record</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Constraint name="MaxRecordDefault">
+        <ows20:AllowedValues>
+          <ows20:Value>10</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Constraint>
+      <ows20:Constraint name="OpenSearchDescriptionDocument">
+        <ows20:AllowedValues>
+          <ows20:Value>http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg?mode=opensearch&service=CSW&version=3.0.0&request=GetCapabilities</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Constraint>
+      <ows20:Constraint name="FederatedCatalogues">
+        <ows20:AllowedValues>
+          <ows20:Value>http://demo.pycsw.org/gisdata/csw</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Constraint>
+    </ows20:Operation>
+    <ows20:Operation name="GetRecordById">
+      <ows20:DCP>
+        <ows20:HTTP>
+          <ows20:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg"/>
+          <ows20:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg"/>
+        </ows20:HTTP>
+      </ows20:DCP>
+      <ows20:Parameter name="ElementSetName">
+        <ows20:AllowedValues>
+          <ows20:Value>brief</ows20:Value>
+          <ows20:Value>full</ows20:Value>
+          <ows20:Value>summary</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Parameter name="outputFormat">
+        <ows20:AllowedValues>
+          <ows20:Value>application/atom+xml</ows20:Value>
+          <ows20:Value>application/json</ows20:Value>
+          <ows20:Value>application/xml</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Parameter name="outputSchema">
+        <ows20:AllowedValues>
+          <ows20:Value>http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/</ows20:Value>
+          <ows20:Value>http://www.interlis.ch/INTERLIS2.3</ows20:Value>
+          <ows20:Value>http://www.opengis.net/cat/csw/3.0</ows20:Value>
+          <ows20:Value>http://www.opengis.net/cat/csw/csdgm</ows20:Value>
+          <ows20:Value>http://www.w3.org/2005/Atom</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+    </ows20:Operation>
+    <ows20:Operation name="GetRepositoryItem">
+      <ows20:DCP>
+        <ows20:HTTP>
+          <ows20:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg"/>
+        </ows20:HTTP>
+      </ows20:DCP>
+    </ows20:Operation>
+    <ows20:Parameter name="service">
+      <ows20:AllowedValues>
+        <ows20:Value>CSW</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Parameter>
+    <ows20:Parameter name="version">
+      <ows20:AllowedValues>
+        <ows20:Value>2.0.2</ows20:Value>
+        <ows20:Value>3.0.0</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Parameter>
+    <ows20:Constraint name="CoreQueryables">
+      <ows20:AllowedValues>
+        <ows20:Value>csw:AnyText</ows20:Value>
+        <ows20:Value>dc:contributor</ows20:Value>
+        <ows20:Value>dc:creator</ows20:Value>
+        <ows20:Value>dc:date</ows20:Value>
+        <ows20:Value>dc:format</ows20:Value>
+        <ows20:Value>dc:identifier</ows20:Value>
+        <ows20:Value>dc:language</ows20:Value>
+        <ows20:Value>dc:publisher</ows20:Value>
+        <ows20:Value>dc:relation</ows20:Value>
+        <ows20:Value>dc:rights</ows20:Value>
+        <ows20:Value>dc:source</ows20:Value>
+        <ows20:Value>dc:subject</ows20:Value>
+        <ows20:Value>dc:title</ows20:Value>
+        <ows20:Value>dc:type</ows20:Value>
+        <ows20:Value>dct:abstract</ows20:Value>
+        <ows20:Value>dct:modified</ows20:Value>
+        <ows20:Value>ows:BoundingBox</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="FederatedCatalogues">
+      <ows20:AllowedValues>
+        <ows20:Value>http://demo.pycsw.org/gisdata/csw</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="MaxRecordDefault">
+      <ows20:AllowedValues>
+        <ows20:Value>10</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="PostEncoding">
+      <ows20:AllowedValues>
+        <ows20:Value>SOAP</ows20:Value>
+        <ows20:Value>XML</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="XPathQueryables">
+      <ows20:AllowedValues>
+        <ows20:Value>allowed</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/CoreQueryables">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/CoreSortables">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/DefaultSortingAlgorithm">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Filter-CQL">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Filter-FES-KVP-Advanced">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Filter-FES-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetCapabilities-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetDomain-KVP">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetDomain-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetRecordById-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetRecords-Async-KVP">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetRecords-Async-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetRecords-Basic-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetRecords-Distributed-KVP">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetRecords-Distributed-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Harvest-Async-KVP">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Harvest-Async-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Harvest-Basic-KVP">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Harvest-Basic-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Harvest-Periodic-KVP">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Harvest-Periodic-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/OpenSearch">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/SupportedGMLVersions">
+      <ows20:AllowedValues>
+        <ows20:Value>http://www.opengis.net/gml</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Transaction">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+  </ows20:OperationsMetadata>
+  <ows20:Languages>
+    <ows20:Language>en</ows20:Language>
+  </ows20:Languages>
+  <fes20:Filter_Capabilities>
+    <fes20:Conformance>
+      <fes20:Constraint name="ImplementsQuery">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsAdHocQuery">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsFunctions">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsResourceld">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsMinStandardFilter">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsStandardFilter">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsMinSpatialFilter">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsSpatialFilter">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsMinTemporalFilter">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsTemporalFilter">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsVersionNav">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsSorting">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsExtendedOperators">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsMinimumXPath">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsSchemaElementFunc">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+    </fes20:Conformance>
+    <fes20:Id_Capabilities>
+      <fes20:ResourceIdentifier name="csw30:id"/>
+    </fes20:Id_Capabilities>
+    <fes20:Scalar_Capabilities>
+      <fes20:LogicalOperators/>
+      <fes20:ComparisonOperators>
+        <fes20:ComparisonOperator name="PropertyIsBetween"/>
+        <fes20:ComparisonOperator name="PropertyIsEqualTo"/>
+        <fes20:ComparisonOperator name="PropertyIsGreaterThan"/>
+        <fes20:ComparisonOperator name="PropertyIsGreaterThanOrEqualTo"/>
+        <fes20:ComparisonOperator name="PropertyIsLessThan"/>
+        <fes20:ComparisonOperator name="PropertyIsLessThanOrEqualTo"/>
+        <fes20:ComparisonOperator name="PropertyIsLike"/>
+        <fes20:ComparisonOperator name="PropertyIsNotEqualTo"/>
+        <fes20:ComparisonOperator name="PropertyIsNull"/>
+      </fes20:ComparisonOperators>
+    </fes20:Scalar_Capabilities>
+    <fes20:Spatial_Capabilities>
+      <fes20:GeometryOperands>
+        <fes20:GeometryOperand name="gml:Point"/>
+        <fes20:GeometryOperand name="gml:LineString"/>
+        <fes20:GeometryOperand name="gml:Polygon"/>
+        <fes20:GeometryOperand name="gml:Envelope"/>
+      </fes20:GeometryOperands>
+      <fes20:SpatialOperators>
+        <fes20:SpatialOperator name="BBOX"/>
+        <fes20:SpatialOperator name="Beyond"/>
+        <fes20:SpatialOperator name="Contains"/>
+        <fes20:SpatialOperator name="Crosses"/>
+        <fes20:SpatialOperator name="Disjoint"/>
+        <fes20:SpatialOperator name="DWithin"/>
+        <fes20:SpatialOperator name="Equals"/>
+        <fes20:SpatialOperator name="Intersects"/>
+        <fes20:SpatialOperator name="Overlaps"/>
+        <fes20:SpatialOperator name="Touches"/>
+        <fes20:SpatialOperator name="Within"/>
+      </fes20:SpatialOperators>
+    </fes20:Spatial_Capabilities>
+    <fes20:Functions>
+      <fes20:Function name="length">
+        <fes20:Returns>xs:string</fes20:Returns>
+      </fes20:Function>
+      <fes20:Function name="lower">
+        <fes20:Returns>xs:string</fes20:Returns>
+      </fes20:Function>
+      <fes20:Function name="ltrim">
+        <fes20:Returns>xs:string</fes20:Returns>
+      </fes20:Function>
+      <fes20:Function name="rtrim">
+        <fes20:Returns>xs:string</fes20:Returns>
+      </fes20:Function>
+      <fes20:Function name="trim">
+        <fes20:Returns>xs:string</fes20:Returns>
+      </fes20:Function>
+      <fes20:Function name="upper">
+        <fes20:Returns>xs:string</fes20:Returns>
+      </fes20:Function>
+    </fes20:Functions>
+  </fes20:Filter_Capabilities>
+</csw30:Capabilities>
diff --git a/tests/expected/suites_csw30_get_28e569df-8596-4128-8d9a-29ad03138915.xml b/tests/expected/suites_csw30_get_28e569df-8596-4128-8d9a-29ad03138915.xml
new file mode 100644
index 0000000..c998b50
--- /dev/null
+++ b/tests/expected/suites_csw30_get_28e569df-8596-4128-8d9a-29ad03138915.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- PYCSW_VERSION -->
+<csw30:SummaryRecord xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:csw30="http://www.opengis.net/cat/csw/3.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema">
+  <dc:identifier>urn:uuid:a06af396-3105-442d-8b40-22b57a90d2f2</dc:identifier>
+  <dc:title>Lorem ipsum dolor sit amet</dc:title>
+  <dc:type>http://purl.org/dc/dcmitype/Image</dc:type>
+  <dc:format>image/jpeg</dc:format>
+</csw30:SummaryRecord>
diff --git a/tests/expected/suites_csw30_get_2b06a5c8-0df2-4af1-8d2e-a425de11c845.xml b/tests/expected/suites_csw30_get_2b06a5c8-0df2-4af1-8d2e-a425de11c845.xml
new file mode 100644
index 0000000..ce9c935
--- /dev/null
+++ b/tests/expected/suites_csw30_get_2b06a5c8-0df2-4af1-8d2e-a425de11c845.xml
@@ -0,0 +1,491 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- PYCSW_VERSION -->
+<csw30:Capabilities xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:csw30="http://www.opengis.net/cat/csw/3.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:fes20="http://www.opengis.net/fes/2.0" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:ows11="http://www.opengis.net/ows/1.1" xmlns:ows20="http://www.opengis.net/ows/2.0" xmlns:xlink="http://www.w3.org/199 [...]
+  <ows20:ServiceIdentification>
+    <ows20:Title>pycsw Geospatial Catalogue</ows20:Title>
+    <ows20:Abstract>pycsw is an OGC CSW server implementation written in Python</ows20:Abstract>
+    <ows20:Keywords>
+      <ows20:Keyword>catalogue</ows20:Keyword>
+      <ows20:Keyword>discovery</ows20:Keyword>
+      <ows20:Type codeSpace="ISOTC211/19115">theme</ows20:Type>
+    </ows20:Keywords>
+    <ows20:ServiceType codeSpace="OGC">CSW</ows20:ServiceType>
+    <ows20:ServiceTypeVersion>2.0.2</ows20:ServiceTypeVersion>
+    <ows20:ServiceTypeVersion>3.0.0</ows20:ServiceTypeVersion>
+    <ows20:Fees>None</ows20:Fees>
+    <ows20:AccessConstraints>None</ows20:AccessConstraints>
+  </ows20:ServiceIdentification>
+  <ows20:ServiceProvider>
+    <ows20:ProviderName>pycsw</ows20:ProviderName>
+    <ows20:ProviderSite xlink:type="simple" xlink:href="http://pycsw.org/"/>
+    <ows20:ServiceContact>
+      <ows20:IndividualName>Kralidis, Tom</ows20:IndividualName>
+      <ows20:PositionName>Senior Systems Scientist</ows20:PositionName>
+      <ows20:ContactInfo>
+        <ows20:Phone>
+          <ows20:Voice>+01-416-xxx-xxxx</ows20:Voice>
+          <ows20:Facsimile>+01-416-xxx-xxxx</ows20:Facsimile>
+        </ows20:Phone>
+        <ows20:Address>
+          <ows20:DeliveryPoint>TBA</ows20:DeliveryPoint>
+          <ows20:City>Toronto</ows20:City>
+          <ows20:AdministrativeArea>Ontario</ows20:AdministrativeArea>
+          <ows20:PostalCode>M9C 3Z9</ows20:PostalCode>
+          <ows20:Country>Canada</ows20:Country>
+          <ows20:ElectronicMailAddress>tomkralidis at gmail.com</ows20:ElectronicMailAddress>
+        </ows20:Address>
+        <ows20:OnlineResource xlink:type="simple" xlink:href="http://kralidis.ca/"/>
+        <ows20:HoursOfService>0800h - 1600h EST</ows20:HoursOfService>
+        <ows20:ContactInstructions>During hours of service.  Off on weekends.</ows20:ContactInstructions>
+      </ows20:ContactInfo>
+      <ows20:Role codeSpace="ISOTC211/19115">pointOfContact</ows20:Role>
+    </ows20:ServiceContact>
+  </ows20:ServiceProvider>
+  <ows20:OperationsMetadata>
+    <ows20:Operation name="GetCapabilities">
+      <ows20:DCP>
+        <ows20:HTTP>
+          <ows20:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg"/>
+          <ows20:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg"/>
+        </ows20:HTTP>
+      </ows20:DCP>
+      <ows20:Parameter name="acceptFormats">
+        <ows20:AllowedValues>
+          <ows20:Value>application/xml</ows20:Value>
+          <ows20:Value>text/xml</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Parameter name="acceptVersions">
+        <ows20:AllowedValues>
+          <ows20:Value>2.0.2</ows20:Value>
+          <ows20:Value>3.0.0</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Parameter name="sections">
+        <ows20:AllowedValues>
+          <ows20:Value>All</ows20:Value>
+          <ows20:Value>Filter_Capabilities</ows20:Value>
+          <ows20:Value>OperationsMetadata</ows20:Value>
+          <ows20:Value>ServiceIdentification</ows20:Value>
+          <ows20:Value>ServiceProvider</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+    </ows20:Operation>
+    <ows20:Operation name="GetDomain">
+      <ows20:DCP>
+        <ows20:HTTP>
+          <ows20:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg"/>
+          <ows20:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg"/>
+        </ows20:HTTP>
+      </ows20:DCP>
+      <ows20:Parameter name="ParameterName">
+        <ows20:AllowedValues>
+          <ows20:Value>GetCapabilities.acceptFormats</ows20:Value>
+          <ows20:Value>GetCapabilities.acceptVersions</ows20:Value>
+          <ows20:Value>GetCapabilities.sections</ows20:Value>
+          <ows20:Value>GetRecordById.ElementSetName</ows20:Value>
+          <ows20:Value>GetRecordById.outputFormat</ows20:Value>
+          <ows20:Value>GetRecordById.outputSchema</ows20:Value>
+          <ows20:Value>GetRecords.CONSTRAINTLANGUAGE</ows20:Value>
+          <ows20:Value>GetRecords.ElementSetName</ows20:Value>
+          <ows20:Value>GetRecords.outputFormat</ows20:Value>
+          <ows20:Value>GetRecords.outputSchema</ows20:Value>
+          <ows20:Value>GetRecords.typeNames</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+    </ows20:Operation>
+    <ows20:Operation name="GetRecords">
+      <ows20:DCP>
+        <ows20:HTTP>
+          <ows20:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg"/>
+          <ows20:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg"/>
+        </ows20:HTTP>
+      </ows20:DCP>
+      <ows20:Parameter name="CONSTRAINTLANGUAGE">
+        <ows20:AllowedValues>
+          <ows20:Value>CQL_TEXT</ows20:Value>
+          <ows20:Value>FILTER</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Parameter name="ElementSetName">
+        <ows20:AllowedValues>
+          <ows20:Value>brief</ows20:Value>
+          <ows20:Value>full</ows20:Value>
+          <ows20:Value>summary</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Parameter name="outputFormat">
+        <ows20:AllowedValues>
+          <ows20:Value>application/atom+xml</ows20:Value>
+          <ows20:Value>application/json</ows20:Value>
+          <ows20:Value>application/xml</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Parameter name="outputSchema">
+        <ows20:AllowedValues>
+          <ows20:Value>http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/</ows20:Value>
+          <ows20:Value>http://www.interlis.ch/INTERLIS2.3</ows20:Value>
+          <ows20:Value>http://www.opengis.net/cat/csw/3.0</ows20:Value>
+          <ows20:Value>http://www.opengis.net/cat/csw/csdgm</ows20:Value>
+          <ows20:Value>http://www.w3.org/2005/Atom</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Parameter name="typeNames">
+        <ows20:AllowedValues>
+          <ows20:Value>csw:Record</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Constraint name="MaxRecordDefault">
+        <ows20:AllowedValues>
+          <ows20:Value>10</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Constraint>
+      <ows20:Constraint name="OpenSearchDescriptionDocument">
+        <ows20:AllowedValues>
+          <ows20:Value>http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg?mode=opensearch&service=CSW&version=3.0.0&request=GetCapabilities</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Constraint>
+      <ows20:Constraint name="FederatedCatalogues">
+        <ows20:AllowedValues>
+          <ows20:Value>http://demo.pycsw.org/gisdata/csw</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Constraint>
+    </ows20:Operation>
+    <ows20:Operation name="GetRecordById">
+      <ows20:DCP>
+        <ows20:HTTP>
+          <ows20:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg"/>
+          <ows20:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg"/>
+        </ows20:HTTP>
+      </ows20:DCP>
+      <ows20:Parameter name="ElementSetName">
+        <ows20:AllowedValues>
+          <ows20:Value>brief</ows20:Value>
+          <ows20:Value>full</ows20:Value>
+          <ows20:Value>summary</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Parameter name="outputFormat">
+        <ows20:AllowedValues>
+          <ows20:Value>application/atom+xml</ows20:Value>
+          <ows20:Value>application/json</ows20:Value>
+          <ows20:Value>application/xml</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Parameter name="outputSchema">
+        <ows20:AllowedValues>
+          <ows20:Value>http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/</ows20:Value>
+          <ows20:Value>http://www.interlis.ch/INTERLIS2.3</ows20:Value>
+          <ows20:Value>http://www.opengis.net/cat/csw/3.0</ows20:Value>
+          <ows20:Value>http://www.opengis.net/cat/csw/csdgm</ows20:Value>
+          <ows20:Value>http://www.w3.org/2005/Atom</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+    </ows20:Operation>
+    <ows20:Operation name="GetRepositoryItem">
+      <ows20:DCP>
+        <ows20:HTTP>
+          <ows20:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg"/>
+        </ows20:HTTP>
+      </ows20:DCP>
+    </ows20:Operation>
+    <ows20:Parameter name="service">
+      <ows20:AllowedValues>
+        <ows20:Value>CSW</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Parameter>
+    <ows20:Parameter name="version">
+      <ows20:AllowedValues>
+        <ows20:Value>2.0.2</ows20:Value>
+        <ows20:Value>3.0.0</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Parameter>
+    <ows20:Constraint name="CoreQueryables">
+      <ows20:AllowedValues>
+        <ows20:Value>csw:AnyText</ows20:Value>
+        <ows20:Value>dc:contributor</ows20:Value>
+        <ows20:Value>dc:creator</ows20:Value>
+        <ows20:Value>dc:date</ows20:Value>
+        <ows20:Value>dc:format</ows20:Value>
+        <ows20:Value>dc:identifier</ows20:Value>
+        <ows20:Value>dc:language</ows20:Value>
+        <ows20:Value>dc:publisher</ows20:Value>
+        <ows20:Value>dc:relation</ows20:Value>
+        <ows20:Value>dc:rights</ows20:Value>
+        <ows20:Value>dc:source</ows20:Value>
+        <ows20:Value>dc:subject</ows20:Value>
+        <ows20:Value>dc:title</ows20:Value>
+        <ows20:Value>dc:type</ows20:Value>
+        <ows20:Value>dct:abstract</ows20:Value>
+        <ows20:Value>dct:modified</ows20:Value>
+        <ows20:Value>ows:BoundingBox</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="FederatedCatalogues">
+      <ows20:AllowedValues>
+        <ows20:Value>http://demo.pycsw.org/gisdata/csw</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="MaxRecordDefault">
+      <ows20:AllowedValues>
+        <ows20:Value>10</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="PostEncoding">
+      <ows20:AllowedValues>
+        <ows20:Value>SOAP</ows20:Value>
+        <ows20:Value>XML</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="XPathQueryables">
+      <ows20:AllowedValues>
+        <ows20:Value>allowed</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/CoreQueryables">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/CoreSortables">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/DefaultSortingAlgorithm">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Filter-CQL">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Filter-FES-KVP-Advanced">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Filter-FES-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetCapabilities-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetDomain-KVP">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetDomain-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetRecordById-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetRecords-Async-KVP">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetRecords-Async-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetRecords-Basic-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetRecords-Distributed-KVP">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetRecords-Distributed-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Harvest-Async-KVP">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Harvest-Async-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Harvest-Basic-KVP">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Harvest-Basic-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Harvest-Periodic-KVP">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Harvest-Periodic-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/OpenSearch">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/SupportedGMLVersions">
+      <ows20:AllowedValues>
+        <ows20:Value>http://www.opengis.net/gml</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Transaction">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+  </ows20:OperationsMetadata>
+  <ows20:Languages>
+    <ows20:Language>en</ows20:Language>
+  </ows20:Languages>
+  <fes20:Filter_Capabilities>
+    <fes20:Conformance>
+      <fes20:Constraint name="ImplementsQuery">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsAdHocQuery">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsFunctions">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsResourceld">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsMinStandardFilter">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsStandardFilter">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsMinSpatialFilter">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsSpatialFilter">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsMinTemporalFilter">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsTemporalFilter">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsVersionNav">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsSorting">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsExtendedOperators">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsMinimumXPath">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsSchemaElementFunc">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+    </fes20:Conformance>
+    <fes20:Id_Capabilities>
+      <fes20:ResourceIdentifier name="csw30:id"/>
+    </fes20:Id_Capabilities>
+    <fes20:Scalar_Capabilities>
+      <fes20:LogicalOperators/>
+      <fes20:ComparisonOperators>
+        <fes20:ComparisonOperator name="PropertyIsBetween"/>
+        <fes20:ComparisonOperator name="PropertyIsEqualTo"/>
+        <fes20:ComparisonOperator name="PropertyIsGreaterThan"/>
+        <fes20:ComparisonOperator name="PropertyIsGreaterThanOrEqualTo"/>
+        <fes20:ComparisonOperator name="PropertyIsLessThan"/>
+        <fes20:ComparisonOperator name="PropertyIsLessThanOrEqualTo"/>
+        <fes20:ComparisonOperator name="PropertyIsLike"/>
+        <fes20:ComparisonOperator name="PropertyIsNotEqualTo"/>
+        <fes20:ComparisonOperator name="PropertyIsNull"/>
+      </fes20:ComparisonOperators>
+    </fes20:Scalar_Capabilities>
+    <fes20:Spatial_Capabilities>
+      <fes20:GeometryOperands>
+        <fes20:GeometryOperand name="gml:Point"/>
+        <fes20:GeometryOperand name="gml:LineString"/>
+        <fes20:GeometryOperand name="gml:Polygon"/>
+        <fes20:GeometryOperand name="gml:Envelope"/>
+      </fes20:GeometryOperands>
+      <fes20:SpatialOperators>
+        <fes20:SpatialOperator name="BBOX"/>
+        <fes20:SpatialOperator name="Beyond"/>
+        <fes20:SpatialOperator name="Contains"/>
+        <fes20:SpatialOperator name="Crosses"/>
+        <fes20:SpatialOperator name="Disjoint"/>
+        <fes20:SpatialOperator name="DWithin"/>
+        <fes20:SpatialOperator name="Equals"/>
+        <fes20:SpatialOperator name="Intersects"/>
+        <fes20:SpatialOperator name="Overlaps"/>
+        <fes20:SpatialOperator name="Touches"/>
+        <fes20:SpatialOperator name="Within"/>
+      </fes20:SpatialOperators>
+    </fes20:Spatial_Capabilities>
+    <fes20:Functions>
+      <fes20:Function name="length">
+        <fes20:Returns>xs:string</fes20:Returns>
+      </fes20:Function>
+      <fes20:Function name="lower">
+        <fes20:Returns>xs:string</fes20:Returns>
+      </fes20:Function>
+      <fes20:Function name="ltrim">
+        <fes20:Returns>xs:string</fes20:Returns>
+      </fes20:Function>
+      <fes20:Function name="rtrim">
+        <fes20:Returns>xs:string</fes20:Returns>
+      </fes20:Function>
+      <fes20:Function name="trim">
+        <fes20:Returns>xs:string</fes20:Returns>
+      </fes20:Function>
+      <fes20:Function name="upper">
+        <fes20:Returns>xs:string</fes20:Returns>
+      </fes20:Function>
+    </fes20:Functions>
+  </fes20:Filter_Capabilities>
+</csw30:Capabilities>
diff --git a/tests/expected/suites_csw30_get_2ba1418a-444d-4cce-9cfe-4c94efcf8b55.xml b/tests/expected/suites_csw30_get_2ba1418a-444d-4cce-9cfe-4c94efcf8b55.xml
new file mode 100644
index 0000000..06869ee
--- /dev/null
+++ b/tests/expected/suites_csw30_get_2ba1418a-444d-4cce-9cfe-4c94efcf8b55.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- PYCSW_VERSION -->
+<atom:feed xmlns:atom="http://www.w3.org/2005/Atom" xmlns:os="http://a9.com/-/spec/opensearch/1.1/">
+  <atom:id>http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg</atom:id>
+  <atom:title>pycsw Geospatial Catalogue</atom:title>
+  <atom:author>
+    <atom:name>pycsw</atom:name>
+  </atom:author>
+  <atom:link href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg&mode=opensearch&service=CSW&version=3.0.0&request=GetCapabilities" rel="search" type="application/opensearchdescription+xml"/>
+  <atom:updated>PYCSW_TIMESTAMP</atom:updated>
+  <os:Query role="request"/>
+  <os:totalResults>12</os:totalResults>
+  <os:startIndex>3</os:startIndex>
+  <os:itemsPerPage>2</os:itemsPerPage>
+  <atom:entry xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dc="http://purl.org/dc/elements/1.1/" xsi:schemaLocation="http://www.w3.org/2005/Atom http://www.kbcafe.com/rss/atom.xsd.xml">
+    <atom:category term="Marine sediments"/>
+    <atom:id>urn:uuid:66ae76b7-54ba-489b-a582-0f0633d96493</atom:id>
+    <dc:identifier>urn:uuid:66ae76b7-54ba-489b-a582-0f0633d96493</dc:identifier>
+    <atom:link href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg?service=CSW&version=2.0.2&request=GetRepositoryItem&id=urn:uuid:66ae76b7-54ba-489b-a582-0f0633d96493"/>
+    <atom:title>Maecenas enim</atom:title>
+    <atom:updated>PYCSW_TIMESTAMP</atom:updated>
+    <atom:summary>Pellentesque tempus magna non sapien fringilla blandit.</atom:summary>
+  </atom:entry>
+  <atom:entry xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dc="http://purl.org/dc/elements/1.1/" xsi:schemaLocation="http://www.w3.org/2005/Atom http://www.kbcafe.com/rss/atom.xsd.xml">
+    <atom:category term="Vegetation"/>
+    <atom:id>urn:uuid:6a3de50b-fa66-4b58-a0e6-ca146fdd18d4</atom:id>
+    <dc:identifier>urn:uuid:6a3de50b-fa66-4b58-a0e6-ca146fdd18d4</dc:identifier>
+    <atom:link href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg?service=CSW&version=2.0.2&request=GetRepositoryItem&id=urn:uuid:6a3de50b-fa66-4b58-a0e6-ca146fdd18d4"/>
+    <atom:title>Ut facilisis justo ut lacus</atom:title>
+    <atom:updated>PYCSW_TIMESTAMP</atom:updated>
+  </atom:entry>
+</atom:feed>
diff --git a/tests/expected/suites_csw30_get_397fe17a-d5b4-4f96-8cc4-4ce467ed4d0a.xml b/tests/expected/suites_csw30_get_397fe17a-d5b4-4f96-8cc4-4ce467ed4d0a.xml
new file mode 100644
index 0000000..a2f3d57
--- /dev/null
+++ b/tests/expected/suites_csw30_get_397fe17a-d5b4-4f96-8cc4-4ce467ed4d0a.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- PYCSW_VERSION -->
+<csw30:GetRecordsResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:csw30="http://www.opengis.net/cat/csw/3.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="3.0.0" xsi:schemaLocation="http://www.opengis.net/cat/cs [...]
+  <csw30:SearchStatus timestamp="PYCSW_TIMESTAMP"/>
+  <csw30:SearchResults expires="PYCSW_EXPIRES" nextRecord="0" numberOfRecordsMatched="3" numberOfRecordsReturned="3" recordSchema="http://www.opengis.net/cat/csw/3.0" status="subset" elementSet="full" elapsedTime="PYCSW_ELAPSED_TIME">
+    <csw30:Record>
+      <dc:identifier>urn:uuid:19887a8a-f6b0-4a63-ae56-7fba0e17801f</dc:identifier>
+      <dc:title>Lorem ipsum</dc:title>
+      <dc:type>http://purl.org/dc/dcmitype/Image</dc:type>
+      <dc:subject>Tourism--Greece</dc:subject>
+      <dc:format>image/svg+xml</dc:format>
+      <dct:abstract>Quisque lacus diam, placerat mollis, pharetra in, commodo sed, augue. Duis iaculis arcu vel arcu.</dct:abstract>
+    </csw30:Record>
+    <csw30:Record>
+      <dc:identifier>urn:uuid:784e2afd-a9fd-44a6-9a92-a3848371c8ec</dc:identifier>
+      <dc:title>Aliquam fermentum purus quis arcu</dc:title>
+      <dc:type>http://purl.org/dc/dcmitype/Text</dc:type>
+      <dc:subject>Hydrography--Dictionaries</dc:subject>
+      <dc:format>application/pdf</dc:format>
+      <dct:abstract>Vestibulum quis ipsum sit amet metus imperdiet vehicula. Nulla scelerisque cursus mi.</dct:abstract>
+      <dc:date>2006-05-12</dc:date>
+    </csw30:Record>
+    <csw30:Record>
+      <dc:identifier>urn:uuid:a06af396-3105-442d-8b40-22b57a90d2f2</dc:identifier>
+      <dc:title>Lorem ipsum dolor sit amet</dc:title>
+      <dc:type>http://purl.org/dc/dcmitype/Image</dc:type>
+      <dc:format>image/jpeg</dc:format>
+    </csw30:Record>
+  </csw30:SearchResults>
+</csw30:GetRecordsResponse>
diff --git a/tests/expected/suites_csw30_get_3dcd1b15-73d2-4b7d-a3e3-ff15bf14aae4.xml b/tests/expected/suites_csw30_get_3dcd1b15-73d2-4b7d-a3e3-ff15bf14aae4.xml
new file mode 100644
index 0000000..4d7f6b1
--- /dev/null
+++ b/tests/expected/suites_csw30_get_3dcd1b15-73d2-4b7d-a3e3-ff15bf14aae4.xml
@@ -0,0 +1,69 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- PYCSW_VERSION -->
+<csw30:GetRecordsResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:csw30="http://www.opengis.net/cat/csw/3.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:ows20="http://www.opengis.net/ows/2.0" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="3.0.0" xsi: [...]
+  <csw30:SearchStatus timestamp="PYCSW_TIMESTAMP"/>
+  <csw30:SearchResults expires="PYCSW_EXPIRES" nextRecord="11" numberOfRecordsMatched="12" numberOfRecordsReturned="10" recordSchema="http://www.opengis.net/cat/csw/3.0" status="subset" elementSet="brief" elapsedTime="PYCSW_ELAPSED_TIME">
+    <csw30:BriefRecord>
+      <dc:identifier>urn:uuid:19887a8a-f6b0-4a63-ae56-7fba0e17801f</dc:identifier>
+      <dc:title>Lorem ipsum</dc:title>
+      <dc:type>http://purl.org/dc/dcmitype/Image</dc:type>
+    </csw30:BriefRecord>
+    <csw30:BriefRecord>
+      <dc:identifier>urn:uuid:1ef30a8b-876d-4828-9246-c37ab4510bbd</dc:identifier>
+      <dc:title></dc:title>
+      <dc:type>http://purl.org/dc/dcmitype/Service</dc:type>
+      <ows20:BoundingBox crs="http://www.opengis.net/def/crs/EPSG/0/4326" dimensions="2">
+        <ows20:LowerCorner>60.04 13.75</ows20:LowerCorner>
+        <ows20:UpperCorner>68.41 17.92</ows20:UpperCorner>
+      </ows20:BoundingBox>
+    </csw30:BriefRecord>
+    <csw30:BriefRecord>
+      <dc:identifier>urn:uuid:66ae76b7-54ba-489b-a582-0f0633d96493</dc:identifier>
+      <dc:title>Maecenas enim</dc:title>
+      <dc:type>http://purl.org/dc/dcmitype/Text</dc:type>
+    </csw30:BriefRecord>
+    <csw30:BriefRecord>
+      <dc:identifier>urn:uuid:6a3de50b-fa66-4b58-a0e6-ca146fdd18d4</dc:identifier>
+      <dc:title>Ut facilisis justo ut lacus</dc:title>
+      <dc:type>http://purl.org/dc/dcmitype/Service</dc:type>
+    </csw30:BriefRecord>
+    <csw30:BriefRecord>
+      <dc:identifier>urn:uuid:784e2afd-a9fd-44a6-9a92-a3848371c8ec</dc:identifier>
+      <dc:title>Aliquam fermentum purus quis arcu</dc:title>
+      <dc:type>http://purl.org/dc/dcmitype/Text</dc:type>
+    </csw30:BriefRecord>
+    <csw30:BriefRecord>
+      <dc:identifier>urn:uuid:829babb0-b2f1-49e1-8cd5-7b489fe71a1e</dc:identifier>
+      <dc:title>Vestibulum massa purus</dc:title>
+      <dc:type>http://purl.org/dc/dcmitype/Image</dc:type>
+    </csw30:BriefRecord>
+    <csw30:BriefRecord>
+      <dc:identifier>urn:uuid:88247b56-4cbc-4df9-9860-db3f8042e357</dc:identifier>
+      <dc:title></dc:title>
+      <dc:type>http://purl.org/dc/dcmitype/Dataset</dc:type>
+    </csw30:BriefRecord>
+    <csw30:BriefRecord>
+      <dc:identifier>urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63</dc:identifier>
+      <dc:title>Mauris sed neque</dc:title>
+      <dc:type>http://purl.org/dc/dcmitype/Dataset</dc:type>
+      <ows20:BoundingBox crs="http://www.opengis.net/def/crs/EPSG/0/4326" dimensions="2">
+        <ows20:LowerCorner>47.59 -4.1</ows20:LowerCorner>
+        <ows20:UpperCorner>51.22 0.89</ows20:UpperCorner>
+      </ows20:BoundingBox>
+    </csw30:BriefRecord>
+    <csw30:BriefRecord>
+      <dc:identifier>urn:uuid:9a669547-b69b-469f-a11f-2d875366bbdc</dc:identifier>
+      <dc:title>Ñunç elementum</dc:title>
+      <dc:type>http://purl.org/dc/dcmitype/Dataset</dc:type>
+      <ows20:BoundingBox crs="http://www.opengis.net/def/crs/EPSG/0/4326" dimensions="2">
+        <ows20:LowerCorner>44.79 -6.17</ows20:LowerCorner>
+        <ows20:UpperCorner>51.13 -2.23</ows20:UpperCorner>
+      </ows20:BoundingBox>
+    </csw30:BriefRecord>
+    <csw30:BriefRecord>
+      <dc:identifier>urn:uuid:a06af396-3105-442d-8b40-22b57a90d2f2</dc:identifier>
+      <dc:title>Lorem ipsum dolor sit amet</dc:title>
+      <dc:type>http://purl.org/dc/dcmitype/Image</dc:type>
+    </csw30:BriefRecord>
+  </csw30:SearchResults>
+</csw30:GetRecordsResponse>
diff --git a/tests/expected/suites_csw30_get_405e1ff1-5c75-4846-a28b-cfaff2a6921a.xml b/tests/expected/suites_csw30_get_405e1ff1-5c75-4846-a28b-cfaff2a6921a.xml
new file mode 100644
index 0000000..22bdf2c
--- /dev/null
+++ b/tests/expected/suites_csw30_get_405e1ff1-5c75-4846-a28b-cfaff2a6921a.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- PYCSW_VERSION -->
+<csw30:GetRecordsResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:csw30="http://www.opengis.net/cat/csw/3.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="3.0.0" xsi:schemaLocation="http://www.opengis.net/cat/cs [...]
+  <csw30:SearchStatus timestamp="PYCSW_TIMESTAMP"/>
+  <csw30:SearchResults expires="PYCSW_EXPIRES" nextRecord="0" numberOfRecordsMatched="2" numberOfRecordsReturned="2" recordSchema="http://www.opengis.net/cat/csw/3.0" status="subset" elementSet="summary" elapsedTime="PYCSW_ELAPSED_TIME">
+    <csw30:SummaryRecord>
+      <dc:identifier>urn:uuid:19887a8a-f6b0-4a63-ae56-7fba0e17801f</dc:identifier>
+      <dc:title>Lorem ipsum</dc:title>
+      <dc:type>http://purl.org/dc/dcmitype/Image</dc:type>
+      <dc:subject>Tourism--Greece</dc:subject>
+      <dc:format>image/svg+xml</dc:format>
+      <dct:abstract>Quisque lacus diam, placerat mollis, pharetra in, commodo sed, augue. Duis iaculis arcu vel arcu.</dct:abstract>
+    </csw30:SummaryRecord>
+    <csw30:SummaryRecord>
+      <dc:identifier>urn:uuid:e9330592-0932-474b-be34-c3a3bb67c7db</dc:identifier>
+      <dc:title>Fuscé vitae ligulä</dc:title>
+      <dc:type>http://purl.org/dc/dcmitype/Text</dc:type>
+      <dc:subject>Land titles</dc:subject>
+      <dc:format>text/rtf</dc:format>
+      <dct:abstract>Morbi ultriçes, dui suscipit vestibulum prètium, velit ante pretium tortor, egët tincidunt pede odio ac nulla.</dct:abstract>
+    </csw30:SummaryRecord>
+  </csw30:SearchResults>
+</csw30:GetRecordsResponse>
diff --git a/tests/expected/suites_csw30_get_43cd6471-6ac7-45bd-8ff9-148cb2de9a52.xml b/tests/expected/suites_csw30_get_43cd6471-6ac7-45bd-8ff9-148cb2de9a52.xml
new file mode 100644
index 0000000..ce9c935
--- /dev/null
+++ b/tests/expected/suites_csw30_get_43cd6471-6ac7-45bd-8ff9-148cb2de9a52.xml
@@ -0,0 +1,491 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- PYCSW_VERSION -->
+<csw30:Capabilities xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:csw30="http://www.opengis.net/cat/csw/3.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:fes20="http://www.opengis.net/fes/2.0" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:ows11="http://www.opengis.net/ows/1.1" xmlns:ows20="http://www.opengis.net/ows/2.0" xmlns:xlink="http://www.w3.org/199 [...]
+  <ows20:ServiceIdentification>
+    <ows20:Title>pycsw Geospatial Catalogue</ows20:Title>
+    <ows20:Abstract>pycsw is an OGC CSW server implementation written in Python</ows20:Abstract>
+    <ows20:Keywords>
+      <ows20:Keyword>catalogue</ows20:Keyword>
+      <ows20:Keyword>discovery</ows20:Keyword>
+      <ows20:Type codeSpace="ISOTC211/19115">theme</ows20:Type>
+    </ows20:Keywords>
+    <ows20:ServiceType codeSpace="OGC">CSW</ows20:ServiceType>
+    <ows20:ServiceTypeVersion>2.0.2</ows20:ServiceTypeVersion>
+    <ows20:ServiceTypeVersion>3.0.0</ows20:ServiceTypeVersion>
+    <ows20:Fees>None</ows20:Fees>
+    <ows20:AccessConstraints>None</ows20:AccessConstraints>
+  </ows20:ServiceIdentification>
+  <ows20:ServiceProvider>
+    <ows20:ProviderName>pycsw</ows20:ProviderName>
+    <ows20:ProviderSite xlink:type="simple" xlink:href="http://pycsw.org/"/>
+    <ows20:ServiceContact>
+      <ows20:IndividualName>Kralidis, Tom</ows20:IndividualName>
+      <ows20:PositionName>Senior Systems Scientist</ows20:PositionName>
+      <ows20:ContactInfo>
+        <ows20:Phone>
+          <ows20:Voice>+01-416-xxx-xxxx</ows20:Voice>
+          <ows20:Facsimile>+01-416-xxx-xxxx</ows20:Facsimile>
+        </ows20:Phone>
+        <ows20:Address>
+          <ows20:DeliveryPoint>TBA</ows20:DeliveryPoint>
+          <ows20:City>Toronto</ows20:City>
+          <ows20:AdministrativeArea>Ontario</ows20:AdministrativeArea>
+          <ows20:PostalCode>M9C 3Z9</ows20:PostalCode>
+          <ows20:Country>Canada</ows20:Country>
+          <ows20:ElectronicMailAddress>tomkralidis at gmail.com</ows20:ElectronicMailAddress>
+        </ows20:Address>
+        <ows20:OnlineResource xlink:type="simple" xlink:href="http://kralidis.ca/"/>
+        <ows20:HoursOfService>0800h - 1600h EST</ows20:HoursOfService>
+        <ows20:ContactInstructions>During hours of service.  Off on weekends.</ows20:ContactInstructions>
+      </ows20:ContactInfo>
+      <ows20:Role codeSpace="ISOTC211/19115">pointOfContact</ows20:Role>
+    </ows20:ServiceContact>
+  </ows20:ServiceProvider>
+  <ows20:OperationsMetadata>
+    <ows20:Operation name="GetCapabilities">
+      <ows20:DCP>
+        <ows20:HTTP>
+          <ows20:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg"/>
+          <ows20:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg"/>
+        </ows20:HTTP>
+      </ows20:DCP>
+      <ows20:Parameter name="acceptFormats">
+        <ows20:AllowedValues>
+          <ows20:Value>application/xml</ows20:Value>
+          <ows20:Value>text/xml</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Parameter name="acceptVersions">
+        <ows20:AllowedValues>
+          <ows20:Value>2.0.2</ows20:Value>
+          <ows20:Value>3.0.0</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Parameter name="sections">
+        <ows20:AllowedValues>
+          <ows20:Value>All</ows20:Value>
+          <ows20:Value>Filter_Capabilities</ows20:Value>
+          <ows20:Value>OperationsMetadata</ows20:Value>
+          <ows20:Value>ServiceIdentification</ows20:Value>
+          <ows20:Value>ServiceProvider</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+    </ows20:Operation>
+    <ows20:Operation name="GetDomain">
+      <ows20:DCP>
+        <ows20:HTTP>
+          <ows20:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg"/>
+          <ows20:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg"/>
+        </ows20:HTTP>
+      </ows20:DCP>
+      <ows20:Parameter name="ParameterName">
+        <ows20:AllowedValues>
+          <ows20:Value>GetCapabilities.acceptFormats</ows20:Value>
+          <ows20:Value>GetCapabilities.acceptVersions</ows20:Value>
+          <ows20:Value>GetCapabilities.sections</ows20:Value>
+          <ows20:Value>GetRecordById.ElementSetName</ows20:Value>
+          <ows20:Value>GetRecordById.outputFormat</ows20:Value>
+          <ows20:Value>GetRecordById.outputSchema</ows20:Value>
+          <ows20:Value>GetRecords.CONSTRAINTLANGUAGE</ows20:Value>
+          <ows20:Value>GetRecords.ElementSetName</ows20:Value>
+          <ows20:Value>GetRecords.outputFormat</ows20:Value>
+          <ows20:Value>GetRecords.outputSchema</ows20:Value>
+          <ows20:Value>GetRecords.typeNames</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+    </ows20:Operation>
+    <ows20:Operation name="GetRecords">
+      <ows20:DCP>
+        <ows20:HTTP>
+          <ows20:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg"/>
+          <ows20:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg"/>
+        </ows20:HTTP>
+      </ows20:DCP>
+      <ows20:Parameter name="CONSTRAINTLANGUAGE">
+        <ows20:AllowedValues>
+          <ows20:Value>CQL_TEXT</ows20:Value>
+          <ows20:Value>FILTER</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Parameter name="ElementSetName">
+        <ows20:AllowedValues>
+          <ows20:Value>brief</ows20:Value>
+          <ows20:Value>full</ows20:Value>
+          <ows20:Value>summary</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Parameter name="outputFormat">
+        <ows20:AllowedValues>
+          <ows20:Value>application/atom+xml</ows20:Value>
+          <ows20:Value>application/json</ows20:Value>
+          <ows20:Value>application/xml</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Parameter name="outputSchema">
+        <ows20:AllowedValues>
+          <ows20:Value>http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/</ows20:Value>
+          <ows20:Value>http://www.interlis.ch/INTERLIS2.3</ows20:Value>
+          <ows20:Value>http://www.opengis.net/cat/csw/3.0</ows20:Value>
+          <ows20:Value>http://www.opengis.net/cat/csw/csdgm</ows20:Value>
+          <ows20:Value>http://www.w3.org/2005/Atom</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Parameter name="typeNames">
+        <ows20:AllowedValues>
+          <ows20:Value>csw:Record</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Constraint name="MaxRecordDefault">
+        <ows20:AllowedValues>
+          <ows20:Value>10</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Constraint>
+      <ows20:Constraint name="OpenSearchDescriptionDocument">
+        <ows20:AllowedValues>
+          <ows20:Value>http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg?mode=opensearch&service=CSW&version=3.0.0&request=GetCapabilities</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Constraint>
+      <ows20:Constraint name="FederatedCatalogues">
+        <ows20:AllowedValues>
+          <ows20:Value>http://demo.pycsw.org/gisdata/csw</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Constraint>
+    </ows20:Operation>
+    <ows20:Operation name="GetRecordById">
+      <ows20:DCP>
+        <ows20:HTTP>
+          <ows20:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg"/>
+          <ows20:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg"/>
+        </ows20:HTTP>
+      </ows20:DCP>
+      <ows20:Parameter name="ElementSetName">
+        <ows20:AllowedValues>
+          <ows20:Value>brief</ows20:Value>
+          <ows20:Value>full</ows20:Value>
+          <ows20:Value>summary</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Parameter name="outputFormat">
+        <ows20:AllowedValues>
+          <ows20:Value>application/atom+xml</ows20:Value>
+          <ows20:Value>application/json</ows20:Value>
+          <ows20:Value>application/xml</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Parameter name="outputSchema">
+        <ows20:AllowedValues>
+          <ows20:Value>http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/</ows20:Value>
+          <ows20:Value>http://www.interlis.ch/INTERLIS2.3</ows20:Value>
+          <ows20:Value>http://www.opengis.net/cat/csw/3.0</ows20:Value>
+          <ows20:Value>http://www.opengis.net/cat/csw/csdgm</ows20:Value>
+          <ows20:Value>http://www.w3.org/2005/Atom</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+    </ows20:Operation>
+    <ows20:Operation name="GetRepositoryItem">
+      <ows20:DCP>
+        <ows20:HTTP>
+          <ows20:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg"/>
+        </ows20:HTTP>
+      </ows20:DCP>
+    </ows20:Operation>
+    <ows20:Parameter name="service">
+      <ows20:AllowedValues>
+        <ows20:Value>CSW</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Parameter>
+    <ows20:Parameter name="version">
+      <ows20:AllowedValues>
+        <ows20:Value>2.0.2</ows20:Value>
+        <ows20:Value>3.0.0</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Parameter>
+    <ows20:Constraint name="CoreQueryables">
+      <ows20:AllowedValues>
+        <ows20:Value>csw:AnyText</ows20:Value>
+        <ows20:Value>dc:contributor</ows20:Value>
+        <ows20:Value>dc:creator</ows20:Value>
+        <ows20:Value>dc:date</ows20:Value>
+        <ows20:Value>dc:format</ows20:Value>
+        <ows20:Value>dc:identifier</ows20:Value>
+        <ows20:Value>dc:language</ows20:Value>
+        <ows20:Value>dc:publisher</ows20:Value>
+        <ows20:Value>dc:relation</ows20:Value>
+        <ows20:Value>dc:rights</ows20:Value>
+        <ows20:Value>dc:source</ows20:Value>
+        <ows20:Value>dc:subject</ows20:Value>
+        <ows20:Value>dc:title</ows20:Value>
+        <ows20:Value>dc:type</ows20:Value>
+        <ows20:Value>dct:abstract</ows20:Value>
+        <ows20:Value>dct:modified</ows20:Value>
+        <ows20:Value>ows:BoundingBox</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="FederatedCatalogues">
+      <ows20:AllowedValues>
+        <ows20:Value>http://demo.pycsw.org/gisdata/csw</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="MaxRecordDefault">
+      <ows20:AllowedValues>
+        <ows20:Value>10</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="PostEncoding">
+      <ows20:AllowedValues>
+        <ows20:Value>SOAP</ows20:Value>
+        <ows20:Value>XML</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="XPathQueryables">
+      <ows20:AllowedValues>
+        <ows20:Value>allowed</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/CoreQueryables">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/CoreSortables">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/DefaultSortingAlgorithm">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Filter-CQL">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Filter-FES-KVP-Advanced">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Filter-FES-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetCapabilities-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetDomain-KVP">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetDomain-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetRecordById-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetRecords-Async-KVP">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetRecords-Async-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetRecords-Basic-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetRecords-Distributed-KVP">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetRecords-Distributed-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Harvest-Async-KVP">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Harvest-Async-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Harvest-Basic-KVP">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Harvest-Basic-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Harvest-Periodic-KVP">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Harvest-Periodic-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/OpenSearch">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/SupportedGMLVersions">
+      <ows20:AllowedValues>
+        <ows20:Value>http://www.opengis.net/gml</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Transaction">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+  </ows20:OperationsMetadata>
+  <ows20:Languages>
+    <ows20:Language>en</ows20:Language>
+  </ows20:Languages>
+  <fes20:Filter_Capabilities>
+    <fes20:Conformance>
+      <fes20:Constraint name="ImplementsQuery">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsAdHocQuery">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsFunctions">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsResourceld">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsMinStandardFilter">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsStandardFilter">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsMinSpatialFilter">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsSpatialFilter">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsMinTemporalFilter">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsTemporalFilter">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsVersionNav">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsSorting">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsExtendedOperators">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsMinimumXPath">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsSchemaElementFunc">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+    </fes20:Conformance>
+    <fes20:Id_Capabilities>
+      <fes20:ResourceIdentifier name="csw30:id"/>
+    </fes20:Id_Capabilities>
+    <fes20:Scalar_Capabilities>
+      <fes20:LogicalOperators/>
+      <fes20:ComparisonOperators>
+        <fes20:ComparisonOperator name="PropertyIsBetween"/>
+        <fes20:ComparisonOperator name="PropertyIsEqualTo"/>
+        <fes20:ComparisonOperator name="PropertyIsGreaterThan"/>
+        <fes20:ComparisonOperator name="PropertyIsGreaterThanOrEqualTo"/>
+        <fes20:ComparisonOperator name="PropertyIsLessThan"/>
+        <fes20:ComparisonOperator name="PropertyIsLessThanOrEqualTo"/>
+        <fes20:ComparisonOperator name="PropertyIsLike"/>
+        <fes20:ComparisonOperator name="PropertyIsNotEqualTo"/>
+        <fes20:ComparisonOperator name="PropertyIsNull"/>
+      </fes20:ComparisonOperators>
+    </fes20:Scalar_Capabilities>
+    <fes20:Spatial_Capabilities>
+      <fes20:GeometryOperands>
+        <fes20:GeometryOperand name="gml:Point"/>
+        <fes20:GeometryOperand name="gml:LineString"/>
+        <fes20:GeometryOperand name="gml:Polygon"/>
+        <fes20:GeometryOperand name="gml:Envelope"/>
+      </fes20:GeometryOperands>
+      <fes20:SpatialOperators>
+        <fes20:SpatialOperator name="BBOX"/>
+        <fes20:SpatialOperator name="Beyond"/>
+        <fes20:SpatialOperator name="Contains"/>
+        <fes20:SpatialOperator name="Crosses"/>
+        <fes20:SpatialOperator name="Disjoint"/>
+        <fes20:SpatialOperator name="DWithin"/>
+        <fes20:SpatialOperator name="Equals"/>
+        <fes20:SpatialOperator name="Intersects"/>
+        <fes20:SpatialOperator name="Overlaps"/>
+        <fes20:SpatialOperator name="Touches"/>
+        <fes20:SpatialOperator name="Within"/>
+      </fes20:SpatialOperators>
+    </fes20:Spatial_Capabilities>
+    <fes20:Functions>
+      <fes20:Function name="length">
+        <fes20:Returns>xs:string</fes20:Returns>
+      </fes20:Function>
+      <fes20:Function name="lower">
+        <fes20:Returns>xs:string</fes20:Returns>
+      </fes20:Function>
+      <fes20:Function name="ltrim">
+        <fes20:Returns>xs:string</fes20:Returns>
+      </fes20:Function>
+      <fes20:Function name="rtrim">
+        <fes20:Returns>xs:string</fes20:Returns>
+      </fes20:Function>
+      <fes20:Function name="trim">
+        <fes20:Returns>xs:string</fes20:Returns>
+      </fes20:Function>
+      <fes20:Function name="upper">
+        <fes20:Returns>xs:string</fes20:Returns>
+      </fes20:Function>
+    </fes20:Functions>
+  </fes20:Filter_Capabilities>
+</csw30:Capabilities>
diff --git a/tests/expected/suites_csw30_get_4566d2ec-1283-4a02-baed-a74fc5b47e37.xml b/tests/expected/suites_csw30_get_4566d2ec-1283-4a02-baed-a74fc5b47e37.xml
new file mode 100644
index 0000000..e907a51
--- /dev/null
+++ b/tests/expected/suites_csw30_get_4566d2ec-1283-4a02-baed-a74fc5b47e37.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- PYCSW_VERSION -->
+<csw30:Capabilities xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:csw30="http://www.opengis.net/cat/csw/3.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:ows20="http://www.opengis.net/ows/2.0" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" updateSequence="PYCSW_UPDA [...]
+  <ows20:ServiceIdentification>
+    <ows20:Title>pycsw Geospatial Catalogue</ows20:Title>
+    <ows20:Abstract>pycsw is an OGC CSW server implementation written in Python</ows20:Abstract>
+    <ows20:Keywords>
+      <ows20:Keyword>catalogue</ows20:Keyword>
+      <ows20:Keyword>discovery</ows20:Keyword>
+      <ows20:Type codeSpace="ISOTC211/19115">theme</ows20:Type>
+    </ows20:Keywords>
+    <ows20:ServiceType codeSpace="OGC">CSW</ows20:ServiceType>
+    <ows20:ServiceTypeVersion>2.0.2</ows20:ServiceTypeVersion>
+    <ows20:ServiceTypeVersion>3.0.0</ows20:ServiceTypeVersion>
+    <ows20:Fees>None</ows20:Fees>
+    <ows20:AccessConstraints>None</ows20:AccessConstraints>
+  </ows20:ServiceIdentification>
+</csw30:Capabilities>
diff --git a/tests/expected/suites_csw30_get_461bd4c5-6623-490d-9036-d91a2201e87b.xml b/tests/expected/suites_csw30_get_461bd4c5-6623-490d-9036-d91a2201e87b.xml
new file mode 100644
index 0000000..cd2d3db
--- /dev/null
+++ b/tests/expected/suites_csw30_get_461bd4c5-6623-490d-9036-d91a2201e87b.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- PYCSW_VERSION -->
+<csw30:Capabilities xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:csw30="http://www.opengis.net/cat/csw/3.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" updateSequence="PYCSW_UPDATESEQUENCE" version="3.0.0" xsi:schemaLocatio [...]
diff --git a/tests/expected/suites_csw30_get_5496894a-3877-4f62-a20b-5d7126f94925.xml b/tests/expected/suites_csw30_get_5496894a-3877-4f62-a20b-5d7126f94925.xml
new file mode 100644
index 0000000..f0c8bac
--- /dev/null
+++ b/tests/expected/suites_csw30_get_5496894a-3877-4f62-a20b-5d7126f94925.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- PYCSW_VERSION -->
+<ows20:ExceptionReport xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:ows20="http://www.opengis.net/ows/2.0" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="3.0.0" xml:lang="en-US" xsi:schemaLocation="http://www.opengis. [...]
+  <ows20:Exception exceptionCode="InvalidParameterValue" locator="bbox">
+    <ows20:ExceptionText>4326 coordinates out of range: ['514432', '5429689', '529130', '5451619']</ows20:ExceptionText>
+  </ows20:Exception>
+</ows20:ExceptionReport>
diff --git a/tests/expected/suites_csw30_get_5a015f6a-bf14-4977-b1e3-6577eb0223c8.xml b/tests/expected/suites_csw30_get_5a015f6a-bf14-4977-b1e3-6577eb0223c8.xml
new file mode 100644
index 0000000..73b0f78
--- /dev/null
+++ b/tests/expected/suites_csw30_get_5a015f6a-bf14-4977-b1e3-6577eb0223c8.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- PYCSW_VERSION -->
+<csw30:GetRecordsResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:csw30="http://www.opengis.net/cat/csw/3.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:ows20="http://www.opengis.net/ows/2.0" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="3.0.0" xsi: [...]
+  <csw30:SearchStatus timestamp="PYCSW_TIMESTAMP"/>
+  <csw30:SearchResults expires="PYCSW_EXPIRES" nextRecord="0" numberOfRecordsMatched="3" numberOfRecordsReturned="3" recordSchema="http://www.opengis.net/cat/csw/3.0" status="subset" elementSet="full" elapsedTime="PYCSW_ELAPSED_TIME">
+    <csw30:Record>
+      <dc:identifier>urn:uuid:1ef30a8b-876d-4828-9246-c37ab4510bbd</dc:identifier>
+      <dc:title></dc:title>
+      <dc:type>http://purl.org/dc/dcmitype/Service</dc:type>
+      <dct:abstract>Proin sit amet justo. In justo. Aenean adipiscing nulla id tellus.</dct:abstract>
+      <ows20:BoundingBox crs="http://www.opengis.net/def/crs/EPSG/0/4326" dimensions="2">
+        <ows20:LowerCorner>60.04 13.75</ows20:LowerCorner>
+        <ows20:UpperCorner>68.41 17.92</ows20:UpperCorner>
+      </ows20:BoundingBox>
+    </csw30:Record>
+    <csw30:Record>
+      <dc:identifier>urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63</dc:identifier>
+      <dc:title>Mauris sed neque</dc:title>
+      <dc:type>http://purl.org/dc/dcmitype/Dataset</dc:type>
+      <dc:subject>Vegetation-Cropland</dc:subject>
+      <dct:abstract>Curabitur lacinia, ante non porta tempus, mi lorem feugiat odio, eget suscipit eros pede ac velit.</dct:abstract>
+      <dc:date>2006-03-26</dc:date>
+      <ows20:BoundingBox crs="http://www.opengis.net/def/crs/EPSG/0/4326" dimensions="2">
+        <ows20:LowerCorner>47.59 -4.1</ows20:LowerCorner>
+        <ows20:UpperCorner>51.22 0.89</ows20:UpperCorner>
+      </ows20:BoundingBox>
+    </csw30:Record>
+    <csw30:Record>
+      <dc:identifier>urn:uuid:9a669547-b69b-469f-a11f-2d875366bbdc</dc:identifier>
+      <dc:title>Ñunç elementum</dc:title>
+      <dc:type>http://purl.org/dc/dcmitype/Dataset</dc:type>
+      <dc:subject>Hydrography-Oceanographic</dc:subject>
+      <dc:date>2005-10-24</dc:date>
+      <ows20:BoundingBox crs="http://www.opengis.net/def/crs/EPSG/0/4326" dimensions="2">
+        <ows20:LowerCorner>44.79 -6.17</ows20:LowerCorner>
+        <ows20:UpperCorner>51.13 -2.23</ows20:UpperCorner>
+      </ows20:BoundingBox>
+    </csw30:Record>
+  </csw30:SearchResults>
+</csw30:GetRecordsResponse>
diff --git a/tests/expected/suites_csw30_get_5c3a2390-1fb9-43f0-b96c-f48c7a69c990.xml b/tests/expected/suites_csw30_get_5c3a2390-1fb9-43f0-b96c-f48c7a69c990.xml
new file mode 100644
index 0000000..ffd1bd0
--- /dev/null
+++ b/tests/expected/suites_csw30_get_5c3a2390-1fb9-43f0-b96c-f48c7a69c990.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- PYCSW_VERSION -->
+<ows20:ExceptionReport xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:ows20="http://www.opengis.net/ows/2.0" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="3.0.0" xml:lang="en-US" xsi:schemaLocation="http://www.opengis. [...]
+  <ows20:Exception exceptionCode="InvalidParameterValue" locator="outputformat">
+    <ows20:ExceptionText>Invalid outputformat parameter model/vnd.collada+xml</ows20:ExceptionText>
+  </ows20:Exception>
+</ows20:ExceptionReport>
diff --git a/tests/expected/suites_csw30_get_5e9e67dc-18d6-4645-8111-c6263c88a61f.xml b/tests/expected/suites_csw30_get_5e9e67dc-18d6-4645-8111-c6263c88a61f.xml
new file mode 100644
index 0000000..4d3fed2
--- /dev/null
+++ b/tests/expected/suites_csw30_get_5e9e67dc-18d6-4645-8111-c6263c88a61f.xml
@@ -0,0 +1,326 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- PYCSW_VERSION -->
+<csw30:Capabilities xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:csw30="http://www.opengis.net/cat/csw/3.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:ows20="http://www.opengis.net/ows/2.0" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XML [...]
+  <ows20:OperationsMetadata>
+    <ows20:Operation name="GetCapabilities">
+      <ows20:DCP>
+        <ows20:HTTP>
+          <ows20:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg"/>
+          <ows20:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg"/>
+        </ows20:HTTP>
+      </ows20:DCP>
+      <ows20:Parameter name="acceptFormats">
+        <ows20:AllowedValues>
+          <ows20:Value>application/xml</ows20:Value>
+          <ows20:Value>text/xml</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Parameter name="acceptVersions">
+        <ows20:AllowedValues>
+          <ows20:Value>2.0.2</ows20:Value>
+          <ows20:Value>3.0.0</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Parameter name="sections">
+        <ows20:AllowedValues>
+          <ows20:Value>All</ows20:Value>
+          <ows20:Value>Filter_Capabilities</ows20:Value>
+          <ows20:Value>OperationsMetadata</ows20:Value>
+          <ows20:Value>ServiceIdentification</ows20:Value>
+          <ows20:Value>ServiceProvider</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+    </ows20:Operation>
+    <ows20:Operation name="GetDomain">
+      <ows20:DCP>
+        <ows20:HTTP>
+          <ows20:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg"/>
+          <ows20:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg"/>
+        </ows20:HTTP>
+      </ows20:DCP>
+      <ows20:Parameter name="ParameterName">
+        <ows20:AllowedValues>
+          <ows20:Value>GetCapabilities.acceptFormats</ows20:Value>
+          <ows20:Value>GetCapabilities.acceptVersions</ows20:Value>
+          <ows20:Value>GetCapabilities.sections</ows20:Value>
+          <ows20:Value>GetRecordById.ElementSetName</ows20:Value>
+          <ows20:Value>GetRecordById.outputFormat</ows20:Value>
+          <ows20:Value>GetRecordById.outputSchema</ows20:Value>
+          <ows20:Value>GetRecords.CONSTRAINTLANGUAGE</ows20:Value>
+          <ows20:Value>GetRecords.ElementSetName</ows20:Value>
+          <ows20:Value>GetRecords.outputFormat</ows20:Value>
+          <ows20:Value>GetRecords.outputSchema</ows20:Value>
+          <ows20:Value>GetRecords.typeNames</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+    </ows20:Operation>
+    <ows20:Operation name="GetRecords">
+      <ows20:DCP>
+        <ows20:HTTP>
+          <ows20:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg"/>
+          <ows20:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg"/>
+        </ows20:HTTP>
+      </ows20:DCP>
+      <ows20:Parameter name="CONSTRAINTLANGUAGE">
+        <ows20:AllowedValues>
+          <ows20:Value>CQL_TEXT</ows20:Value>
+          <ows20:Value>FILTER</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Parameter name="ElementSetName">
+        <ows20:AllowedValues>
+          <ows20:Value>brief</ows20:Value>
+          <ows20:Value>full</ows20:Value>
+          <ows20:Value>summary</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Parameter name="outputFormat">
+        <ows20:AllowedValues>
+          <ows20:Value>application/atom+xml</ows20:Value>
+          <ows20:Value>application/json</ows20:Value>
+          <ows20:Value>application/xml</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Parameter name="outputSchema">
+        <ows20:AllowedValues>
+          <ows20:Value>http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/</ows20:Value>
+          <ows20:Value>http://www.interlis.ch/INTERLIS2.3</ows20:Value>
+          <ows20:Value>http://www.opengis.net/cat/csw/3.0</ows20:Value>
+          <ows20:Value>http://www.opengis.net/cat/csw/csdgm</ows20:Value>
+          <ows20:Value>http://www.w3.org/2005/Atom</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Parameter name="typeNames">
+        <ows20:AllowedValues>
+          <ows20:Value>csw:Record</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Constraint name="MaxRecordDefault">
+        <ows20:AllowedValues>
+          <ows20:Value>10</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Constraint>
+      <ows20:Constraint name="OpenSearchDescriptionDocument">
+        <ows20:AllowedValues>
+          <ows20:Value>http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg?mode=opensearch&service=CSW&version=3.0.0&request=GetCapabilities</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Constraint>
+      <ows20:Constraint name="FederatedCatalogues">
+        <ows20:AllowedValues>
+          <ows20:Value>http://demo.pycsw.org/gisdata/csw</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Constraint>
+    </ows20:Operation>
+    <ows20:Operation name="GetRecordById">
+      <ows20:DCP>
+        <ows20:HTTP>
+          <ows20:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg"/>
+          <ows20:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg"/>
+        </ows20:HTTP>
+      </ows20:DCP>
+      <ows20:Parameter name="ElementSetName">
+        <ows20:AllowedValues>
+          <ows20:Value>brief</ows20:Value>
+          <ows20:Value>full</ows20:Value>
+          <ows20:Value>summary</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Parameter name="outputFormat">
+        <ows20:AllowedValues>
+          <ows20:Value>application/atom+xml</ows20:Value>
+          <ows20:Value>application/json</ows20:Value>
+          <ows20:Value>application/xml</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Parameter name="outputSchema">
+        <ows20:AllowedValues>
+          <ows20:Value>http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/</ows20:Value>
+          <ows20:Value>http://www.interlis.ch/INTERLIS2.3</ows20:Value>
+          <ows20:Value>http://www.opengis.net/cat/csw/3.0</ows20:Value>
+          <ows20:Value>http://www.opengis.net/cat/csw/csdgm</ows20:Value>
+          <ows20:Value>http://www.w3.org/2005/Atom</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+    </ows20:Operation>
+    <ows20:Operation name="GetRepositoryItem">
+      <ows20:DCP>
+        <ows20:HTTP>
+          <ows20:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg"/>
+        </ows20:HTTP>
+      </ows20:DCP>
+    </ows20:Operation>
+    <ows20:Parameter name="service">
+      <ows20:AllowedValues>
+        <ows20:Value>CSW</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Parameter>
+    <ows20:Parameter name="version">
+      <ows20:AllowedValues>
+        <ows20:Value>2.0.2</ows20:Value>
+        <ows20:Value>3.0.0</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Parameter>
+    <ows20:Constraint name="CoreQueryables">
+      <ows20:AllowedValues>
+        <ows20:Value>csw:AnyText</ows20:Value>
+        <ows20:Value>dc:contributor</ows20:Value>
+        <ows20:Value>dc:creator</ows20:Value>
+        <ows20:Value>dc:date</ows20:Value>
+        <ows20:Value>dc:format</ows20:Value>
+        <ows20:Value>dc:identifier</ows20:Value>
+        <ows20:Value>dc:language</ows20:Value>
+        <ows20:Value>dc:publisher</ows20:Value>
+        <ows20:Value>dc:relation</ows20:Value>
+        <ows20:Value>dc:rights</ows20:Value>
+        <ows20:Value>dc:source</ows20:Value>
+        <ows20:Value>dc:subject</ows20:Value>
+        <ows20:Value>dc:title</ows20:Value>
+        <ows20:Value>dc:type</ows20:Value>
+        <ows20:Value>dct:abstract</ows20:Value>
+        <ows20:Value>dct:modified</ows20:Value>
+        <ows20:Value>ows:BoundingBox</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="FederatedCatalogues">
+      <ows20:AllowedValues>
+        <ows20:Value>http://demo.pycsw.org/gisdata/csw</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="MaxRecordDefault">
+      <ows20:AllowedValues>
+        <ows20:Value>10</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="PostEncoding">
+      <ows20:AllowedValues>
+        <ows20:Value>SOAP</ows20:Value>
+        <ows20:Value>XML</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="XPathQueryables">
+      <ows20:AllowedValues>
+        <ows20:Value>allowed</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/CoreQueryables">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/CoreSortables">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/DefaultSortingAlgorithm">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Filter-CQL">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Filter-FES-KVP-Advanced">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Filter-FES-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetCapabilities-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetDomain-KVP">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetDomain-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetRecordById-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetRecords-Async-KVP">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetRecords-Async-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetRecords-Basic-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetRecords-Distributed-KVP">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetRecords-Distributed-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Harvest-Async-KVP">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Harvest-Async-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Harvest-Basic-KVP">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Harvest-Basic-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Harvest-Periodic-KVP">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Harvest-Periodic-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/OpenSearch">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/SupportedGMLVersions">
+      <ows20:AllowedValues>
+        <ows20:Value>http://www.opengis.net/gml</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Transaction">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+  </ows20:OperationsMetadata>
+</csw30:Capabilities>
diff --git a/tests/expected/suites_csw30_get_604d9379-741c-42e5-b4cf-92e56c87fa64.xml b/tests/expected/suites_csw30_get_604d9379-741c-42e5-b4cf-92e56c87fa64.xml
new file mode 100644
index 0000000..17019ae
--- /dev/null
+++ b/tests/expected/suites_csw30_get_604d9379-741c-42e5-b4cf-92e56c87fa64.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- PYCSW_VERSION -->
+<csw30:GetRecordsResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:csw30="http://www.opengis.net/cat/csw/3.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:ows20="http://www.opengis.net/ows/2.0" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="3.0.0" xsi: [...]
+  <csw30:SearchStatus timestamp="PYCSW_TIMESTAMP"/>
+  <csw30:SearchResults expires="PYCSW_EXPIRES" nextRecord="0" numberOfRecordsMatched="3" numberOfRecordsReturned="3" recordSchema="http://www.opengis.net/cat/csw/3.0" status="subset" elementSet="full" elapsedTime="PYCSW_ELAPSED_TIME">
+    <csw30:Record>
+      <dc:identifier>urn:uuid:1ef30a8b-876d-4828-9246-c37ab4510bbd</dc:identifier>
+      <dc:title></dc:title>
+      <dc:type>http://purl.org/dc/dcmitype/Service</dc:type>
+      <dct:abstract>Proin sit amet justo. In justo. Aenean adipiscing nulla id tellus.</dct:abstract>
+      <ows20:BoundingBox crs="http://www.opengis.net/def/crs/EPSG/0/4326" dimensions="2">
+        <ows20:LowerCorner>60.04 13.75</ows20:LowerCorner>
+        <ows20:UpperCorner>68.41 17.92</ows20:UpperCorner>
+      </ows20:BoundingBox>
+    </csw30:Record>
+    <csw30:Record>
+      <dc:identifier>urn:uuid:784e2afd-a9fd-44a6-9a92-a3848371c8ec</dc:identifier>
+      <dc:title>Aliquam fermentum purus quis arcu</dc:title>
+      <dc:type>http://purl.org/dc/dcmitype/Text</dc:type>
+      <dc:subject>Hydrography--Dictionaries</dc:subject>
+      <dc:format>application/pdf</dc:format>
+      <dct:abstract>Vestibulum quis ipsum sit amet metus imperdiet vehicula. Nulla scelerisque cursus mi.</dct:abstract>
+      <dc:date>2006-05-12</dc:date>
+    </csw30:Record>
+    <csw30:Record>
+      <dc:identifier>urn:uuid:a06af396-3105-442d-8b40-22b57a90d2f2</dc:identifier>
+      <dc:title>Lorem ipsum dolor sit amet</dc:title>
+      <dc:type>http://purl.org/dc/dcmitype/Image</dc:type>
+      <dc:format>image/jpeg</dc:format>
+    </csw30:Record>
+  </csw30:SearchResults>
+</csw30:GetRecordsResponse>
diff --git a/tests/expected/suites_csw30_get_60e6af95-d5fc-465a-82e2-fd2e6d85e4af.xml b/tests/expected/suites_csw30_get_60e6af95-d5fc-465a-82e2-fd2e6d85e4af.xml
new file mode 100644
index 0000000..d4ac1d5
--- /dev/null
+++ b/tests/expected/suites_csw30_get_60e6af95-d5fc-465a-82e2-fd2e6d85e4af.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- PYCSW_VERSION -->
+<ows20:ExceptionReport xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:ows20="http://www.opengis.net/ows/2.0" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="3.0.0" xml:lang="en-US" xsi:schemaLocation="http://www.opengis. [...]
+  <ows20:Exception exceptionCode="InvalidParameterValue" locator="typenames">
+    <ows20:ExceptionText>Invalid typeNames parameter value: UnknownType</ows20:ExceptionText>
+  </ows20:Exception>
+</ows20:ExceptionReport>
diff --git a/tests/expected/suites_csw30_get_62ad94c2-b558-4265-a427-23d6677975d6.xml b/tests/expected/suites_csw30_get_62ad94c2-b558-4265-a427-23d6677975d6.xml
new file mode 100644
index 0000000..faf07a5
--- /dev/null
+++ b/tests/expected/suites_csw30_get_62ad94c2-b558-4265-a427-23d6677975d6.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- PYCSW_VERSION -->
+<ows20:ExceptionReport xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:ows20="http://www.opengis.net/ows/2.0" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="3.0.0" xml:lang="en-US" xsi:schemaLocation="http://www.opengis. [...]
+  <ows20:Exception exceptionCode="NotFound" locator="recordids">
+    <ows20:ExceptionText>No records found for 'uid-bc5017e6-5cc8-4b03-aee7-d88f88caba0a'</ows20:ExceptionText>
+  </ows20:Exception>
+</ows20:ExceptionReport>
diff --git a/tests/expected/suites_csw30_get_6a5e247b-0961-4b8a-a0d6-35a491d9cfe7.xml b/tests/expected/suites_csw30_get_6a5e247b-0961-4b8a-a0d6-35a491d9cfe7.xml
new file mode 100644
index 0000000..5912e69
--- /dev/null
+++ b/tests/expected/suites_csw30_get_6a5e247b-0961-4b8a-a0d6-35a491d9cfe7.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- PYCSW_VERSION -->
+<ows20:ExceptionReport xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:ows20="http://www.opengis.net/ows/2.0" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="3.0.0" xml:lang="en-US" xsi:schemaLocation="http://www.opengis. [...]
+  <ows20:Exception exceptionCode="InvalidParameterValue" locator="elementsetname">
+    <ows20:ExceptionText>Invalid ElementSetName parameter value: undefined-view</ows20:ExceptionText>
+  </ows20:Exception>
+</ows20:ExceptionReport>
diff --git a/tests/expected/suites_csw30_get_6a9d0558-9d87-495b-b999-b49a3ef1cf99.xml b/tests/expected/suites_csw30_get_6a9d0558-9d87-495b-b999-b49a3ef1cf99.xml
new file mode 100644
index 0000000..ce9c935
--- /dev/null
+++ b/tests/expected/suites_csw30_get_6a9d0558-9d87-495b-b999-b49a3ef1cf99.xml
@@ -0,0 +1,491 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- PYCSW_VERSION -->
+<csw30:Capabilities xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:csw30="http://www.opengis.net/cat/csw/3.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:fes20="http://www.opengis.net/fes/2.0" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:ows11="http://www.opengis.net/ows/1.1" xmlns:ows20="http://www.opengis.net/ows/2.0" xmlns:xlink="http://www.w3.org/199 [...]
+  <ows20:ServiceIdentification>
+    <ows20:Title>pycsw Geospatial Catalogue</ows20:Title>
+    <ows20:Abstract>pycsw is an OGC CSW server implementation written in Python</ows20:Abstract>
+    <ows20:Keywords>
+      <ows20:Keyword>catalogue</ows20:Keyword>
+      <ows20:Keyword>discovery</ows20:Keyword>
+      <ows20:Type codeSpace="ISOTC211/19115">theme</ows20:Type>
+    </ows20:Keywords>
+    <ows20:ServiceType codeSpace="OGC">CSW</ows20:ServiceType>
+    <ows20:ServiceTypeVersion>2.0.2</ows20:ServiceTypeVersion>
+    <ows20:ServiceTypeVersion>3.0.0</ows20:ServiceTypeVersion>
+    <ows20:Fees>None</ows20:Fees>
+    <ows20:AccessConstraints>None</ows20:AccessConstraints>
+  </ows20:ServiceIdentification>
+  <ows20:ServiceProvider>
+    <ows20:ProviderName>pycsw</ows20:ProviderName>
+    <ows20:ProviderSite xlink:type="simple" xlink:href="http://pycsw.org/"/>
+    <ows20:ServiceContact>
+      <ows20:IndividualName>Kralidis, Tom</ows20:IndividualName>
+      <ows20:PositionName>Senior Systems Scientist</ows20:PositionName>
+      <ows20:ContactInfo>
+        <ows20:Phone>
+          <ows20:Voice>+01-416-xxx-xxxx</ows20:Voice>
+          <ows20:Facsimile>+01-416-xxx-xxxx</ows20:Facsimile>
+        </ows20:Phone>
+        <ows20:Address>
+          <ows20:DeliveryPoint>TBA</ows20:DeliveryPoint>
+          <ows20:City>Toronto</ows20:City>
+          <ows20:AdministrativeArea>Ontario</ows20:AdministrativeArea>
+          <ows20:PostalCode>M9C 3Z9</ows20:PostalCode>
+          <ows20:Country>Canada</ows20:Country>
+          <ows20:ElectronicMailAddress>tomkralidis at gmail.com</ows20:ElectronicMailAddress>
+        </ows20:Address>
+        <ows20:OnlineResource xlink:type="simple" xlink:href="http://kralidis.ca/"/>
+        <ows20:HoursOfService>0800h - 1600h EST</ows20:HoursOfService>
+        <ows20:ContactInstructions>During hours of service.  Off on weekends.</ows20:ContactInstructions>
+      </ows20:ContactInfo>
+      <ows20:Role codeSpace="ISOTC211/19115">pointOfContact</ows20:Role>
+    </ows20:ServiceContact>
+  </ows20:ServiceProvider>
+  <ows20:OperationsMetadata>
+    <ows20:Operation name="GetCapabilities">
+      <ows20:DCP>
+        <ows20:HTTP>
+          <ows20:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg"/>
+          <ows20:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg"/>
+        </ows20:HTTP>
+      </ows20:DCP>
+      <ows20:Parameter name="acceptFormats">
+        <ows20:AllowedValues>
+          <ows20:Value>application/xml</ows20:Value>
+          <ows20:Value>text/xml</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Parameter name="acceptVersions">
+        <ows20:AllowedValues>
+          <ows20:Value>2.0.2</ows20:Value>
+          <ows20:Value>3.0.0</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Parameter name="sections">
+        <ows20:AllowedValues>
+          <ows20:Value>All</ows20:Value>
+          <ows20:Value>Filter_Capabilities</ows20:Value>
+          <ows20:Value>OperationsMetadata</ows20:Value>
+          <ows20:Value>ServiceIdentification</ows20:Value>
+          <ows20:Value>ServiceProvider</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+    </ows20:Operation>
+    <ows20:Operation name="GetDomain">
+      <ows20:DCP>
+        <ows20:HTTP>
+          <ows20:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg"/>
+          <ows20:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg"/>
+        </ows20:HTTP>
+      </ows20:DCP>
+      <ows20:Parameter name="ParameterName">
+        <ows20:AllowedValues>
+          <ows20:Value>GetCapabilities.acceptFormats</ows20:Value>
+          <ows20:Value>GetCapabilities.acceptVersions</ows20:Value>
+          <ows20:Value>GetCapabilities.sections</ows20:Value>
+          <ows20:Value>GetRecordById.ElementSetName</ows20:Value>
+          <ows20:Value>GetRecordById.outputFormat</ows20:Value>
+          <ows20:Value>GetRecordById.outputSchema</ows20:Value>
+          <ows20:Value>GetRecords.CONSTRAINTLANGUAGE</ows20:Value>
+          <ows20:Value>GetRecords.ElementSetName</ows20:Value>
+          <ows20:Value>GetRecords.outputFormat</ows20:Value>
+          <ows20:Value>GetRecords.outputSchema</ows20:Value>
+          <ows20:Value>GetRecords.typeNames</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+    </ows20:Operation>
+    <ows20:Operation name="GetRecords">
+      <ows20:DCP>
+        <ows20:HTTP>
+          <ows20:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg"/>
+          <ows20:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg"/>
+        </ows20:HTTP>
+      </ows20:DCP>
+      <ows20:Parameter name="CONSTRAINTLANGUAGE">
+        <ows20:AllowedValues>
+          <ows20:Value>CQL_TEXT</ows20:Value>
+          <ows20:Value>FILTER</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Parameter name="ElementSetName">
+        <ows20:AllowedValues>
+          <ows20:Value>brief</ows20:Value>
+          <ows20:Value>full</ows20:Value>
+          <ows20:Value>summary</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Parameter name="outputFormat">
+        <ows20:AllowedValues>
+          <ows20:Value>application/atom+xml</ows20:Value>
+          <ows20:Value>application/json</ows20:Value>
+          <ows20:Value>application/xml</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Parameter name="outputSchema">
+        <ows20:AllowedValues>
+          <ows20:Value>http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/</ows20:Value>
+          <ows20:Value>http://www.interlis.ch/INTERLIS2.3</ows20:Value>
+          <ows20:Value>http://www.opengis.net/cat/csw/3.0</ows20:Value>
+          <ows20:Value>http://www.opengis.net/cat/csw/csdgm</ows20:Value>
+          <ows20:Value>http://www.w3.org/2005/Atom</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Parameter name="typeNames">
+        <ows20:AllowedValues>
+          <ows20:Value>csw:Record</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Constraint name="MaxRecordDefault">
+        <ows20:AllowedValues>
+          <ows20:Value>10</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Constraint>
+      <ows20:Constraint name="OpenSearchDescriptionDocument">
+        <ows20:AllowedValues>
+          <ows20:Value>http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg?mode=opensearch&service=CSW&version=3.0.0&request=GetCapabilities</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Constraint>
+      <ows20:Constraint name="FederatedCatalogues">
+        <ows20:AllowedValues>
+          <ows20:Value>http://demo.pycsw.org/gisdata/csw</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Constraint>
+    </ows20:Operation>
+    <ows20:Operation name="GetRecordById">
+      <ows20:DCP>
+        <ows20:HTTP>
+          <ows20:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg"/>
+          <ows20:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg"/>
+        </ows20:HTTP>
+      </ows20:DCP>
+      <ows20:Parameter name="ElementSetName">
+        <ows20:AllowedValues>
+          <ows20:Value>brief</ows20:Value>
+          <ows20:Value>full</ows20:Value>
+          <ows20:Value>summary</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Parameter name="outputFormat">
+        <ows20:AllowedValues>
+          <ows20:Value>application/atom+xml</ows20:Value>
+          <ows20:Value>application/json</ows20:Value>
+          <ows20:Value>application/xml</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Parameter name="outputSchema">
+        <ows20:AllowedValues>
+          <ows20:Value>http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/</ows20:Value>
+          <ows20:Value>http://www.interlis.ch/INTERLIS2.3</ows20:Value>
+          <ows20:Value>http://www.opengis.net/cat/csw/3.0</ows20:Value>
+          <ows20:Value>http://www.opengis.net/cat/csw/csdgm</ows20:Value>
+          <ows20:Value>http://www.w3.org/2005/Atom</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+    </ows20:Operation>
+    <ows20:Operation name="GetRepositoryItem">
+      <ows20:DCP>
+        <ows20:HTTP>
+          <ows20:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg"/>
+        </ows20:HTTP>
+      </ows20:DCP>
+    </ows20:Operation>
+    <ows20:Parameter name="service">
+      <ows20:AllowedValues>
+        <ows20:Value>CSW</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Parameter>
+    <ows20:Parameter name="version">
+      <ows20:AllowedValues>
+        <ows20:Value>2.0.2</ows20:Value>
+        <ows20:Value>3.0.0</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Parameter>
+    <ows20:Constraint name="CoreQueryables">
+      <ows20:AllowedValues>
+        <ows20:Value>csw:AnyText</ows20:Value>
+        <ows20:Value>dc:contributor</ows20:Value>
+        <ows20:Value>dc:creator</ows20:Value>
+        <ows20:Value>dc:date</ows20:Value>
+        <ows20:Value>dc:format</ows20:Value>
+        <ows20:Value>dc:identifier</ows20:Value>
+        <ows20:Value>dc:language</ows20:Value>
+        <ows20:Value>dc:publisher</ows20:Value>
+        <ows20:Value>dc:relation</ows20:Value>
+        <ows20:Value>dc:rights</ows20:Value>
+        <ows20:Value>dc:source</ows20:Value>
+        <ows20:Value>dc:subject</ows20:Value>
+        <ows20:Value>dc:title</ows20:Value>
+        <ows20:Value>dc:type</ows20:Value>
+        <ows20:Value>dct:abstract</ows20:Value>
+        <ows20:Value>dct:modified</ows20:Value>
+        <ows20:Value>ows:BoundingBox</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="FederatedCatalogues">
+      <ows20:AllowedValues>
+        <ows20:Value>http://demo.pycsw.org/gisdata/csw</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="MaxRecordDefault">
+      <ows20:AllowedValues>
+        <ows20:Value>10</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="PostEncoding">
+      <ows20:AllowedValues>
+        <ows20:Value>SOAP</ows20:Value>
+        <ows20:Value>XML</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="XPathQueryables">
+      <ows20:AllowedValues>
+        <ows20:Value>allowed</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/CoreQueryables">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/CoreSortables">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/DefaultSortingAlgorithm">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Filter-CQL">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Filter-FES-KVP-Advanced">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Filter-FES-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetCapabilities-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetDomain-KVP">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetDomain-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetRecordById-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetRecords-Async-KVP">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetRecords-Async-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetRecords-Basic-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetRecords-Distributed-KVP">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetRecords-Distributed-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Harvest-Async-KVP">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Harvest-Async-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Harvest-Basic-KVP">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Harvest-Basic-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Harvest-Periodic-KVP">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Harvest-Periodic-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/OpenSearch">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/SupportedGMLVersions">
+      <ows20:AllowedValues>
+        <ows20:Value>http://www.opengis.net/gml</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Transaction">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+  </ows20:OperationsMetadata>
+  <ows20:Languages>
+    <ows20:Language>en</ows20:Language>
+  </ows20:Languages>
+  <fes20:Filter_Capabilities>
+    <fes20:Conformance>
+      <fes20:Constraint name="ImplementsQuery">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsAdHocQuery">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsFunctions">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsResourceld">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsMinStandardFilter">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsStandardFilter">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsMinSpatialFilter">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsSpatialFilter">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsMinTemporalFilter">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsTemporalFilter">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsVersionNav">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsSorting">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsExtendedOperators">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsMinimumXPath">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsSchemaElementFunc">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+    </fes20:Conformance>
+    <fes20:Id_Capabilities>
+      <fes20:ResourceIdentifier name="csw30:id"/>
+    </fes20:Id_Capabilities>
+    <fes20:Scalar_Capabilities>
+      <fes20:LogicalOperators/>
+      <fes20:ComparisonOperators>
+        <fes20:ComparisonOperator name="PropertyIsBetween"/>
+        <fes20:ComparisonOperator name="PropertyIsEqualTo"/>
+        <fes20:ComparisonOperator name="PropertyIsGreaterThan"/>
+        <fes20:ComparisonOperator name="PropertyIsGreaterThanOrEqualTo"/>
+        <fes20:ComparisonOperator name="PropertyIsLessThan"/>
+        <fes20:ComparisonOperator name="PropertyIsLessThanOrEqualTo"/>
+        <fes20:ComparisonOperator name="PropertyIsLike"/>
+        <fes20:ComparisonOperator name="PropertyIsNotEqualTo"/>
+        <fes20:ComparisonOperator name="PropertyIsNull"/>
+      </fes20:ComparisonOperators>
+    </fes20:Scalar_Capabilities>
+    <fes20:Spatial_Capabilities>
+      <fes20:GeometryOperands>
+        <fes20:GeometryOperand name="gml:Point"/>
+        <fes20:GeometryOperand name="gml:LineString"/>
+        <fes20:GeometryOperand name="gml:Polygon"/>
+        <fes20:GeometryOperand name="gml:Envelope"/>
+      </fes20:GeometryOperands>
+      <fes20:SpatialOperators>
+        <fes20:SpatialOperator name="BBOX"/>
+        <fes20:SpatialOperator name="Beyond"/>
+        <fes20:SpatialOperator name="Contains"/>
+        <fes20:SpatialOperator name="Crosses"/>
+        <fes20:SpatialOperator name="Disjoint"/>
+        <fes20:SpatialOperator name="DWithin"/>
+        <fes20:SpatialOperator name="Equals"/>
+        <fes20:SpatialOperator name="Intersects"/>
+        <fes20:SpatialOperator name="Overlaps"/>
+        <fes20:SpatialOperator name="Touches"/>
+        <fes20:SpatialOperator name="Within"/>
+      </fes20:SpatialOperators>
+    </fes20:Spatial_Capabilities>
+    <fes20:Functions>
+      <fes20:Function name="length">
+        <fes20:Returns>xs:string</fes20:Returns>
+      </fes20:Function>
+      <fes20:Function name="lower">
+        <fes20:Returns>xs:string</fes20:Returns>
+      </fes20:Function>
+      <fes20:Function name="ltrim">
+        <fes20:Returns>xs:string</fes20:Returns>
+      </fes20:Function>
+      <fes20:Function name="rtrim">
+        <fes20:Returns>xs:string</fes20:Returns>
+      </fes20:Function>
+      <fes20:Function name="trim">
+        <fes20:Returns>xs:string</fes20:Returns>
+      </fes20:Function>
+      <fes20:Function name="upper">
+        <fes20:Returns>xs:string</fes20:Returns>
+      </fes20:Function>
+    </fes20:Functions>
+  </fes20:Filter_Capabilities>
+</csw30:Capabilities>
diff --git a/tests/expected/suites_csw30_get_6bd790c9-6019-4652-9c91-330a894d6700.xml b/tests/expected/suites_csw30_get_6bd790c9-6019-4652-9c91-330a894d6700.xml
new file mode 100644
index 0000000..1430fc3
--- /dev/null
+++ b/tests/expected/suites_csw30_get_6bd790c9-6019-4652-9c91-330a894d6700.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- PYCSW_VERSION -->
+<csw30:GetRecordsResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:csw30="http://www.opengis.net/cat/csw/3.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="3.0.0" xsi:schemaLocation="http://www.opengis.net/cat/cs [...]
+  <csw30:SearchStatus timestamp="PYCSW_TIMESTAMP"/>
+  <csw30:SearchResults expires="PYCSW_EXPIRES" nextRecord="0" numberOfRecordsMatched="1" numberOfRecordsReturned="1" recordSchema="http://www.opengis.net/cat/csw/3.0" status="subset" elementSet="full" elapsedTime="PYCSW_ELAPSED_TIME">
+    <csw30:Record>
+      <dc:identifier>urn:uuid:e9330592-0932-474b-be34-c3a3bb67c7db</dc:identifier>
+      <dc:title>Fuscé vitae ligulä</dc:title>
+      <dc:type>http://purl.org/dc/dcmitype/Text</dc:type>
+      <dc:subject>Land titles</dc:subject>
+      <dc:format>text/rtf</dc:format>
+      <dct:abstract>Morbi ultriçes, dui suscipit vestibulum prètium, velit ante pretium tortor, egët tincidunt pede odio ac nulla.</dct:abstract>
+      <dc:date>2003-05-09</dc:date>
+    </csw30:Record>
+  </csw30:SearchResults>
+</csw30:GetRecordsResponse>
diff --git a/tests/expected/suites_csw30_get_6e9cba43-5e27-415d-adbd-a92851c2c173.xml b/tests/expected/suites_csw30_get_6e9cba43-5e27-415d-adbd-a92851c2c173.xml
new file mode 100644
index 0000000..ce9c935
--- /dev/null
+++ b/tests/expected/suites_csw30_get_6e9cba43-5e27-415d-adbd-a92851c2c173.xml
@@ -0,0 +1,491 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- PYCSW_VERSION -->
+<csw30:Capabilities xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:csw30="http://www.opengis.net/cat/csw/3.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:fes20="http://www.opengis.net/fes/2.0" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:ows11="http://www.opengis.net/ows/1.1" xmlns:ows20="http://www.opengis.net/ows/2.0" xmlns:xlink="http://www.w3.org/199 [...]
+  <ows20:ServiceIdentification>
+    <ows20:Title>pycsw Geospatial Catalogue</ows20:Title>
+    <ows20:Abstract>pycsw is an OGC CSW server implementation written in Python</ows20:Abstract>
+    <ows20:Keywords>
+      <ows20:Keyword>catalogue</ows20:Keyword>
+      <ows20:Keyword>discovery</ows20:Keyword>
+      <ows20:Type codeSpace="ISOTC211/19115">theme</ows20:Type>
+    </ows20:Keywords>
+    <ows20:ServiceType codeSpace="OGC">CSW</ows20:ServiceType>
+    <ows20:ServiceTypeVersion>2.0.2</ows20:ServiceTypeVersion>
+    <ows20:ServiceTypeVersion>3.0.0</ows20:ServiceTypeVersion>
+    <ows20:Fees>None</ows20:Fees>
+    <ows20:AccessConstraints>None</ows20:AccessConstraints>
+  </ows20:ServiceIdentification>
+  <ows20:ServiceProvider>
+    <ows20:ProviderName>pycsw</ows20:ProviderName>
+    <ows20:ProviderSite xlink:type="simple" xlink:href="http://pycsw.org/"/>
+    <ows20:ServiceContact>
+      <ows20:IndividualName>Kralidis, Tom</ows20:IndividualName>
+      <ows20:PositionName>Senior Systems Scientist</ows20:PositionName>
+      <ows20:ContactInfo>
+        <ows20:Phone>
+          <ows20:Voice>+01-416-xxx-xxxx</ows20:Voice>
+          <ows20:Facsimile>+01-416-xxx-xxxx</ows20:Facsimile>
+        </ows20:Phone>
+        <ows20:Address>
+          <ows20:DeliveryPoint>TBA</ows20:DeliveryPoint>
+          <ows20:City>Toronto</ows20:City>
+          <ows20:AdministrativeArea>Ontario</ows20:AdministrativeArea>
+          <ows20:PostalCode>M9C 3Z9</ows20:PostalCode>
+          <ows20:Country>Canada</ows20:Country>
+          <ows20:ElectronicMailAddress>tomkralidis at gmail.com</ows20:ElectronicMailAddress>
+        </ows20:Address>
+        <ows20:OnlineResource xlink:type="simple" xlink:href="http://kralidis.ca/"/>
+        <ows20:HoursOfService>0800h - 1600h EST</ows20:HoursOfService>
+        <ows20:ContactInstructions>During hours of service.  Off on weekends.</ows20:ContactInstructions>
+      </ows20:ContactInfo>
+      <ows20:Role codeSpace="ISOTC211/19115">pointOfContact</ows20:Role>
+    </ows20:ServiceContact>
+  </ows20:ServiceProvider>
+  <ows20:OperationsMetadata>
+    <ows20:Operation name="GetCapabilities">
+      <ows20:DCP>
+        <ows20:HTTP>
+          <ows20:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg"/>
+          <ows20:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg"/>
+        </ows20:HTTP>
+      </ows20:DCP>
+      <ows20:Parameter name="acceptFormats">
+        <ows20:AllowedValues>
+          <ows20:Value>application/xml</ows20:Value>
+          <ows20:Value>text/xml</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Parameter name="acceptVersions">
+        <ows20:AllowedValues>
+          <ows20:Value>2.0.2</ows20:Value>
+          <ows20:Value>3.0.0</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Parameter name="sections">
+        <ows20:AllowedValues>
+          <ows20:Value>All</ows20:Value>
+          <ows20:Value>Filter_Capabilities</ows20:Value>
+          <ows20:Value>OperationsMetadata</ows20:Value>
+          <ows20:Value>ServiceIdentification</ows20:Value>
+          <ows20:Value>ServiceProvider</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+    </ows20:Operation>
+    <ows20:Operation name="GetDomain">
+      <ows20:DCP>
+        <ows20:HTTP>
+          <ows20:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg"/>
+          <ows20:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg"/>
+        </ows20:HTTP>
+      </ows20:DCP>
+      <ows20:Parameter name="ParameterName">
+        <ows20:AllowedValues>
+          <ows20:Value>GetCapabilities.acceptFormats</ows20:Value>
+          <ows20:Value>GetCapabilities.acceptVersions</ows20:Value>
+          <ows20:Value>GetCapabilities.sections</ows20:Value>
+          <ows20:Value>GetRecordById.ElementSetName</ows20:Value>
+          <ows20:Value>GetRecordById.outputFormat</ows20:Value>
+          <ows20:Value>GetRecordById.outputSchema</ows20:Value>
+          <ows20:Value>GetRecords.CONSTRAINTLANGUAGE</ows20:Value>
+          <ows20:Value>GetRecords.ElementSetName</ows20:Value>
+          <ows20:Value>GetRecords.outputFormat</ows20:Value>
+          <ows20:Value>GetRecords.outputSchema</ows20:Value>
+          <ows20:Value>GetRecords.typeNames</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+    </ows20:Operation>
+    <ows20:Operation name="GetRecords">
+      <ows20:DCP>
+        <ows20:HTTP>
+          <ows20:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg"/>
+          <ows20:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg"/>
+        </ows20:HTTP>
+      </ows20:DCP>
+      <ows20:Parameter name="CONSTRAINTLANGUAGE">
+        <ows20:AllowedValues>
+          <ows20:Value>CQL_TEXT</ows20:Value>
+          <ows20:Value>FILTER</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Parameter name="ElementSetName">
+        <ows20:AllowedValues>
+          <ows20:Value>brief</ows20:Value>
+          <ows20:Value>full</ows20:Value>
+          <ows20:Value>summary</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Parameter name="outputFormat">
+        <ows20:AllowedValues>
+          <ows20:Value>application/atom+xml</ows20:Value>
+          <ows20:Value>application/json</ows20:Value>
+          <ows20:Value>application/xml</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Parameter name="outputSchema">
+        <ows20:AllowedValues>
+          <ows20:Value>http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/</ows20:Value>
+          <ows20:Value>http://www.interlis.ch/INTERLIS2.3</ows20:Value>
+          <ows20:Value>http://www.opengis.net/cat/csw/3.0</ows20:Value>
+          <ows20:Value>http://www.opengis.net/cat/csw/csdgm</ows20:Value>
+          <ows20:Value>http://www.w3.org/2005/Atom</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Parameter name="typeNames">
+        <ows20:AllowedValues>
+          <ows20:Value>csw:Record</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Constraint name="MaxRecordDefault">
+        <ows20:AllowedValues>
+          <ows20:Value>10</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Constraint>
+      <ows20:Constraint name="OpenSearchDescriptionDocument">
+        <ows20:AllowedValues>
+          <ows20:Value>http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg?mode=opensearch&service=CSW&version=3.0.0&request=GetCapabilities</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Constraint>
+      <ows20:Constraint name="FederatedCatalogues">
+        <ows20:AllowedValues>
+          <ows20:Value>http://demo.pycsw.org/gisdata/csw</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Constraint>
+    </ows20:Operation>
+    <ows20:Operation name="GetRecordById">
+      <ows20:DCP>
+        <ows20:HTTP>
+          <ows20:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg"/>
+          <ows20:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg"/>
+        </ows20:HTTP>
+      </ows20:DCP>
+      <ows20:Parameter name="ElementSetName">
+        <ows20:AllowedValues>
+          <ows20:Value>brief</ows20:Value>
+          <ows20:Value>full</ows20:Value>
+          <ows20:Value>summary</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Parameter name="outputFormat">
+        <ows20:AllowedValues>
+          <ows20:Value>application/atom+xml</ows20:Value>
+          <ows20:Value>application/json</ows20:Value>
+          <ows20:Value>application/xml</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Parameter name="outputSchema">
+        <ows20:AllowedValues>
+          <ows20:Value>http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/</ows20:Value>
+          <ows20:Value>http://www.interlis.ch/INTERLIS2.3</ows20:Value>
+          <ows20:Value>http://www.opengis.net/cat/csw/3.0</ows20:Value>
+          <ows20:Value>http://www.opengis.net/cat/csw/csdgm</ows20:Value>
+          <ows20:Value>http://www.w3.org/2005/Atom</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+    </ows20:Operation>
+    <ows20:Operation name="GetRepositoryItem">
+      <ows20:DCP>
+        <ows20:HTTP>
+          <ows20:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg"/>
+        </ows20:HTTP>
+      </ows20:DCP>
+    </ows20:Operation>
+    <ows20:Parameter name="service">
+      <ows20:AllowedValues>
+        <ows20:Value>CSW</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Parameter>
+    <ows20:Parameter name="version">
+      <ows20:AllowedValues>
+        <ows20:Value>2.0.2</ows20:Value>
+        <ows20:Value>3.0.0</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Parameter>
+    <ows20:Constraint name="CoreQueryables">
+      <ows20:AllowedValues>
+        <ows20:Value>csw:AnyText</ows20:Value>
+        <ows20:Value>dc:contributor</ows20:Value>
+        <ows20:Value>dc:creator</ows20:Value>
+        <ows20:Value>dc:date</ows20:Value>
+        <ows20:Value>dc:format</ows20:Value>
+        <ows20:Value>dc:identifier</ows20:Value>
+        <ows20:Value>dc:language</ows20:Value>
+        <ows20:Value>dc:publisher</ows20:Value>
+        <ows20:Value>dc:relation</ows20:Value>
+        <ows20:Value>dc:rights</ows20:Value>
+        <ows20:Value>dc:source</ows20:Value>
+        <ows20:Value>dc:subject</ows20:Value>
+        <ows20:Value>dc:title</ows20:Value>
+        <ows20:Value>dc:type</ows20:Value>
+        <ows20:Value>dct:abstract</ows20:Value>
+        <ows20:Value>dct:modified</ows20:Value>
+        <ows20:Value>ows:BoundingBox</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="FederatedCatalogues">
+      <ows20:AllowedValues>
+        <ows20:Value>http://demo.pycsw.org/gisdata/csw</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="MaxRecordDefault">
+      <ows20:AllowedValues>
+        <ows20:Value>10</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="PostEncoding">
+      <ows20:AllowedValues>
+        <ows20:Value>SOAP</ows20:Value>
+        <ows20:Value>XML</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="XPathQueryables">
+      <ows20:AllowedValues>
+        <ows20:Value>allowed</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/CoreQueryables">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/CoreSortables">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/DefaultSortingAlgorithm">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Filter-CQL">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Filter-FES-KVP-Advanced">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Filter-FES-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetCapabilities-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetDomain-KVP">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetDomain-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetRecordById-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetRecords-Async-KVP">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetRecords-Async-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetRecords-Basic-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetRecords-Distributed-KVP">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetRecords-Distributed-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Harvest-Async-KVP">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Harvest-Async-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Harvest-Basic-KVP">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Harvest-Basic-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Harvest-Periodic-KVP">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Harvest-Periodic-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/OpenSearch">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/SupportedGMLVersions">
+      <ows20:AllowedValues>
+        <ows20:Value>http://www.opengis.net/gml</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Transaction">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+  </ows20:OperationsMetadata>
+  <ows20:Languages>
+    <ows20:Language>en</ows20:Language>
+  </ows20:Languages>
+  <fes20:Filter_Capabilities>
+    <fes20:Conformance>
+      <fes20:Constraint name="ImplementsQuery">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsAdHocQuery">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsFunctions">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsResourceld">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsMinStandardFilter">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsStandardFilter">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsMinSpatialFilter">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsSpatialFilter">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsMinTemporalFilter">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsTemporalFilter">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsVersionNav">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsSorting">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsExtendedOperators">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsMinimumXPath">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsSchemaElementFunc">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+    </fes20:Conformance>
+    <fes20:Id_Capabilities>
+      <fes20:ResourceIdentifier name="csw30:id"/>
+    </fes20:Id_Capabilities>
+    <fes20:Scalar_Capabilities>
+      <fes20:LogicalOperators/>
+      <fes20:ComparisonOperators>
+        <fes20:ComparisonOperator name="PropertyIsBetween"/>
+        <fes20:ComparisonOperator name="PropertyIsEqualTo"/>
+        <fes20:ComparisonOperator name="PropertyIsGreaterThan"/>
+        <fes20:ComparisonOperator name="PropertyIsGreaterThanOrEqualTo"/>
+        <fes20:ComparisonOperator name="PropertyIsLessThan"/>
+        <fes20:ComparisonOperator name="PropertyIsLessThanOrEqualTo"/>
+        <fes20:ComparisonOperator name="PropertyIsLike"/>
+        <fes20:ComparisonOperator name="PropertyIsNotEqualTo"/>
+        <fes20:ComparisonOperator name="PropertyIsNull"/>
+      </fes20:ComparisonOperators>
+    </fes20:Scalar_Capabilities>
+    <fes20:Spatial_Capabilities>
+      <fes20:GeometryOperands>
+        <fes20:GeometryOperand name="gml:Point"/>
+        <fes20:GeometryOperand name="gml:LineString"/>
+        <fes20:GeometryOperand name="gml:Polygon"/>
+        <fes20:GeometryOperand name="gml:Envelope"/>
+      </fes20:GeometryOperands>
+      <fes20:SpatialOperators>
+        <fes20:SpatialOperator name="BBOX"/>
+        <fes20:SpatialOperator name="Beyond"/>
+        <fes20:SpatialOperator name="Contains"/>
+        <fes20:SpatialOperator name="Crosses"/>
+        <fes20:SpatialOperator name="Disjoint"/>
+        <fes20:SpatialOperator name="DWithin"/>
+        <fes20:SpatialOperator name="Equals"/>
+        <fes20:SpatialOperator name="Intersects"/>
+        <fes20:SpatialOperator name="Overlaps"/>
+        <fes20:SpatialOperator name="Touches"/>
+        <fes20:SpatialOperator name="Within"/>
+      </fes20:SpatialOperators>
+    </fes20:Spatial_Capabilities>
+    <fes20:Functions>
+      <fes20:Function name="length">
+        <fes20:Returns>xs:string</fes20:Returns>
+      </fes20:Function>
+      <fes20:Function name="lower">
+        <fes20:Returns>xs:string</fes20:Returns>
+      </fes20:Function>
+      <fes20:Function name="ltrim">
+        <fes20:Returns>xs:string</fes20:Returns>
+      </fes20:Function>
+      <fes20:Function name="rtrim">
+        <fes20:Returns>xs:string</fes20:Returns>
+      </fes20:Function>
+      <fes20:Function name="trim">
+        <fes20:Returns>xs:string</fes20:Returns>
+      </fes20:Function>
+      <fes20:Function name="upper">
+        <fes20:Returns>xs:string</fes20:Returns>
+      </fes20:Function>
+    </fes20:Functions>
+  </fes20:Filter_Capabilities>
+</csw30:Capabilities>
diff --git a/tests/expected/suites_csw30_get_7630d230-e142-4a09-accf-f091000b90cd.xml b/tests/expected/suites_csw30_get_7630d230-e142-4a09-accf-f091000b90cd.xml
new file mode 100644
index 0000000..9a891dc
--- /dev/null
+++ b/tests/expected/suites_csw30_get_7630d230-e142-4a09-accf-f091000b90cd.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- PYCSW_VERSION -->
+<csw30:SummaryRecord xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:csw30="http://www.opengis.net/cat/csw/3.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema">
+  <dc:identifier>urn:uuid:66ae76b7-54ba-489b-a582-0f0633d96493</dc:identifier>
+  <dc:title>Maecenas enim</dc:title>
+  <dc:type>http://purl.org/dc/dcmitype/Text</dc:type>
+  <dc:subject>Marine sediments</dc:subject>
+  <dc:format>application/xhtml+xml</dc:format>
+  <dct:abstract>Pellentesque tempus magna non sapien fringilla blandit.</dct:abstract>
+</csw30:SummaryRecord>
diff --git a/tests/expected/suites_csw30_get_7e82446a-b5dc-43fe-9a73-4cc1f2f2f0bf.xml b/tests/expected/suites_csw30_get_7e82446a-b5dc-43fe-9a73-4cc1f2f2f0bf.xml
new file mode 100644
index 0000000..ce9c935
--- /dev/null
+++ b/tests/expected/suites_csw30_get_7e82446a-b5dc-43fe-9a73-4cc1f2f2f0bf.xml
@@ -0,0 +1,491 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- PYCSW_VERSION -->
+<csw30:Capabilities xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:csw30="http://www.opengis.net/cat/csw/3.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:fes20="http://www.opengis.net/fes/2.0" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:ows11="http://www.opengis.net/ows/1.1" xmlns:ows20="http://www.opengis.net/ows/2.0" xmlns:xlink="http://www.w3.org/199 [...]
+  <ows20:ServiceIdentification>
+    <ows20:Title>pycsw Geospatial Catalogue</ows20:Title>
+    <ows20:Abstract>pycsw is an OGC CSW server implementation written in Python</ows20:Abstract>
+    <ows20:Keywords>
+      <ows20:Keyword>catalogue</ows20:Keyword>
+      <ows20:Keyword>discovery</ows20:Keyword>
+      <ows20:Type codeSpace="ISOTC211/19115">theme</ows20:Type>
+    </ows20:Keywords>
+    <ows20:ServiceType codeSpace="OGC">CSW</ows20:ServiceType>
+    <ows20:ServiceTypeVersion>2.0.2</ows20:ServiceTypeVersion>
+    <ows20:ServiceTypeVersion>3.0.0</ows20:ServiceTypeVersion>
+    <ows20:Fees>None</ows20:Fees>
+    <ows20:AccessConstraints>None</ows20:AccessConstraints>
+  </ows20:ServiceIdentification>
+  <ows20:ServiceProvider>
+    <ows20:ProviderName>pycsw</ows20:ProviderName>
+    <ows20:ProviderSite xlink:type="simple" xlink:href="http://pycsw.org/"/>
+    <ows20:ServiceContact>
+      <ows20:IndividualName>Kralidis, Tom</ows20:IndividualName>
+      <ows20:PositionName>Senior Systems Scientist</ows20:PositionName>
+      <ows20:ContactInfo>
+        <ows20:Phone>
+          <ows20:Voice>+01-416-xxx-xxxx</ows20:Voice>
+          <ows20:Facsimile>+01-416-xxx-xxxx</ows20:Facsimile>
+        </ows20:Phone>
+        <ows20:Address>
+          <ows20:DeliveryPoint>TBA</ows20:DeliveryPoint>
+          <ows20:City>Toronto</ows20:City>
+          <ows20:AdministrativeArea>Ontario</ows20:AdministrativeArea>
+          <ows20:PostalCode>M9C 3Z9</ows20:PostalCode>
+          <ows20:Country>Canada</ows20:Country>
+          <ows20:ElectronicMailAddress>tomkralidis at gmail.com</ows20:ElectronicMailAddress>
+        </ows20:Address>
+        <ows20:OnlineResource xlink:type="simple" xlink:href="http://kralidis.ca/"/>
+        <ows20:HoursOfService>0800h - 1600h EST</ows20:HoursOfService>
+        <ows20:ContactInstructions>During hours of service.  Off on weekends.</ows20:ContactInstructions>
+      </ows20:ContactInfo>
+      <ows20:Role codeSpace="ISOTC211/19115">pointOfContact</ows20:Role>
+    </ows20:ServiceContact>
+  </ows20:ServiceProvider>
+  <ows20:OperationsMetadata>
+    <ows20:Operation name="GetCapabilities">
+      <ows20:DCP>
+        <ows20:HTTP>
+          <ows20:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg"/>
+          <ows20:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg"/>
+        </ows20:HTTP>
+      </ows20:DCP>
+      <ows20:Parameter name="acceptFormats">
+        <ows20:AllowedValues>
+          <ows20:Value>application/xml</ows20:Value>
+          <ows20:Value>text/xml</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Parameter name="acceptVersions">
+        <ows20:AllowedValues>
+          <ows20:Value>2.0.2</ows20:Value>
+          <ows20:Value>3.0.0</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Parameter name="sections">
+        <ows20:AllowedValues>
+          <ows20:Value>All</ows20:Value>
+          <ows20:Value>Filter_Capabilities</ows20:Value>
+          <ows20:Value>OperationsMetadata</ows20:Value>
+          <ows20:Value>ServiceIdentification</ows20:Value>
+          <ows20:Value>ServiceProvider</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+    </ows20:Operation>
+    <ows20:Operation name="GetDomain">
+      <ows20:DCP>
+        <ows20:HTTP>
+          <ows20:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg"/>
+          <ows20:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg"/>
+        </ows20:HTTP>
+      </ows20:DCP>
+      <ows20:Parameter name="ParameterName">
+        <ows20:AllowedValues>
+          <ows20:Value>GetCapabilities.acceptFormats</ows20:Value>
+          <ows20:Value>GetCapabilities.acceptVersions</ows20:Value>
+          <ows20:Value>GetCapabilities.sections</ows20:Value>
+          <ows20:Value>GetRecordById.ElementSetName</ows20:Value>
+          <ows20:Value>GetRecordById.outputFormat</ows20:Value>
+          <ows20:Value>GetRecordById.outputSchema</ows20:Value>
+          <ows20:Value>GetRecords.CONSTRAINTLANGUAGE</ows20:Value>
+          <ows20:Value>GetRecords.ElementSetName</ows20:Value>
+          <ows20:Value>GetRecords.outputFormat</ows20:Value>
+          <ows20:Value>GetRecords.outputSchema</ows20:Value>
+          <ows20:Value>GetRecords.typeNames</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+    </ows20:Operation>
+    <ows20:Operation name="GetRecords">
+      <ows20:DCP>
+        <ows20:HTTP>
+          <ows20:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg"/>
+          <ows20:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg"/>
+        </ows20:HTTP>
+      </ows20:DCP>
+      <ows20:Parameter name="CONSTRAINTLANGUAGE">
+        <ows20:AllowedValues>
+          <ows20:Value>CQL_TEXT</ows20:Value>
+          <ows20:Value>FILTER</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Parameter name="ElementSetName">
+        <ows20:AllowedValues>
+          <ows20:Value>brief</ows20:Value>
+          <ows20:Value>full</ows20:Value>
+          <ows20:Value>summary</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Parameter name="outputFormat">
+        <ows20:AllowedValues>
+          <ows20:Value>application/atom+xml</ows20:Value>
+          <ows20:Value>application/json</ows20:Value>
+          <ows20:Value>application/xml</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Parameter name="outputSchema">
+        <ows20:AllowedValues>
+          <ows20:Value>http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/</ows20:Value>
+          <ows20:Value>http://www.interlis.ch/INTERLIS2.3</ows20:Value>
+          <ows20:Value>http://www.opengis.net/cat/csw/3.0</ows20:Value>
+          <ows20:Value>http://www.opengis.net/cat/csw/csdgm</ows20:Value>
+          <ows20:Value>http://www.w3.org/2005/Atom</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Parameter name="typeNames">
+        <ows20:AllowedValues>
+          <ows20:Value>csw:Record</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Constraint name="MaxRecordDefault">
+        <ows20:AllowedValues>
+          <ows20:Value>10</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Constraint>
+      <ows20:Constraint name="OpenSearchDescriptionDocument">
+        <ows20:AllowedValues>
+          <ows20:Value>http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg?mode=opensearch&service=CSW&version=3.0.0&request=GetCapabilities</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Constraint>
+      <ows20:Constraint name="FederatedCatalogues">
+        <ows20:AllowedValues>
+          <ows20:Value>http://demo.pycsw.org/gisdata/csw</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Constraint>
+    </ows20:Operation>
+    <ows20:Operation name="GetRecordById">
+      <ows20:DCP>
+        <ows20:HTTP>
+          <ows20:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg"/>
+          <ows20:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg"/>
+        </ows20:HTTP>
+      </ows20:DCP>
+      <ows20:Parameter name="ElementSetName">
+        <ows20:AllowedValues>
+          <ows20:Value>brief</ows20:Value>
+          <ows20:Value>full</ows20:Value>
+          <ows20:Value>summary</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Parameter name="outputFormat">
+        <ows20:AllowedValues>
+          <ows20:Value>application/atom+xml</ows20:Value>
+          <ows20:Value>application/json</ows20:Value>
+          <ows20:Value>application/xml</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Parameter name="outputSchema">
+        <ows20:AllowedValues>
+          <ows20:Value>http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/</ows20:Value>
+          <ows20:Value>http://www.interlis.ch/INTERLIS2.3</ows20:Value>
+          <ows20:Value>http://www.opengis.net/cat/csw/3.0</ows20:Value>
+          <ows20:Value>http://www.opengis.net/cat/csw/csdgm</ows20:Value>
+          <ows20:Value>http://www.w3.org/2005/Atom</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+    </ows20:Operation>
+    <ows20:Operation name="GetRepositoryItem">
+      <ows20:DCP>
+        <ows20:HTTP>
+          <ows20:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg"/>
+        </ows20:HTTP>
+      </ows20:DCP>
+    </ows20:Operation>
+    <ows20:Parameter name="service">
+      <ows20:AllowedValues>
+        <ows20:Value>CSW</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Parameter>
+    <ows20:Parameter name="version">
+      <ows20:AllowedValues>
+        <ows20:Value>2.0.2</ows20:Value>
+        <ows20:Value>3.0.0</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Parameter>
+    <ows20:Constraint name="CoreQueryables">
+      <ows20:AllowedValues>
+        <ows20:Value>csw:AnyText</ows20:Value>
+        <ows20:Value>dc:contributor</ows20:Value>
+        <ows20:Value>dc:creator</ows20:Value>
+        <ows20:Value>dc:date</ows20:Value>
+        <ows20:Value>dc:format</ows20:Value>
+        <ows20:Value>dc:identifier</ows20:Value>
+        <ows20:Value>dc:language</ows20:Value>
+        <ows20:Value>dc:publisher</ows20:Value>
+        <ows20:Value>dc:relation</ows20:Value>
+        <ows20:Value>dc:rights</ows20:Value>
+        <ows20:Value>dc:source</ows20:Value>
+        <ows20:Value>dc:subject</ows20:Value>
+        <ows20:Value>dc:title</ows20:Value>
+        <ows20:Value>dc:type</ows20:Value>
+        <ows20:Value>dct:abstract</ows20:Value>
+        <ows20:Value>dct:modified</ows20:Value>
+        <ows20:Value>ows:BoundingBox</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="FederatedCatalogues">
+      <ows20:AllowedValues>
+        <ows20:Value>http://demo.pycsw.org/gisdata/csw</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="MaxRecordDefault">
+      <ows20:AllowedValues>
+        <ows20:Value>10</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="PostEncoding">
+      <ows20:AllowedValues>
+        <ows20:Value>SOAP</ows20:Value>
+        <ows20:Value>XML</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="XPathQueryables">
+      <ows20:AllowedValues>
+        <ows20:Value>allowed</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/CoreQueryables">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/CoreSortables">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/DefaultSortingAlgorithm">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Filter-CQL">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Filter-FES-KVP-Advanced">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Filter-FES-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetCapabilities-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetDomain-KVP">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetDomain-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetRecordById-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetRecords-Async-KVP">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetRecords-Async-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetRecords-Basic-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetRecords-Distributed-KVP">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetRecords-Distributed-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Harvest-Async-KVP">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Harvest-Async-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Harvest-Basic-KVP">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Harvest-Basic-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Harvest-Periodic-KVP">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Harvest-Periodic-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/OpenSearch">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/SupportedGMLVersions">
+      <ows20:AllowedValues>
+        <ows20:Value>http://www.opengis.net/gml</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Transaction">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+  </ows20:OperationsMetadata>
+  <ows20:Languages>
+    <ows20:Language>en</ows20:Language>
+  </ows20:Languages>
+  <fes20:Filter_Capabilities>
+    <fes20:Conformance>
+      <fes20:Constraint name="ImplementsQuery">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsAdHocQuery">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsFunctions">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsResourceld">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsMinStandardFilter">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsStandardFilter">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsMinSpatialFilter">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsSpatialFilter">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsMinTemporalFilter">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsTemporalFilter">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsVersionNav">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsSorting">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsExtendedOperators">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsMinimumXPath">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsSchemaElementFunc">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+    </fes20:Conformance>
+    <fes20:Id_Capabilities>
+      <fes20:ResourceIdentifier name="csw30:id"/>
+    </fes20:Id_Capabilities>
+    <fes20:Scalar_Capabilities>
+      <fes20:LogicalOperators/>
+      <fes20:ComparisonOperators>
+        <fes20:ComparisonOperator name="PropertyIsBetween"/>
+        <fes20:ComparisonOperator name="PropertyIsEqualTo"/>
+        <fes20:ComparisonOperator name="PropertyIsGreaterThan"/>
+        <fes20:ComparisonOperator name="PropertyIsGreaterThanOrEqualTo"/>
+        <fes20:ComparisonOperator name="PropertyIsLessThan"/>
+        <fes20:ComparisonOperator name="PropertyIsLessThanOrEqualTo"/>
+        <fes20:ComparisonOperator name="PropertyIsLike"/>
+        <fes20:ComparisonOperator name="PropertyIsNotEqualTo"/>
+        <fes20:ComparisonOperator name="PropertyIsNull"/>
+      </fes20:ComparisonOperators>
+    </fes20:Scalar_Capabilities>
+    <fes20:Spatial_Capabilities>
+      <fes20:GeometryOperands>
+        <fes20:GeometryOperand name="gml:Point"/>
+        <fes20:GeometryOperand name="gml:LineString"/>
+        <fes20:GeometryOperand name="gml:Polygon"/>
+        <fes20:GeometryOperand name="gml:Envelope"/>
+      </fes20:GeometryOperands>
+      <fes20:SpatialOperators>
+        <fes20:SpatialOperator name="BBOX"/>
+        <fes20:SpatialOperator name="Beyond"/>
+        <fes20:SpatialOperator name="Contains"/>
+        <fes20:SpatialOperator name="Crosses"/>
+        <fes20:SpatialOperator name="Disjoint"/>
+        <fes20:SpatialOperator name="DWithin"/>
+        <fes20:SpatialOperator name="Equals"/>
+        <fes20:SpatialOperator name="Intersects"/>
+        <fes20:SpatialOperator name="Overlaps"/>
+        <fes20:SpatialOperator name="Touches"/>
+        <fes20:SpatialOperator name="Within"/>
+      </fes20:SpatialOperators>
+    </fes20:Spatial_Capabilities>
+    <fes20:Functions>
+      <fes20:Function name="length">
+        <fes20:Returns>xs:string</fes20:Returns>
+      </fes20:Function>
+      <fes20:Function name="lower">
+        <fes20:Returns>xs:string</fes20:Returns>
+      </fes20:Function>
+      <fes20:Function name="ltrim">
+        <fes20:Returns>xs:string</fes20:Returns>
+      </fes20:Function>
+      <fes20:Function name="rtrim">
+        <fes20:Returns>xs:string</fes20:Returns>
+      </fes20:Function>
+      <fes20:Function name="trim">
+        <fes20:Returns>xs:string</fes20:Returns>
+      </fes20:Function>
+      <fes20:Function name="upper">
+        <fes20:Returns>xs:string</fes20:Returns>
+      </fes20:Function>
+    </fes20:Functions>
+  </fes20:Filter_Capabilities>
+</csw30:Capabilities>
diff --git a/tests/expected/suites_csw30_get_8025978e-1a35-4d70-80c2-e8329e0c7864.xml b/tests/expected/suites_csw30_get_8025978e-1a35-4d70-80c2-e8329e0c7864.xml
new file mode 100644
index 0000000..ce9c935
--- /dev/null
+++ b/tests/expected/suites_csw30_get_8025978e-1a35-4d70-80c2-e8329e0c7864.xml
@@ -0,0 +1,491 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- PYCSW_VERSION -->
+<csw30:Capabilities xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:csw30="http://www.opengis.net/cat/csw/3.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:fes20="http://www.opengis.net/fes/2.0" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:ows11="http://www.opengis.net/ows/1.1" xmlns:ows20="http://www.opengis.net/ows/2.0" xmlns:xlink="http://www.w3.org/199 [...]
+  <ows20:ServiceIdentification>
+    <ows20:Title>pycsw Geospatial Catalogue</ows20:Title>
+    <ows20:Abstract>pycsw is an OGC CSW server implementation written in Python</ows20:Abstract>
+    <ows20:Keywords>
+      <ows20:Keyword>catalogue</ows20:Keyword>
+      <ows20:Keyword>discovery</ows20:Keyword>
+      <ows20:Type codeSpace="ISOTC211/19115">theme</ows20:Type>
+    </ows20:Keywords>
+    <ows20:ServiceType codeSpace="OGC">CSW</ows20:ServiceType>
+    <ows20:ServiceTypeVersion>2.0.2</ows20:ServiceTypeVersion>
+    <ows20:ServiceTypeVersion>3.0.0</ows20:ServiceTypeVersion>
+    <ows20:Fees>None</ows20:Fees>
+    <ows20:AccessConstraints>None</ows20:AccessConstraints>
+  </ows20:ServiceIdentification>
+  <ows20:ServiceProvider>
+    <ows20:ProviderName>pycsw</ows20:ProviderName>
+    <ows20:ProviderSite xlink:type="simple" xlink:href="http://pycsw.org/"/>
+    <ows20:ServiceContact>
+      <ows20:IndividualName>Kralidis, Tom</ows20:IndividualName>
+      <ows20:PositionName>Senior Systems Scientist</ows20:PositionName>
+      <ows20:ContactInfo>
+        <ows20:Phone>
+          <ows20:Voice>+01-416-xxx-xxxx</ows20:Voice>
+          <ows20:Facsimile>+01-416-xxx-xxxx</ows20:Facsimile>
+        </ows20:Phone>
+        <ows20:Address>
+          <ows20:DeliveryPoint>TBA</ows20:DeliveryPoint>
+          <ows20:City>Toronto</ows20:City>
+          <ows20:AdministrativeArea>Ontario</ows20:AdministrativeArea>
+          <ows20:PostalCode>M9C 3Z9</ows20:PostalCode>
+          <ows20:Country>Canada</ows20:Country>
+          <ows20:ElectronicMailAddress>tomkralidis at gmail.com</ows20:ElectronicMailAddress>
+        </ows20:Address>
+        <ows20:OnlineResource xlink:type="simple" xlink:href="http://kralidis.ca/"/>
+        <ows20:HoursOfService>0800h - 1600h EST</ows20:HoursOfService>
+        <ows20:ContactInstructions>During hours of service.  Off on weekends.</ows20:ContactInstructions>
+      </ows20:ContactInfo>
+      <ows20:Role codeSpace="ISOTC211/19115">pointOfContact</ows20:Role>
+    </ows20:ServiceContact>
+  </ows20:ServiceProvider>
+  <ows20:OperationsMetadata>
+    <ows20:Operation name="GetCapabilities">
+      <ows20:DCP>
+        <ows20:HTTP>
+          <ows20:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg"/>
+          <ows20:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg"/>
+        </ows20:HTTP>
+      </ows20:DCP>
+      <ows20:Parameter name="acceptFormats">
+        <ows20:AllowedValues>
+          <ows20:Value>application/xml</ows20:Value>
+          <ows20:Value>text/xml</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Parameter name="acceptVersions">
+        <ows20:AllowedValues>
+          <ows20:Value>2.0.2</ows20:Value>
+          <ows20:Value>3.0.0</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Parameter name="sections">
+        <ows20:AllowedValues>
+          <ows20:Value>All</ows20:Value>
+          <ows20:Value>Filter_Capabilities</ows20:Value>
+          <ows20:Value>OperationsMetadata</ows20:Value>
+          <ows20:Value>ServiceIdentification</ows20:Value>
+          <ows20:Value>ServiceProvider</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+    </ows20:Operation>
+    <ows20:Operation name="GetDomain">
+      <ows20:DCP>
+        <ows20:HTTP>
+          <ows20:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg"/>
+          <ows20:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg"/>
+        </ows20:HTTP>
+      </ows20:DCP>
+      <ows20:Parameter name="ParameterName">
+        <ows20:AllowedValues>
+          <ows20:Value>GetCapabilities.acceptFormats</ows20:Value>
+          <ows20:Value>GetCapabilities.acceptVersions</ows20:Value>
+          <ows20:Value>GetCapabilities.sections</ows20:Value>
+          <ows20:Value>GetRecordById.ElementSetName</ows20:Value>
+          <ows20:Value>GetRecordById.outputFormat</ows20:Value>
+          <ows20:Value>GetRecordById.outputSchema</ows20:Value>
+          <ows20:Value>GetRecords.CONSTRAINTLANGUAGE</ows20:Value>
+          <ows20:Value>GetRecords.ElementSetName</ows20:Value>
+          <ows20:Value>GetRecords.outputFormat</ows20:Value>
+          <ows20:Value>GetRecords.outputSchema</ows20:Value>
+          <ows20:Value>GetRecords.typeNames</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+    </ows20:Operation>
+    <ows20:Operation name="GetRecords">
+      <ows20:DCP>
+        <ows20:HTTP>
+          <ows20:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg"/>
+          <ows20:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg"/>
+        </ows20:HTTP>
+      </ows20:DCP>
+      <ows20:Parameter name="CONSTRAINTLANGUAGE">
+        <ows20:AllowedValues>
+          <ows20:Value>CQL_TEXT</ows20:Value>
+          <ows20:Value>FILTER</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Parameter name="ElementSetName">
+        <ows20:AllowedValues>
+          <ows20:Value>brief</ows20:Value>
+          <ows20:Value>full</ows20:Value>
+          <ows20:Value>summary</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Parameter name="outputFormat">
+        <ows20:AllowedValues>
+          <ows20:Value>application/atom+xml</ows20:Value>
+          <ows20:Value>application/json</ows20:Value>
+          <ows20:Value>application/xml</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Parameter name="outputSchema">
+        <ows20:AllowedValues>
+          <ows20:Value>http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/</ows20:Value>
+          <ows20:Value>http://www.interlis.ch/INTERLIS2.3</ows20:Value>
+          <ows20:Value>http://www.opengis.net/cat/csw/3.0</ows20:Value>
+          <ows20:Value>http://www.opengis.net/cat/csw/csdgm</ows20:Value>
+          <ows20:Value>http://www.w3.org/2005/Atom</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Parameter name="typeNames">
+        <ows20:AllowedValues>
+          <ows20:Value>csw:Record</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Constraint name="MaxRecordDefault">
+        <ows20:AllowedValues>
+          <ows20:Value>10</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Constraint>
+      <ows20:Constraint name="OpenSearchDescriptionDocument">
+        <ows20:AllowedValues>
+          <ows20:Value>http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg?mode=opensearch&service=CSW&version=3.0.0&request=GetCapabilities</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Constraint>
+      <ows20:Constraint name="FederatedCatalogues">
+        <ows20:AllowedValues>
+          <ows20:Value>http://demo.pycsw.org/gisdata/csw</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Constraint>
+    </ows20:Operation>
+    <ows20:Operation name="GetRecordById">
+      <ows20:DCP>
+        <ows20:HTTP>
+          <ows20:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg"/>
+          <ows20:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg"/>
+        </ows20:HTTP>
+      </ows20:DCP>
+      <ows20:Parameter name="ElementSetName">
+        <ows20:AllowedValues>
+          <ows20:Value>brief</ows20:Value>
+          <ows20:Value>full</ows20:Value>
+          <ows20:Value>summary</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Parameter name="outputFormat">
+        <ows20:AllowedValues>
+          <ows20:Value>application/atom+xml</ows20:Value>
+          <ows20:Value>application/json</ows20:Value>
+          <ows20:Value>application/xml</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Parameter name="outputSchema">
+        <ows20:AllowedValues>
+          <ows20:Value>http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/</ows20:Value>
+          <ows20:Value>http://www.interlis.ch/INTERLIS2.3</ows20:Value>
+          <ows20:Value>http://www.opengis.net/cat/csw/3.0</ows20:Value>
+          <ows20:Value>http://www.opengis.net/cat/csw/csdgm</ows20:Value>
+          <ows20:Value>http://www.w3.org/2005/Atom</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+    </ows20:Operation>
+    <ows20:Operation name="GetRepositoryItem">
+      <ows20:DCP>
+        <ows20:HTTP>
+          <ows20:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg"/>
+        </ows20:HTTP>
+      </ows20:DCP>
+    </ows20:Operation>
+    <ows20:Parameter name="service">
+      <ows20:AllowedValues>
+        <ows20:Value>CSW</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Parameter>
+    <ows20:Parameter name="version">
+      <ows20:AllowedValues>
+        <ows20:Value>2.0.2</ows20:Value>
+        <ows20:Value>3.0.0</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Parameter>
+    <ows20:Constraint name="CoreQueryables">
+      <ows20:AllowedValues>
+        <ows20:Value>csw:AnyText</ows20:Value>
+        <ows20:Value>dc:contributor</ows20:Value>
+        <ows20:Value>dc:creator</ows20:Value>
+        <ows20:Value>dc:date</ows20:Value>
+        <ows20:Value>dc:format</ows20:Value>
+        <ows20:Value>dc:identifier</ows20:Value>
+        <ows20:Value>dc:language</ows20:Value>
+        <ows20:Value>dc:publisher</ows20:Value>
+        <ows20:Value>dc:relation</ows20:Value>
+        <ows20:Value>dc:rights</ows20:Value>
+        <ows20:Value>dc:source</ows20:Value>
+        <ows20:Value>dc:subject</ows20:Value>
+        <ows20:Value>dc:title</ows20:Value>
+        <ows20:Value>dc:type</ows20:Value>
+        <ows20:Value>dct:abstract</ows20:Value>
+        <ows20:Value>dct:modified</ows20:Value>
+        <ows20:Value>ows:BoundingBox</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="FederatedCatalogues">
+      <ows20:AllowedValues>
+        <ows20:Value>http://demo.pycsw.org/gisdata/csw</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="MaxRecordDefault">
+      <ows20:AllowedValues>
+        <ows20:Value>10</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="PostEncoding">
+      <ows20:AllowedValues>
+        <ows20:Value>SOAP</ows20:Value>
+        <ows20:Value>XML</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="XPathQueryables">
+      <ows20:AllowedValues>
+        <ows20:Value>allowed</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/CoreQueryables">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/CoreSortables">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/DefaultSortingAlgorithm">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Filter-CQL">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Filter-FES-KVP-Advanced">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Filter-FES-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetCapabilities-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetDomain-KVP">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetDomain-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetRecordById-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetRecords-Async-KVP">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetRecords-Async-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetRecords-Basic-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetRecords-Distributed-KVP">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetRecords-Distributed-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Harvest-Async-KVP">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Harvest-Async-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Harvest-Basic-KVP">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Harvest-Basic-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Harvest-Periodic-KVP">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Harvest-Periodic-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/OpenSearch">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/SupportedGMLVersions">
+      <ows20:AllowedValues>
+        <ows20:Value>http://www.opengis.net/gml</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Transaction">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+  </ows20:OperationsMetadata>
+  <ows20:Languages>
+    <ows20:Language>en</ows20:Language>
+  </ows20:Languages>
+  <fes20:Filter_Capabilities>
+    <fes20:Conformance>
+      <fes20:Constraint name="ImplementsQuery">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsAdHocQuery">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsFunctions">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsResourceld">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsMinStandardFilter">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsStandardFilter">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsMinSpatialFilter">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsSpatialFilter">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsMinTemporalFilter">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsTemporalFilter">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsVersionNav">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsSorting">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsExtendedOperators">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsMinimumXPath">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsSchemaElementFunc">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+    </fes20:Conformance>
+    <fes20:Id_Capabilities>
+      <fes20:ResourceIdentifier name="csw30:id"/>
+    </fes20:Id_Capabilities>
+    <fes20:Scalar_Capabilities>
+      <fes20:LogicalOperators/>
+      <fes20:ComparisonOperators>
+        <fes20:ComparisonOperator name="PropertyIsBetween"/>
+        <fes20:ComparisonOperator name="PropertyIsEqualTo"/>
+        <fes20:ComparisonOperator name="PropertyIsGreaterThan"/>
+        <fes20:ComparisonOperator name="PropertyIsGreaterThanOrEqualTo"/>
+        <fes20:ComparisonOperator name="PropertyIsLessThan"/>
+        <fes20:ComparisonOperator name="PropertyIsLessThanOrEqualTo"/>
+        <fes20:ComparisonOperator name="PropertyIsLike"/>
+        <fes20:ComparisonOperator name="PropertyIsNotEqualTo"/>
+        <fes20:ComparisonOperator name="PropertyIsNull"/>
+      </fes20:ComparisonOperators>
+    </fes20:Scalar_Capabilities>
+    <fes20:Spatial_Capabilities>
+      <fes20:GeometryOperands>
+        <fes20:GeometryOperand name="gml:Point"/>
+        <fes20:GeometryOperand name="gml:LineString"/>
+        <fes20:GeometryOperand name="gml:Polygon"/>
+        <fes20:GeometryOperand name="gml:Envelope"/>
+      </fes20:GeometryOperands>
+      <fes20:SpatialOperators>
+        <fes20:SpatialOperator name="BBOX"/>
+        <fes20:SpatialOperator name="Beyond"/>
+        <fes20:SpatialOperator name="Contains"/>
+        <fes20:SpatialOperator name="Crosses"/>
+        <fes20:SpatialOperator name="Disjoint"/>
+        <fes20:SpatialOperator name="DWithin"/>
+        <fes20:SpatialOperator name="Equals"/>
+        <fes20:SpatialOperator name="Intersects"/>
+        <fes20:SpatialOperator name="Overlaps"/>
+        <fes20:SpatialOperator name="Touches"/>
+        <fes20:SpatialOperator name="Within"/>
+      </fes20:SpatialOperators>
+    </fes20:Spatial_Capabilities>
+    <fes20:Functions>
+      <fes20:Function name="length">
+        <fes20:Returns>xs:string</fes20:Returns>
+      </fes20:Function>
+      <fes20:Function name="lower">
+        <fes20:Returns>xs:string</fes20:Returns>
+      </fes20:Function>
+      <fes20:Function name="ltrim">
+        <fes20:Returns>xs:string</fes20:Returns>
+      </fes20:Function>
+      <fes20:Function name="rtrim">
+        <fes20:Returns>xs:string</fes20:Returns>
+      </fes20:Function>
+      <fes20:Function name="trim">
+        <fes20:Returns>xs:string</fes20:Returns>
+      </fes20:Function>
+      <fes20:Function name="upper">
+        <fes20:Returns>xs:string</fes20:Returns>
+      </fes20:Function>
+    </fes20:Functions>
+  </fes20:Filter_Capabilities>
+</csw30:Capabilities>
diff --git a/tests/expected/suites_csw30_get_8184ae4f-536d-4978-8b28-ad703be96967.xml b/tests/expected/suites_csw30_get_8184ae4f-536d-4978-8b28-ad703be96967.xml
new file mode 100644
index 0000000..0965e05
--- /dev/null
+++ b/tests/expected/suites_csw30_get_8184ae4f-536d-4978-8b28-ad703be96967.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- PYCSW_VERSION -->
+<csw30:GetRecordsResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:csw30="http://www.opengis.net/cat/csw/3.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:ows20="http://www.opengis.net/ows/2.0" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="3.0.0" xsi: [...]
+  <csw30:SearchStatus timestamp="PYCSW_TIMESTAMP"/>
+  <csw30:SearchResults expires="PYCSW_EXPIRES" nextRecord="0" numberOfRecordsMatched="3" numberOfRecordsReturned="3" recordSchema="http://www.opengis.net/cat/csw/3.0" status="subset" elementSet="brief" elapsedTime="PYCSW_ELAPSED_TIME">
+    <csw30:BriefRecord>
+      <dc:identifier>urn:uuid:1ef30a8b-876d-4828-9246-c37ab4510bbd</dc:identifier>
+      <dc:title></dc:title>
+      <dc:type>http://purl.org/dc/dcmitype/Service</dc:type>
+      <ows20:BoundingBox crs="http://www.opengis.net/def/crs/EPSG/0/4326" dimensions="2">
+        <ows20:LowerCorner>60.04 13.75</ows20:LowerCorner>
+        <ows20:UpperCorner>68.41 17.92</ows20:UpperCorner>
+      </ows20:BoundingBox>
+    </csw30:BriefRecord>
+    <csw30:BriefRecord>
+      <dc:identifier>urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63</dc:identifier>
+      <dc:title>Mauris sed neque</dc:title>
+      <dc:type>http://purl.org/dc/dcmitype/Dataset</dc:type>
+      <ows20:BoundingBox crs="http://www.opengis.net/def/crs/EPSG/0/4326" dimensions="2">
+        <ows20:LowerCorner>47.59 -4.1</ows20:LowerCorner>
+        <ows20:UpperCorner>51.22 0.89</ows20:UpperCorner>
+      </ows20:BoundingBox>
+    </csw30:BriefRecord>
+    <csw30:BriefRecord>
+      <dc:identifier>urn:uuid:9a669547-b69b-469f-a11f-2d875366bbdc</dc:identifier>
+      <dc:title>Ñunç elementum</dc:title>
+      <dc:type>http://purl.org/dc/dcmitype/Dataset</dc:type>
+      <ows20:BoundingBox crs="http://www.opengis.net/def/crs/EPSG/0/4326" dimensions="2">
+        <ows20:LowerCorner>44.79 -6.17</ows20:LowerCorner>
+        <ows20:UpperCorner>51.13 -2.23</ows20:UpperCorner>
+      </ows20:BoundingBox>
+    </csw30:BriefRecord>
+  </csw30:SearchResults>
+</csw30:GetRecordsResponse>
diff --git a/tests/expected/suites_csw30_get_88f63a89-664f-4315-b4f8-04a0b33803a7.xml b/tests/expected/suites_csw30_get_88f63a89-664f-4315-b4f8-04a0b33803a7.xml
new file mode 100644
index 0000000..63e2151
--- /dev/null
+++ b/tests/expected/suites_csw30_get_88f63a89-664f-4315-b4f8-04a0b33803a7.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- PYCSW_VERSION -->
+<csw30:GetRecordsResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:csw30="http://www.opengis.net/cat/csw/3.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:ows20="http://www.opengis.net/ows/2.0" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="3.0.0" xsi: [...]
+  <csw30:SearchStatus timestamp="PYCSW_TIMESTAMP"/>
+  <csw30:SearchResults expires="PYCSW_EXPIRES" nextRecord="0" numberOfRecordsMatched="1" numberOfRecordsReturned="1" recordSchema="http://www.opengis.net/cat/csw/3.0" status="subset" elementSet="summary" elapsedTime="PYCSW_ELAPSED_TIME">
+    <csw30:SummaryRecord>
+      <dc:identifier>urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63</dc:identifier>
+      <dc:title>Mauris sed neque</dc:title>
+      <dc:type>http://purl.org/dc/dcmitype/Dataset</dc:type>
+      <dc:subject>Vegetation-Cropland</dc:subject>
+      <dct:abstract>Curabitur lacinia, ante non porta tempus, mi lorem feugiat odio, eget suscipit eros pede ac velit.</dct:abstract>
+      <ows20:BoundingBox crs="http://www.opengis.net/def/crs/EPSG/0/4326" dimensions="2">
+        <ows20:LowerCorner>47.59 -4.1</ows20:LowerCorner>
+        <ows20:UpperCorner>51.22 0.89</ows20:UpperCorner>
+      </ows20:BoundingBox>
+    </csw30:SummaryRecord>
+  </csw30:SearchResults>
+</csw30:GetRecordsResponse>
diff --git a/tests/expected/suites_csw30_get_8987f8f0-4d93-4481-968c-a2ccbd6b8be2.xml b/tests/expected/suites_csw30_get_8987f8f0-4d93-4481-968c-a2ccbd6b8be2.xml
new file mode 100644
index 0000000..d40a39a
--- /dev/null
+++ b/tests/expected/suites_csw30_get_8987f8f0-4d93-4481-968c-a2ccbd6b8be2.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- PYCSW_VERSION -->
+<ows20:ExceptionReport xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:ows20="http://www.opengis.net/ows/2.0" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="3.0.0" xml:lang="en-US" xsi:schemaLocation="http://www.opengis. [...]
+  <ows20:Exception exceptionCode="NotFound" locator="id">
+    <ows20:ExceptionText>No repository item found for 'urn:example:1461546298217'</ows20:ExceptionText>
+  </ows20:Exception>
+</ows20:ExceptionReport>
diff --git a/tests/expected/suites_csw30_get_8e5fa0f6-3f29-4d1f-abe2-d9866f3def98.xml b/tests/expected/suites_csw30_get_8e5fa0f6-3f29-4d1f-abe2-d9866f3def98.xml
new file mode 100644
index 0000000..6a8e4b0
--- /dev/null
+++ b/tests/expected/suites_csw30_get_8e5fa0f6-3f29-4d1f-abe2-d9866f3def98.xml
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- PYCSW_VERSION -->
+<atom:feed xmlns:atom="http://www.w3.org/2005/Atom" xmlns:os="http://a9.com/-/spec/opensearch/1.1/">
+  <atom:id>http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg</atom:id>
+  <atom:title>pycsw Geospatial Catalogue</atom:title>
+  <atom:author>
+    <atom:name>pycsw</atom:name>
+  </atom:author>
+  <atom:link href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg&mode=opensearch&service=CSW&version=3.0.0&request=GetCapabilities" rel="search" type="application/opensearchdescription+xml"/>
+  <atom:updated>PYCSW_TIMESTAMP</atom:updated>
+  <os:Query role="request"/>
+  <os:totalResults>3</os:totalResults>
+  <os:startIndex>1</os:startIndex>
+  <os:itemsPerPage>3</os:itemsPerPage>
+  <atom:entry xmlns:georss="http://www.georss.org/georss" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:gml="http://www.opengis.net/gml" xsi:schemaLocation="http://www.w3.org/2005/Atom http://www.kbcafe.com/rss/atom.xsd.xml">
+    <atom:id>urn:uuid:1ef30a8b-876d-4828-9246-c37ab4510bbd</atom:id>
+    <dc:identifier>urn:uuid:1ef30a8b-876d-4828-9246-c37ab4510bbd</dc:identifier>
+    <atom:link href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg?service=CSW&version=2.0.2&request=GetRepositoryItem&id=urn:uuid:1ef30a8b-876d-4828-9246-c37ab4510bbd"/>
+    <atom:title/>
+    <atom:updated>PYCSW_TIMESTAMP</atom:updated>
+    <atom:summary>Proin sit amet justo. In justo. Aenean adipiscing nulla id tellus.</atom:summary>
+    <georss:where>
+      <gml:Envelope srsName="http://www.opengis.net/def/crs/EPSG/0/4326">
+        <gml:lowerCorner>60.04 13.75</gml:lowerCorner>
+        <gml:upperCorner>68.41 17.92</gml:upperCorner>
+      </gml:Envelope>
+    </georss:where>
+  </atom:entry>
+  <atom:entry xmlns:georss="http://www.georss.org/georss" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:gml="http://www.opengis.net/gml" xsi:schemaLocation="http://www.w3.org/2005/Atom http://www.kbcafe.com/rss/atom.xsd.xml">
+    <atom:category term="Vegetation-Cropland"/>
+    <atom:id>urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63</atom:id>
+    <dc:identifier>urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63</dc:identifier>
+    <atom:link href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg?service=CSW&version=2.0.2&request=GetRepositoryItem&id=urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63"/>
+    <atom:title>Mauris sed neque</atom:title>
+    <atom:updated>PYCSW_TIMESTAMP</atom:updated>
+    <atom:summary>Curabitur lacinia, ante non porta tempus, mi lorem feugiat odio, eget suscipit eros pede ac velit.</atom:summary>
+    <georss:where>
+      <gml:Envelope srsName="http://www.opengis.net/def/crs/EPSG/0/4326">
+        <gml:lowerCorner>47.59 -4.1</gml:lowerCorner>
+        <gml:upperCorner>51.22 0.89</gml:upperCorner>
+      </gml:Envelope>
+    </georss:where>
+  </atom:entry>
+  <atom:entry xmlns:georss="http://www.georss.org/georss" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:gml="http://www.opengis.net/gml" xsi:schemaLocation="http://www.w3.org/2005/Atom http://www.kbcafe.com/rss/atom.xsd.xml">
+    <atom:category term="Hydrography-Oceanographic"/>
+    <atom:id>urn:uuid:9a669547-b69b-469f-a11f-2d875366bbdc</atom:id>
+    <dc:identifier>urn:uuid:9a669547-b69b-469f-a11f-2d875366bbdc</dc:identifier>
+    <atom:link href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg?service=CSW&version=2.0.2&request=GetRepositoryItem&id=urn:uuid:9a669547-b69b-469f-a11f-2d875366bbdc"/>
+    <atom:title>Ñunç elementum</atom:title>
+    <atom:updated>PYCSW_TIMESTAMP</atom:updated>
+    <georss:where>
+      <gml:Envelope srsName="http://www.opengis.net/def/crs/EPSG/0/4326">
+        <gml:lowerCorner>44.79 -6.17</gml:lowerCorner>
+        <gml:upperCorner>51.13 -2.23</gml:upperCorner>
+      </gml:Envelope>
+    </georss:where>
+  </atom:entry>
+</atom:feed>
diff --git a/tests/expected/suites_csw30_get_9000ec29-5649-474e-b2d6-55c00f8a52c0.xml b/tests/expected/suites_csw30_get_9000ec29-5649-474e-b2d6-55c00f8a52c0.xml
new file mode 100644
index 0000000..3e5a418
--- /dev/null
+++ b/tests/expected/suites_csw30_get_9000ec29-5649-474e-b2d6-55c00f8a52c0.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- PYCSW_VERSION -->
+<ows20:ExceptionReport xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:ows20="http://www.opengis.net/ows/2.0" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="3.0.0" xml:lang="en-US" xsi:schemaLocation="http://www.opengis. [...]
+  <ows20:Exception exceptionCode="VersionNegotiationFailed" locator="acceptversions">
+    <ows20:ExceptionText>Invalid parameter value in acceptversions: 9999.12.31. Value MUST be 2.0.2 or 3.0.0</ows20:ExceptionText>
+  </ows20:Exception>
+</ows20:ExceptionReport>
diff --git a/tests/expected/suites_csw30_get_91914d35-7bbf-45e6-9b37-5ef484869a4e.xml b/tests/expected/suites_csw30_get_91914d35-7bbf-45e6-9b37-5ef484869a4e.xml
new file mode 100644
index 0000000..ef58aa9
--- /dev/null
+++ b/tests/expected/suites_csw30_get_91914d35-7bbf-45e6-9b37-5ef484869a4e.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- PYCSW_VERSION -->
+<csw30:GetRecordsResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:csw30="http://www.opengis.net/cat/csw/3.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:ows20="http://www.opengis.net/ows/2.0" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="3.0.0" xsi: [...]
+  <csw30:SearchStatus timestamp="PYCSW_TIMESTAMP"/>
+  <csw30:SearchResults expires="PYCSW_EXPIRES" nextRecord="0" numberOfRecordsMatched="3" numberOfRecordsReturned="3" recordSchema="http://www.opengis.net/cat/csw/3.0" status="subset" elementSet="summary" elapsedTime="PYCSW_ELAPSED_TIME">
+    <csw30:SummaryRecord>
+      <dc:identifier>urn:uuid:1ef30a8b-876d-4828-9246-c37ab4510bbd</dc:identifier>
+      <dc:title></dc:title>
+      <dc:type>http://purl.org/dc/dcmitype/Service</dc:type>
+      <dct:abstract>Proin sit amet justo. In justo. Aenean adipiscing nulla id tellus.</dct:abstract>
+      <ows20:BoundingBox crs="http://www.opengis.net/def/crs/EPSG/0/4326" dimensions="2">
+        <ows20:LowerCorner>60.04 13.75</ows20:LowerCorner>
+        <ows20:UpperCorner>68.41 17.92</ows20:UpperCorner>
+      </ows20:BoundingBox>
+    </csw30:SummaryRecord>
+    <csw30:SummaryRecord>
+      <dc:identifier>urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63</dc:identifier>
+      <dc:title>Mauris sed neque</dc:title>
+      <dc:type>http://purl.org/dc/dcmitype/Dataset</dc:type>
+      <dc:subject>Vegetation-Cropland</dc:subject>
+      <dct:abstract>Curabitur lacinia, ante non porta tempus, mi lorem feugiat odio, eget suscipit eros pede ac velit.</dct:abstract>
+      <ows20:BoundingBox crs="http://www.opengis.net/def/crs/EPSG/0/4326" dimensions="2">
+        <ows20:LowerCorner>47.59 -4.1</ows20:LowerCorner>
+        <ows20:UpperCorner>51.22 0.89</ows20:UpperCorner>
+      </ows20:BoundingBox>
+    </csw30:SummaryRecord>
+    <csw30:SummaryRecord>
+      <dc:identifier>urn:uuid:9a669547-b69b-469f-a11f-2d875366bbdc</dc:identifier>
+      <dc:title>Ñunç elementum</dc:title>
+      <dc:type>http://purl.org/dc/dcmitype/Dataset</dc:type>
+      <dc:subject>Hydrography-Oceanographic</dc:subject>
+      <ows20:BoundingBox crs="http://www.opengis.net/def/crs/EPSG/0/4326" dimensions="2">
+        <ows20:LowerCorner>44.79 -6.17</ows20:LowerCorner>
+        <ows20:UpperCorner>51.13 -2.23</ows20:UpperCorner>
+      </ows20:BoundingBox>
+    </csw30:SummaryRecord>
+  </csw30:SearchResults>
+</csw30:GetRecordsResponse>
diff --git a/tests/expected/suites_csw30_get_92d4844d-57d5-4cf3-8f47-ba50e369dc04.xml b/tests/expected/suites_csw30_get_92d4844d-57d5-4cf3-8f47-ba50e369dc04.xml
new file mode 100644
index 0000000..d91c31b
--- /dev/null
+++ b/tests/expected/suites_csw30_get_92d4844d-57d5-4cf3-8f47-ba50e369dc04.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- PYCSW_VERSION -->
+<csw30:GetRecordsResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:csw30="http://www.opengis.net/cat/csw/3.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="3.0.0" xsi:schemaLocation="http://www.opengis.net/cat/cs [...]
+  <csw30:SearchStatus timestamp="PYCSW_TIMESTAMP"/>
+  <csw30:SearchResults expires="PYCSW_EXPIRES" nextRecord="0" numberOfRecordsMatched="0" numberOfRecordsReturned="0" recordSchema="http://www.opengis.net/cat/csw/3.0" status="subset" elementSet="full" elapsedTime="PYCSW_ELAPSED_TIME"/>
+</csw30:GetRecordsResponse>
diff --git a/tests/expected/suites_csw30_get_9c0e2a4b-b4e6-41c0-b630-c8c99fc89ff3.xml b/tests/expected/suites_csw30_get_9c0e2a4b-b4e6-41c0-b630-c8c99fc89ff3.xml
new file mode 100644
index 0000000..e015942
--- /dev/null
+++ b/tests/expected/suites_csw30_get_9c0e2a4b-b4e6-41c0-b630-c8c99fc89ff3.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- PYCSW_VERSION -->
+<ows20:ExceptionReport xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:ows20="http://www.opengis.net/ows/2.0" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="3.0.0" xml:lang="en-US" xsi:schemaLocation="http://www.opengis. [...]
+  <ows20:Exception exceptionCode="InvalidParameterValue" locator="outputschema">
+    <ows20:ExceptionText>Invalid outputSchema parameter value: urn:uuid:6a29d2a8-9651-47a6-9b14-f05d2b5644f0</ows20:ExceptionText>
+  </ows20:Exception>
+</ows20:ExceptionReport>
diff --git a/tests/expected/suites_csw30_get_9d7ffac8-9798-428d-8e27-3cd12497ee6b.xml b/tests/expected/suites_csw30_get_9d7ffac8-9798-428d-8e27-3cd12497ee6b.xml
new file mode 100644
index 0000000..e576137
--- /dev/null
+++ b/tests/expected/suites_csw30_get_9d7ffac8-9798-428d-8e27-3cd12497ee6b.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- PYCSW_VERSION -->
+<ows20:ExceptionReport xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:ows20="http://www.opengis.net/ows/2.0" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="3.0.0" xml:lang="en-US" xsi:schemaLocation="http://www.opengis. [...]
+  <ows20:Exception exceptionCode="InvalidParameterValue" locator="outputschema">
+    <ows20:ExceptionText>Invalid outputschema parameter http://www.example.org/ns/alpha</ows20:ExceptionText>
+  </ows20:Exception>
+</ows20:ExceptionReport>
diff --git a/tests/expected/suites_csw30_get_Exception-GetDomain-value-reference.xml b/tests/expected/suites_csw30_get_Exception-GetDomain-value-reference.xml
new file mode 100644
index 0000000..3c1621b
--- /dev/null
+++ b/tests/expected/suites_csw30_get_Exception-GetDomain-value-reference.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- PYCSW_VERSION -->
+<csw30:GetDomainResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:csw30="http://www.opengis.net/cat/csw/3.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/cat/csw/3.0 http://sche [...]
+  <csw30:DomainValues resultType="available" type="csw30:Record">
+    <csw30:ValueReference>dc:title2</csw30:ValueReference>
+  </csw30:DomainValues>
+</csw30:GetDomainResponse>
diff --git a/tests/expected/suites_csw30_get_Exception-GetDomain.xml b/tests/expected/suites_csw30_get_Exception-GetDomain.xml
new file mode 100644
index 0000000..ead6823
--- /dev/null
+++ b/tests/expected/suites_csw30_get_Exception-GetDomain.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- PYCSW_VERSION -->
+<ows20:ExceptionReport xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:ows20="http://www.opengis.net/ows/2.0" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="3.0.0" xml:lang="en-US" xsi:schemaLocation="http://www.opengis. [...]
+  <ows20:Exception exceptionCode="MissingParameterValue" locator="parametername">
+    <ows20:ExceptionText>Missing value.             One of valuereference or parametername must be specified</ows20:ExceptionText>
+  </ows20:Exception>
+</ows20:ExceptionReport>
diff --git a/tests/expected/suites_csw30_get_Exception-GetRecordById-404.xml b/tests/expected/suites_csw30_get_Exception-GetRecordById-404.xml
new file mode 100644
index 0000000..bd41e1d
--- /dev/null
+++ b/tests/expected/suites_csw30_get_Exception-GetRecordById-404.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- PYCSW_VERSION -->
+<ows20:ExceptionReport xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:ows20="http://www.opengis.net/ows/2.0" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="3.0.0" xml:lang="en-US" xsi:schemaLocation="http://www.opengis. [...]
+  <ows20:Exception exceptionCode="NotFound" locator="id">
+    <ows20:ExceptionText>No repository item found for 'does_not_exist2'</ows20:ExceptionText>
+  </ows20:Exception>
+</ows20:ExceptionReport>
diff --git a/tests/expected/suites_csw30_get_Exception-GetRecordById-dc.xml.xml b/tests/expected/suites_csw30_get_Exception-GetRecordById-dc.xml.xml
new file mode 100644
index 0000000..536321c
--- /dev/null
+++ b/tests/expected/suites_csw30_get_Exception-GetRecordById-dc.xml.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- PYCSW_VERSION -->
+<csw30:SummaryRecord xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:csw30="http://www.opengis.net/cat/csw/3.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema">
+  <dc:identifier>urn:uuid:829babb0-b2f1-49e1-8cd5-7b489fe71a1e</dc:identifier>
+  <dc:title>Vestibulum massa purus</dc:title>
+  <dc:type>http://purl.org/dc/dcmitype/Image</dc:type>
+  <dc:format>image/jp2</dc:format>
+  <dc:relation>urn:uuid:9a669547-b69b-469f-a11f-2d875366bbdc</dc:relation>
+</csw30:SummaryRecord>
diff --git a/tests/expected/suites_csw30_get_Exception-GetRepositoryItem-notfound.xml b/tests/expected/suites_csw30_get_Exception-GetRepositoryItem-notfound.xml
new file mode 100644
index 0000000..04c7e9c
--- /dev/null
+++ b/tests/expected/suites_csw30_get_Exception-GetRepositoryItem-notfound.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- PYCSW_VERSION -->
+<ows20:ExceptionReport xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:ows20="http://www.opengis.net/ows/2.0" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="3.0.0" xml:lang="en-US" xsi:schemaLocation="http://www.opengis. [...]
+  <ows20:Exception exceptionCode="NotFound" locator="id">
+    <ows20:ExceptionText>No repository item found for 'NOTFOUND'</ows20:ExceptionText>
+  </ows20:Exception>
+</ows20:ExceptionReport>
diff --git a/tests/expected/suites_csw30_get_Exception-invalid-request.xml b/tests/expected/suites_csw30_get_Exception-invalid-request.xml
new file mode 100644
index 0000000..4cd3418
--- /dev/null
+++ b/tests/expected/suites_csw30_get_Exception-invalid-request.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- PYCSW_VERSION -->
+<ows20:ExceptionReport xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:ows20="http://www.opengis.net/ows/2.0" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="3.0.0" xml:lang="en-US" xsi:schemaLocation="http://www.opengis. [...]
+  <ows20:Exception exceptionCode="InvalidParameterValue" locator="request">
+    <ows20:ExceptionText>Invalid value for request: GetCapabilities-foo</ows20:ExceptionText>
+  </ows20:Exception>
+</ows20:ExceptionReport>
diff --git a/tests/expected/suites_csw30_get_GetCapabilities-base-url.xml b/tests/expected/suites_csw30_get_GetCapabilities-base-url.xml
new file mode 100644
index 0000000..ce9c935
--- /dev/null
+++ b/tests/expected/suites_csw30_get_GetCapabilities-base-url.xml
@@ -0,0 +1,491 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- PYCSW_VERSION -->
+<csw30:Capabilities xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:csw30="http://www.opengis.net/cat/csw/3.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:fes20="http://www.opengis.net/fes/2.0" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:ows11="http://www.opengis.net/ows/1.1" xmlns:ows20="http://www.opengis.net/ows/2.0" xmlns:xlink="http://www.w3.org/199 [...]
+  <ows20:ServiceIdentification>
+    <ows20:Title>pycsw Geospatial Catalogue</ows20:Title>
+    <ows20:Abstract>pycsw is an OGC CSW server implementation written in Python</ows20:Abstract>
+    <ows20:Keywords>
+      <ows20:Keyword>catalogue</ows20:Keyword>
+      <ows20:Keyword>discovery</ows20:Keyword>
+      <ows20:Type codeSpace="ISOTC211/19115">theme</ows20:Type>
+    </ows20:Keywords>
+    <ows20:ServiceType codeSpace="OGC">CSW</ows20:ServiceType>
+    <ows20:ServiceTypeVersion>2.0.2</ows20:ServiceTypeVersion>
+    <ows20:ServiceTypeVersion>3.0.0</ows20:ServiceTypeVersion>
+    <ows20:Fees>None</ows20:Fees>
+    <ows20:AccessConstraints>None</ows20:AccessConstraints>
+  </ows20:ServiceIdentification>
+  <ows20:ServiceProvider>
+    <ows20:ProviderName>pycsw</ows20:ProviderName>
+    <ows20:ProviderSite xlink:type="simple" xlink:href="http://pycsw.org/"/>
+    <ows20:ServiceContact>
+      <ows20:IndividualName>Kralidis, Tom</ows20:IndividualName>
+      <ows20:PositionName>Senior Systems Scientist</ows20:PositionName>
+      <ows20:ContactInfo>
+        <ows20:Phone>
+          <ows20:Voice>+01-416-xxx-xxxx</ows20:Voice>
+          <ows20:Facsimile>+01-416-xxx-xxxx</ows20:Facsimile>
+        </ows20:Phone>
+        <ows20:Address>
+          <ows20:DeliveryPoint>TBA</ows20:DeliveryPoint>
+          <ows20:City>Toronto</ows20:City>
+          <ows20:AdministrativeArea>Ontario</ows20:AdministrativeArea>
+          <ows20:PostalCode>M9C 3Z9</ows20:PostalCode>
+          <ows20:Country>Canada</ows20:Country>
+          <ows20:ElectronicMailAddress>tomkralidis at gmail.com</ows20:ElectronicMailAddress>
+        </ows20:Address>
+        <ows20:OnlineResource xlink:type="simple" xlink:href="http://kralidis.ca/"/>
+        <ows20:HoursOfService>0800h - 1600h EST</ows20:HoursOfService>
+        <ows20:ContactInstructions>During hours of service.  Off on weekends.</ows20:ContactInstructions>
+      </ows20:ContactInfo>
+      <ows20:Role codeSpace="ISOTC211/19115">pointOfContact</ows20:Role>
+    </ows20:ServiceContact>
+  </ows20:ServiceProvider>
+  <ows20:OperationsMetadata>
+    <ows20:Operation name="GetCapabilities">
+      <ows20:DCP>
+        <ows20:HTTP>
+          <ows20:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg"/>
+          <ows20:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg"/>
+        </ows20:HTTP>
+      </ows20:DCP>
+      <ows20:Parameter name="acceptFormats">
+        <ows20:AllowedValues>
+          <ows20:Value>application/xml</ows20:Value>
+          <ows20:Value>text/xml</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Parameter name="acceptVersions">
+        <ows20:AllowedValues>
+          <ows20:Value>2.0.2</ows20:Value>
+          <ows20:Value>3.0.0</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Parameter name="sections">
+        <ows20:AllowedValues>
+          <ows20:Value>All</ows20:Value>
+          <ows20:Value>Filter_Capabilities</ows20:Value>
+          <ows20:Value>OperationsMetadata</ows20:Value>
+          <ows20:Value>ServiceIdentification</ows20:Value>
+          <ows20:Value>ServiceProvider</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+    </ows20:Operation>
+    <ows20:Operation name="GetDomain">
+      <ows20:DCP>
+        <ows20:HTTP>
+          <ows20:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg"/>
+          <ows20:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg"/>
+        </ows20:HTTP>
+      </ows20:DCP>
+      <ows20:Parameter name="ParameterName">
+        <ows20:AllowedValues>
+          <ows20:Value>GetCapabilities.acceptFormats</ows20:Value>
+          <ows20:Value>GetCapabilities.acceptVersions</ows20:Value>
+          <ows20:Value>GetCapabilities.sections</ows20:Value>
+          <ows20:Value>GetRecordById.ElementSetName</ows20:Value>
+          <ows20:Value>GetRecordById.outputFormat</ows20:Value>
+          <ows20:Value>GetRecordById.outputSchema</ows20:Value>
+          <ows20:Value>GetRecords.CONSTRAINTLANGUAGE</ows20:Value>
+          <ows20:Value>GetRecords.ElementSetName</ows20:Value>
+          <ows20:Value>GetRecords.outputFormat</ows20:Value>
+          <ows20:Value>GetRecords.outputSchema</ows20:Value>
+          <ows20:Value>GetRecords.typeNames</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+    </ows20:Operation>
+    <ows20:Operation name="GetRecords">
+      <ows20:DCP>
+        <ows20:HTTP>
+          <ows20:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg"/>
+          <ows20:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg"/>
+        </ows20:HTTP>
+      </ows20:DCP>
+      <ows20:Parameter name="CONSTRAINTLANGUAGE">
+        <ows20:AllowedValues>
+          <ows20:Value>CQL_TEXT</ows20:Value>
+          <ows20:Value>FILTER</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Parameter name="ElementSetName">
+        <ows20:AllowedValues>
+          <ows20:Value>brief</ows20:Value>
+          <ows20:Value>full</ows20:Value>
+          <ows20:Value>summary</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Parameter name="outputFormat">
+        <ows20:AllowedValues>
+          <ows20:Value>application/atom+xml</ows20:Value>
+          <ows20:Value>application/json</ows20:Value>
+          <ows20:Value>application/xml</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Parameter name="outputSchema">
+        <ows20:AllowedValues>
+          <ows20:Value>http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/</ows20:Value>
+          <ows20:Value>http://www.interlis.ch/INTERLIS2.3</ows20:Value>
+          <ows20:Value>http://www.opengis.net/cat/csw/3.0</ows20:Value>
+          <ows20:Value>http://www.opengis.net/cat/csw/csdgm</ows20:Value>
+          <ows20:Value>http://www.w3.org/2005/Atom</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Parameter name="typeNames">
+        <ows20:AllowedValues>
+          <ows20:Value>csw:Record</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Constraint name="MaxRecordDefault">
+        <ows20:AllowedValues>
+          <ows20:Value>10</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Constraint>
+      <ows20:Constraint name="OpenSearchDescriptionDocument">
+        <ows20:AllowedValues>
+          <ows20:Value>http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg?mode=opensearch&service=CSW&version=3.0.0&request=GetCapabilities</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Constraint>
+      <ows20:Constraint name="FederatedCatalogues">
+        <ows20:AllowedValues>
+          <ows20:Value>http://demo.pycsw.org/gisdata/csw</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Constraint>
+    </ows20:Operation>
+    <ows20:Operation name="GetRecordById">
+      <ows20:DCP>
+        <ows20:HTTP>
+          <ows20:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg"/>
+          <ows20:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg"/>
+        </ows20:HTTP>
+      </ows20:DCP>
+      <ows20:Parameter name="ElementSetName">
+        <ows20:AllowedValues>
+          <ows20:Value>brief</ows20:Value>
+          <ows20:Value>full</ows20:Value>
+          <ows20:Value>summary</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Parameter name="outputFormat">
+        <ows20:AllowedValues>
+          <ows20:Value>application/atom+xml</ows20:Value>
+          <ows20:Value>application/json</ows20:Value>
+          <ows20:Value>application/xml</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Parameter name="outputSchema">
+        <ows20:AllowedValues>
+          <ows20:Value>http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/</ows20:Value>
+          <ows20:Value>http://www.interlis.ch/INTERLIS2.3</ows20:Value>
+          <ows20:Value>http://www.opengis.net/cat/csw/3.0</ows20:Value>
+          <ows20:Value>http://www.opengis.net/cat/csw/csdgm</ows20:Value>
+          <ows20:Value>http://www.w3.org/2005/Atom</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+    </ows20:Operation>
+    <ows20:Operation name="GetRepositoryItem">
+      <ows20:DCP>
+        <ows20:HTTP>
+          <ows20:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg"/>
+        </ows20:HTTP>
+      </ows20:DCP>
+    </ows20:Operation>
+    <ows20:Parameter name="service">
+      <ows20:AllowedValues>
+        <ows20:Value>CSW</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Parameter>
+    <ows20:Parameter name="version">
+      <ows20:AllowedValues>
+        <ows20:Value>2.0.2</ows20:Value>
+        <ows20:Value>3.0.0</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Parameter>
+    <ows20:Constraint name="CoreQueryables">
+      <ows20:AllowedValues>
+        <ows20:Value>csw:AnyText</ows20:Value>
+        <ows20:Value>dc:contributor</ows20:Value>
+        <ows20:Value>dc:creator</ows20:Value>
+        <ows20:Value>dc:date</ows20:Value>
+        <ows20:Value>dc:format</ows20:Value>
+        <ows20:Value>dc:identifier</ows20:Value>
+        <ows20:Value>dc:language</ows20:Value>
+        <ows20:Value>dc:publisher</ows20:Value>
+        <ows20:Value>dc:relation</ows20:Value>
+        <ows20:Value>dc:rights</ows20:Value>
+        <ows20:Value>dc:source</ows20:Value>
+        <ows20:Value>dc:subject</ows20:Value>
+        <ows20:Value>dc:title</ows20:Value>
+        <ows20:Value>dc:type</ows20:Value>
+        <ows20:Value>dct:abstract</ows20:Value>
+        <ows20:Value>dct:modified</ows20:Value>
+        <ows20:Value>ows:BoundingBox</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="FederatedCatalogues">
+      <ows20:AllowedValues>
+        <ows20:Value>http://demo.pycsw.org/gisdata/csw</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="MaxRecordDefault">
+      <ows20:AllowedValues>
+        <ows20:Value>10</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="PostEncoding">
+      <ows20:AllowedValues>
+        <ows20:Value>SOAP</ows20:Value>
+        <ows20:Value>XML</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="XPathQueryables">
+      <ows20:AllowedValues>
+        <ows20:Value>allowed</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/CoreQueryables">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/CoreSortables">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/DefaultSortingAlgorithm">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Filter-CQL">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Filter-FES-KVP-Advanced">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Filter-FES-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetCapabilities-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetDomain-KVP">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetDomain-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetRecordById-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetRecords-Async-KVP">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetRecords-Async-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetRecords-Basic-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetRecords-Distributed-KVP">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetRecords-Distributed-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Harvest-Async-KVP">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Harvest-Async-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Harvest-Basic-KVP">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Harvest-Basic-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Harvest-Periodic-KVP">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Harvest-Periodic-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/OpenSearch">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/SupportedGMLVersions">
+      <ows20:AllowedValues>
+        <ows20:Value>http://www.opengis.net/gml</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Transaction">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+  </ows20:OperationsMetadata>
+  <ows20:Languages>
+    <ows20:Language>en</ows20:Language>
+  </ows20:Languages>
+  <fes20:Filter_Capabilities>
+    <fes20:Conformance>
+      <fes20:Constraint name="ImplementsQuery">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsAdHocQuery">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsFunctions">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsResourceld">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsMinStandardFilter">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsStandardFilter">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsMinSpatialFilter">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsSpatialFilter">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsMinTemporalFilter">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsTemporalFilter">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsVersionNav">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsSorting">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsExtendedOperators">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsMinimumXPath">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsSchemaElementFunc">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+    </fes20:Conformance>
+    <fes20:Id_Capabilities>
+      <fes20:ResourceIdentifier name="csw30:id"/>
+    </fes20:Id_Capabilities>
+    <fes20:Scalar_Capabilities>
+      <fes20:LogicalOperators/>
+      <fes20:ComparisonOperators>
+        <fes20:ComparisonOperator name="PropertyIsBetween"/>
+        <fes20:ComparisonOperator name="PropertyIsEqualTo"/>
+        <fes20:ComparisonOperator name="PropertyIsGreaterThan"/>
+        <fes20:ComparisonOperator name="PropertyIsGreaterThanOrEqualTo"/>
+        <fes20:ComparisonOperator name="PropertyIsLessThan"/>
+        <fes20:ComparisonOperator name="PropertyIsLessThanOrEqualTo"/>
+        <fes20:ComparisonOperator name="PropertyIsLike"/>
+        <fes20:ComparisonOperator name="PropertyIsNotEqualTo"/>
+        <fes20:ComparisonOperator name="PropertyIsNull"/>
+      </fes20:ComparisonOperators>
+    </fes20:Scalar_Capabilities>
+    <fes20:Spatial_Capabilities>
+      <fes20:GeometryOperands>
+        <fes20:GeometryOperand name="gml:Point"/>
+        <fes20:GeometryOperand name="gml:LineString"/>
+        <fes20:GeometryOperand name="gml:Polygon"/>
+        <fes20:GeometryOperand name="gml:Envelope"/>
+      </fes20:GeometryOperands>
+      <fes20:SpatialOperators>
+        <fes20:SpatialOperator name="BBOX"/>
+        <fes20:SpatialOperator name="Beyond"/>
+        <fes20:SpatialOperator name="Contains"/>
+        <fes20:SpatialOperator name="Crosses"/>
+        <fes20:SpatialOperator name="Disjoint"/>
+        <fes20:SpatialOperator name="DWithin"/>
+        <fes20:SpatialOperator name="Equals"/>
+        <fes20:SpatialOperator name="Intersects"/>
+        <fes20:SpatialOperator name="Overlaps"/>
+        <fes20:SpatialOperator name="Touches"/>
+        <fes20:SpatialOperator name="Within"/>
+      </fes20:SpatialOperators>
+    </fes20:Spatial_Capabilities>
+    <fes20:Functions>
+      <fes20:Function name="length">
+        <fes20:Returns>xs:string</fes20:Returns>
+      </fes20:Function>
+      <fes20:Function name="lower">
+        <fes20:Returns>xs:string</fes20:Returns>
+      </fes20:Function>
+      <fes20:Function name="ltrim">
+        <fes20:Returns>xs:string</fes20:Returns>
+      </fes20:Function>
+      <fes20:Function name="rtrim">
+        <fes20:Returns>xs:string</fes20:Returns>
+      </fes20:Function>
+      <fes20:Function name="trim">
+        <fes20:Returns>xs:string</fes20:Returns>
+      </fes20:Function>
+      <fes20:Function name="upper">
+        <fes20:Returns>xs:string</fes20:Returns>
+      </fes20:Function>
+    </fes20:Functions>
+  </fes20:Filter_Capabilities>
+</csw30:Capabilities>
diff --git a/tests/expected/suites_csw30_get_GetCapabilities-no-version.xml b/tests/expected/suites_csw30_get_GetCapabilities-no-version.xml
new file mode 100644
index 0000000..ce9c935
--- /dev/null
+++ b/tests/expected/suites_csw30_get_GetCapabilities-no-version.xml
@@ -0,0 +1,491 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- PYCSW_VERSION -->
+<csw30:Capabilities xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:csw30="http://www.opengis.net/cat/csw/3.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:fes20="http://www.opengis.net/fes/2.0" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:ows11="http://www.opengis.net/ows/1.1" xmlns:ows20="http://www.opengis.net/ows/2.0" xmlns:xlink="http://www.w3.org/199 [...]
+  <ows20:ServiceIdentification>
+    <ows20:Title>pycsw Geospatial Catalogue</ows20:Title>
+    <ows20:Abstract>pycsw is an OGC CSW server implementation written in Python</ows20:Abstract>
+    <ows20:Keywords>
+      <ows20:Keyword>catalogue</ows20:Keyword>
+      <ows20:Keyword>discovery</ows20:Keyword>
+      <ows20:Type codeSpace="ISOTC211/19115">theme</ows20:Type>
+    </ows20:Keywords>
+    <ows20:ServiceType codeSpace="OGC">CSW</ows20:ServiceType>
+    <ows20:ServiceTypeVersion>2.0.2</ows20:ServiceTypeVersion>
+    <ows20:ServiceTypeVersion>3.0.0</ows20:ServiceTypeVersion>
+    <ows20:Fees>None</ows20:Fees>
+    <ows20:AccessConstraints>None</ows20:AccessConstraints>
+  </ows20:ServiceIdentification>
+  <ows20:ServiceProvider>
+    <ows20:ProviderName>pycsw</ows20:ProviderName>
+    <ows20:ProviderSite xlink:type="simple" xlink:href="http://pycsw.org/"/>
+    <ows20:ServiceContact>
+      <ows20:IndividualName>Kralidis, Tom</ows20:IndividualName>
+      <ows20:PositionName>Senior Systems Scientist</ows20:PositionName>
+      <ows20:ContactInfo>
+        <ows20:Phone>
+          <ows20:Voice>+01-416-xxx-xxxx</ows20:Voice>
+          <ows20:Facsimile>+01-416-xxx-xxxx</ows20:Facsimile>
+        </ows20:Phone>
+        <ows20:Address>
+          <ows20:DeliveryPoint>TBA</ows20:DeliveryPoint>
+          <ows20:City>Toronto</ows20:City>
+          <ows20:AdministrativeArea>Ontario</ows20:AdministrativeArea>
+          <ows20:PostalCode>M9C 3Z9</ows20:PostalCode>
+          <ows20:Country>Canada</ows20:Country>
+          <ows20:ElectronicMailAddress>tomkralidis at gmail.com</ows20:ElectronicMailAddress>
+        </ows20:Address>
+        <ows20:OnlineResource xlink:type="simple" xlink:href="http://kralidis.ca/"/>
+        <ows20:HoursOfService>0800h - 1600h EST</ows20:HoursOfService>
+        <ows20:ContactInstructions>During hours of service.  Off on weekends.</ows20:ContactInstructions>
+      </ows20:ContactInfo>
+      <ows20:Role codeSpace="ISOTC211/19115">pointOfContact</ows20:Role>
+    </ows20:ServiceContact>
+  </ows20:ServiceProvider>
+  <ows20:OperationsMetadata>
+    <ows20:Operation name="GetCapabilities">
+      <ows20:DCP>
+        <ows20:HTTP>
+          <ows20:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg"/>
+          <ows20:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg"/>
+        </ows20:HTTP>
+      </ows20:DCP>
+      <ows20:Parameter name="acceptFormats">
+        <ows20:AllowedValues>
+          <ows20:Value>application/xml</ows20:Value>
+          <ows20:Value>text/xml</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Parameter name="acceptVersions">
+        <ows20:AllowedValues>
+          <ows20:Value>2.0.2</ows20:Value>
+          <ows20:Value>3.0.0</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Parameter name="sections">
+        <ows20:AllowedValues>
+          <ows20:Value>All</ows20:Value>
+          <ows20:Value>Filter_Capabilities</ows20:Value>
+          <ows20:Value>OperationsMetadata</ows20:Value>
+          <ows20:Value>ServiceIdentification</ows20:Value>
+          <ows20:Value>ServiceProvider</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+    </ows20:Operation>
+    <ows20:Operation name="GetDomain">
+      <ows20:DCP>
+        <ows20:HTTP>
+          <ows20:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg"/>
+          <ows20:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg"/>
+        </ows20:HTTP>
+      </ows20:DCP>
+      <ows20:Parameter name="ParameterName">
+        <ows20:AllowedValues>
+          <ows20:Value>GetCapabilities.acceptFormats</ows20:Value>
+          <ows20:Value>GetCapabilities.acceptVersions</ows20:Value>
+          <ows20:Value>GetCapabilities.sections</ows20:Value>
+          <ows20:Value>GetRecordById.ElementSetName</ows20:Value>
+          <ows20:Value>GetRecordById.outputFormat</ows20:Value>
+          <ows20:Value>GetRecordById.outputSchema</ows20:Value>
+          <ows20:Value>GetRecords.CONSTRAINTLANGUAGE</ows20:Value>
+          <ows20:Value>GetRecords.ElementSetName</ows20:Value>
+          <ows20:Value>GetRecords.outputFormat</ows20:Value>
+          <ows20:Value>GetRecords.outputSchema</ows20:Value>
+          <ows20:Value>GetRecords.typeNames</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+    </ows20:Operation>
+    <ows20:Operation name="GetRecords">
+      <ows20:DCP>
+        <ows20:HTTP>
+          <ows20:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg"/>
+          <ows20:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg"/>
+        </ows20:HTTP>
+      </ows20:DCP>
+      <ows20:Parameter name="CONSTRAINTLANGUAGE">
+        <ows20:AllowedValues>
+          <ows20:Value>CQL_TEXT</ows20:Value>
+          <ows20:Value>FILTER</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Parameter name="ElementSetName">
+        <ows20:AllowedValues>
+          <ows20:Value>brief</ows20:Value>
+          <ows20:Value>full</ows20:Value>
+          <ows20:Value>summary</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Parameter name="outputFormat">
+        <ows20:AllowedValues>
+          <ows20:Value>application/atom+xml</ows20:Value>
+          <ows20:Value>application/json</ows20:Value>
+          <ows20:Value>application/xml</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Parameter name="outputSchema">
+        <ows20:AllowedValues>
+          <ows20:Value>http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/</ows20:Value>
+          <ows20:Value>http://www.interlis.ch/INTERLIS2.3</ows20:Value>
+          <ows20:Value>http://www.opengis.net/cat/csw/3.0</ows20:Value>
+          <ows20:Value>http://www.opengis.net/cat/csw/csdgm</ows20:Value>
+          <ows20:Value>http://www.w3.org/2005/Atom</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Parameter name="typeNames">
+        <ows20:AllowedValues>
+          <ows20:Value>csw:Record</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Constraint name="MaxRecordDefault">
+        <ows20:AllowedValues>
+          <ows20:Value>10</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Constraint>
+      <ows20:Constraint name="OpenSearchDescriptionDocument">
+        <ows20:AllowedValues>
+          <ows20:Value>http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg?mode=opensearch&service=CSW&version=3.0.0&request=GetCapabilities</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Constraint>
+      <ows20:Constraint name="FederatedCatalogues">
+        <ows20:AllowedValues>
+          <ows20:Value>http://demo.pycsw.org/gisdata/csw</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Constraint>
+    </ows20:Operation>
+    <ows20:Operation name="GetRecordById">
+      <ows20:DCP>
+        <ows20:HTTP>
+          <ows20:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg"/>
+          <ows20:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg"/>
+        </ows20:HTTP>
+      </ows20:DCP>
+      <ows20:Parameter name="ElementSetName">
+        <ows20:AllowedValues>
+          <ows20:Value>brief</ows20:Value>
+          <ows20:Value>full</ows20:Value>
+          <ows20:Value>summary</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Parameter name="outputFormat">
+        <ows20:AllowedValues>
+          <ows20:Value>application/atom+xml</ows20:Value>
+          <ows20:Value>application/json</ows20:Value>
+          <ows20:Value>application/xml</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Parameter name="outputSchema">
+        <ows20:AllowedValues>
+          <ows20:Value>http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/</ows20:Value>
+          <ows20:Value>http://www.interlis.ch/INTERLIS2.3</ows20:Value>
+          <ows20:Value>http://www.opengis.net/cat/csw/3.0</ows20:Value>
+          <ows20:Value>http://www.opengis.net/cat/csw/csdgm</ows20:Value>
+          <ows20:Value>http://www.w3.org/2005/Atom</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+    </ows20:Operation>
+    <ows20:Operation name="GetRepositoryItem">
+      <ows20:DCP>
+        <ows20:HTTP>
+          <ows20:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg"/>
+        </ows20:HTTP>
+      </ows20:DCP>
+    </ows20:Operation>
+    <ows20:Parameter name="service">
+      <ows20:AllowedValues>
+        <ows20:Value>CSW</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Parameter>
+    <ows20:Parameter name="version">
+      <ows20:AllowedValues>
+        <ows20:Value>2.0.2</ows20:Value>
+        <ows20:Value>3.0.0</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Parameter>
+    <ows20:Constraint name="CoreQueryables">
+      <ows20:AllowedValues>
+        <ows20:Value>csw:AnyText</ows20:Value>
+        <ows20:Value>dc:contributor</ows20:Value>
+        <ows20:Value>dc:creator</ows20:Value>
+        <ows20:Value>dc:date</ows20:Value>
+        <ows20:Value>dc:format</ows20:Value>
+        <ows20:Value>dc:identifier</ows20:Value>
+        <ows20:Value>dc:language</ows20:Value>
+        <ows20:Value>dc:publisher</ows20:Value>
+        <ows20:Value>dc:relation</ows20:Value>
+        <ows20:Value>dc:rights</ows20:Value>
+        <ows20:Value>dc:source</ows20:Value>
+        <ows20:Value>dc:subject</ows20:Value>
+        <ows20:Value>dc:title</ows20:Value>
+        <ows20:Value>dc:type</ows20:Value>
+        <ows20:Value>dct:abstract</ows20:Value>
+        <ows20:Value>dct:modified</ows20:Value>
+        <ows20:Value>ows:BoundingBox</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="FederatedCatalogues">
+      <ows20:AllowedValues>
+        <ows20:Value>http://demo.pycsw.org/gisdata/csw</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="MaxRecordDefault">
+      <ows20:AllowedValues>
+        <ows20:Value>10</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="PostEncoding">
+      <ows20:AllowedValues>
+        <ows20:Value>SOAP</ows20:Value>
+        <ows20:Value>XML</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="XPathQueryables">
+      <ows20:AllowedValues>
+        <ows20:Value>allowed</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/CoreQueryables">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/CoreSortables">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/DefaultSortingAlgorithm">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Filter-CQL">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Filter-FES-KVP-Advanced">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Filter-FES-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetCapabilities-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetDomain-KVP">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetDomain-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetRecordById-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetRecords-Async-KVP">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetRecords-Async-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetRecords-Basic-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetRecords-Distributed-KVP">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetRecords-Distributed-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Harvest-Async-KVP">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Harvest-Async-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Harvest-Basic-KVP">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Harvest-Basic-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Harvest-Periodic-KVP">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Harvest-Periodic-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/OpenSearch">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/SupportedGMLVersions">
+      <ows20:AllowedValues>
+        <ows20:Value>http://www.opengis.net/gml</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Transaction">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+  </ows20:OperationsMetadata>
+  <ows20:Languages>
+    <ows20:Language>en</ows20:Language>
+  </ows20:Languages>
+  <fes20:Filter_Capabilities>
+    <fes20:Conformance>
+      <fes20:Constraint name="ImplementsQuery">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsAdHocQuery">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsFunctions">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsResourceld">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsMinStandardFilter">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsStandardFilter">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsMinSpatialFilter">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsSpatialFilter">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsMinTemporalFilter">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsTemporalFilter">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsVersionNav">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsSorting">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsExtendedOperators">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsMinimumXPath">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsSchemaElementFunc">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+    </fes20:Conformance>
+    <fes20:Id_Capabilities>
+      <fes20:ResourceIdentifier name="csw30:id"/>
+    </fes20:Id_Capabilities>
+    <fes20:Scalar_Capabilities>
+      <fes20:LogicalOperators/>
+      <fes20:ComparisonOperators>
+        <fes20:ComparisonOperator name="PropertyIsBetween"/>
+        <fes20:ComparisonOperator name="PropertyIsEqualTo"/>
+        <fes20:ComparisonOperator name="PropertyIsGreaterThan"/>
+        <fes20:ComparisonOperator name="PropertyIsGreaterThanOrEqualTo"/>
+        <fes20:ComparisonOperator name="PropertyIsLessThan"/>
+        <fes20:ComparisonOperator name="PropertyIsLessThanOrEqualTo"/>
+        <fes20:ComparisonOperator name="PropertyIsLike"/>
+        <fes20:ComparisonOperator name="PropertyIsNotEqualTo"/>
+        <fes20:ComparisonOperator name="PropertyIsNull"/>
+      </fes20:ComparisonOperators>
+    </fes20:Scalar_Capabilities>
+    <fes20:Spatial_Capabilities>
+      <fes20:GeometryOperands>
+        <fes20:GeometryOperand name="gml:Point"/>
+        <fes20:GeometryOperand name="gml:LineString"/>
+        <fes20:GeometryOperand name="gml:Polygon"/>
+        <fes20:GeometryOperand name="gml:Envelope"/>
+      </fes20:GeometryOperands>
+      <fes20:SpatialOperators>
+        <fes20:SpatialOperator name="BBOX"/>
+        <fes20:SpatialOperator name="Beyond"/>
+        <fes20:SpatialOperator name="Contains"/>
+        <fes20:SpatialOperator name="Crosses"/>
+        <fes20:SpatialOperator name="Disjoint"/>
+        <fes20:SpatialOperator name="DWithin"/>
+        <fes20:SpatialOperator name="Equals"/>
+        <fes20:SpatialOperator name="Intersects"/>
+        <fes20:SpatialOperator name="Overlaps"/>
+        <fes20:SpatialOperator name="Touches"/>
+        <fes20:SpatialOperator name="Within"/>
+      </fes20:SpatialOperators>
+    </fes20:Spatial_Capabilities>
+    <fes20:Functions>
+      <fes20:Function name="length">
+        <fes20:Returns>xs:string</fes20:Returns>
+      </fes20:Function>
+      <fes20:Function name="lower">
+        <fes20:Returns>xs:string</fes20:Returns>
+      </fes20:Function>
+      <fes20:Function name="ltrim">
+        <fes20:Returns>xs:string</fes20:Returns>
+      </fes20:Function>
+      <fes20:Function name="rtrim">
+        <fes20:Returns>xs:string</fes20:Returns>
+      </fes20:Function>
+      <fes20:Function name="trim">
+        <fes20:Returns>xs:string</fes20:Returns>
+      </fes20:Function>
+      <fes20:Function name="upper">
+        <fes20:Returns>xs:string</fes20:Returns>
+      </fes20:Function>
+    </fes20:Functions>
+  </fes20:Filter_Capabilities>
+</csw30:Capabilities>
diff --git a/tests/expected/suites_csw30_get_GetCapabilities.xml b/tests/expected/suites_csw30_get_GetCapabilities.xml
new file mode 100644
index 0000000..ce9c935
--- /dev/null
+++ b/tests/expected/suites_csw30_get_GetCapabilities.xml
@@ -0,0 +1,491 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- PYCSW_VERSION -->
+<csw30:Capabilities xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:csw30="http://www.opengis.net/cat/csw/3.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:fes20="http://www.opengis.net/fes/2.0" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:ows11="http://www.opengis.net/ows/1.1" xmlns:ows20="http://www.opengis.net/ows/2.0" xmlns:xlink="http://www.w3.org/199 [...]
+  <ows20:ServiceIdentification>
+    <ows20:Title>pycsw Geospatial Catalogue</ows20:Title>
+    <ows20:Abstract>pycsw is an OGC CSW server implementation written in Python</ows20:Abstract>
+    <ows20:Keywords>
+      <ows20:Keyword>catalogue</ows20:Keyword>
+      <ows20:Keyword>discovery</ows20:Keyword>
+      <ows20:Type codeSpace="ISOTC211/19115">theme</ows20:Type>
+    </ows20:Keywords>
+    <ows20:ServiceType codeSpace="OGC">CSW</ows20:ServiceType>
+    <ows20:ServiceTypeVersion>2.0.2</ows20:ServiceTypeVersion>
+    <ows20:ServiceTypeVersion>3.0.0</ows20:ServiceTypeVersion>
+    <ows20:Fees>None</ows20:Fees>
+    <ows20:AccessConstraints>None</ows20:AccessConstraints>
+  </ows20:ServiceIdentification>
+  <ows20:ServiceProvider>
+    <ows20:ProviderName>pycsw</ows20:ProviderName>
+    <ows20:ProviderSite xlink:type="simple" xlink:href="http://pycsw.org/"/>
+    <ows20:ServiceContact>
+      <ows20:IndividualName>Kralidis, Tom</ows20:IndividualName>
+      <ows20:PositionName>Senior Systems Scientist</ows20:PositionName>
+      <ows20:ContactInfo>
+        <ows20:Phone>
+          <ows20:Voice>+01-416-xxx-xxxx</ows20:Voice>
+          <ows20:Facsimile>+01-416-xxx-xxxx</ows20:Facsimile>
+        </ows20:Phone>
+        <ows20:Address>
+          <ows20:DeliveryPoint>TBA</ows20:DeliveryPoint>
+          <ows20:City>Toronto</ows20:City>
+          <ows20:AdministrativeArea>Ontario</ows20:AdministrativeArea>
+          <ows20:PostalCode>M9C 3Z9</ows20:PostalCode>
+          <ows20:Country>Canada</ows20:Country>
+          <ows20:ElectronicMailAddress>tomkralidis at gmail.com</ows20:ElectronicMailAddress>
+        </ows20:Address>
+        <ows20:OnlineResource xlink:type="simple" xlink:href="http://kralidis.ca/"/>
+        <ows20:HoursOfService>0800h - 1600h EST</ows20:HoursOfService>
+        <ows20:ContactInstructions>During hours of service.  Off on weekends.</ows20:ContactInstructions>
+      </ows20:ContactInfo>
+      <ows20:Role codeSpace="ISOTC211/19115">pointOfContact</ows20:Role>
+    </ows20:ServiceContact>
+  </ows20:ServiceProvider>
+  <ows20:OperationsMetadata>
+    <ows20:Operation name="GetCapabilities">
+      <ows20:DCP>
+        <ows20:HTTP>
+          <ows20:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg"/>
+          <ows20:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg"/>
+        </ows20:HTTP>
+      </ows20:DCP>
+      <ows20:Parameter name="acceptFormats">
+        <ows20:AllowedValues>
+          <ows20:Value>application/xml</ows20:Value>
+          <ows20:Value>text/xml</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Parameter name="acceptVersions">
+        <ows20:AllowedValues>
+          <ows20:Value>2.0.2</ows20:Value>
+          <ows20:Value>3.0.0</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Parameter name="sections">
+        <ows20:AllowedValues>
+          <ows20:Value>All</ows20:Value>
+          <ows20:Value>Filter_Capabilities</ows20:Value>
+          <ows20:Value>OperationsMetadata</ows20:Value>
+          <ows20:Value>ServiceIdentification</ows20:Value>
+          <ows20:Value>ServiceProvider</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+    </ows20:Operation>
+    <ows20:Operation name="GetDomain">
+      <ows20:DCP>
+        <ows20:HTTP>
+          <ows20:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg"/>
+          <ows20:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg"/>
+        </ows20:HTTP>
+      </ows20:DCP>
+      <ows20:Parameter name="ParameterName">
+        <ows20:AllowedValues>
+          <ows20:Value>GetCapabilities.acceptFormats</ows20:Value>
+          <ows20:Value>GetCapabilities.acceptVersions</ows20:Value>
+          <ows20:Value>GetCapabilities.sections</ows20:Value>
+          <ows20:Value>GetRecordById.ElementSetName</ows20:Value>
+          <ows20:Value>GetRecordById.outputFormat</ows20:Value>
+          <ows20:Value>GetRecordById.outputSchema</ows20:Value>
+          <ows20:Value>GetRecords.CONSTRAINTLANGUAGE</ows20:Value>
+          <ows20:Value>GetRecords.ElementSetName</ows20:Value>
+          <ows20:Value>GetRecords.outputFormat</ows20:Value>
+          <ows20:Value>GetRecords.outputSchema</ows20:Value>
+          <ows20:Value>GetRecords.typeNames</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+    </ows20:Operation>
+    <ows20:Operation name="GetRecords">
+      <ows20:DCP>
+        <ows20:HTTP>
+          <ows20:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg"/>
+          <ows20:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg"/>
+        </ows20:HTTP>
+      </ows20:DCP>
+      <ows20:Parameter name="CONSTRAINTLANGUAGE">
+        <ows20:AllowedValues>
+          <ows20:Value>CQL_TEXT</ows20:Value>
+          <ows20:Value>FILTER</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Parameter name="ElementSetName">
+        <ows20:AllowedValues>
+          <ows20:Value>brief</ows20:Value>
+          <ows20:Value>full</ows20:Value>
+          <ows20:Value>summary</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Parameter name="outputFormat">
+        <ows20:AllowedValues>
+          <ows20:Value>application/atom+xml</ows20:Value>
+          <ows20:Value>application/json</ows20:Value>
+          <ows20:Value>application/xml</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Parameter name="outputSchema">
+        <ows20:AllowedValues>
+          <ows20:Value>http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/</ows20:Value>
+          <ows20:Value>http://www.interlis.ch/INTERLIS2.3</ows20:Value>
+          <ows20:Value>http://www.opengis.net/cat/csw/3.0</ows20:Value>
+          <ows20:Value>http://www.opengis.net/cat/csw/csdgm</ows20:Value>
+          <ows20:Value>http://www.w3.org/2005/Atom</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Parameter name="typeNames">
+        <ows20:AllowedValues>
+          <ows20:Value>csw:Record</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Constraint name="MaxRecordDefault">
+        <ows20:AllowedValues>
+          <ows20:Value>10</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Constraint>
+      <ows20:Constraint name="OpenSearchDescriptionDocument">
+        <ows20:AllowedValues>
+          <ows20:Value>http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg?mode=opensearch&service=CSW&version=3.0.0&request=GetCapabilities</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Constraint>
+      <ows20:Constraint name="FederatedCatalogues">
+        <ows20:AllowedValues>
+          <ows20:Value>http://demo.pycsw.org/gisdata/csw</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Constraint>
+    </ows20:Operation>
+    <ows20:Operation name="GetRecordById">
+      <ows20:DCP>
+        <ows20:HTTP>
+          <ows20:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg"/>
+          <ows20:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg"/>
+        </ows20:HTTP>
+      </ows20:DCP>
+      <ows20:Parameter name="ElementSetName">
+        <ows20:AllowedValues>
+          <ows20:Value>brief</ows20:Value>
+          <ows20:Value>full</ows20:Value>
+          <ows20:Value>summary</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Parameter name="outputFormat">
+        <ows20:AllowedValues>
+          <ows20:Value>application/atom+xml</ows20:Value>
+          <ows20:Value>application/json</ows20:Value>
+          <ows20:Value>application/xml</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Parameter name="outputSchema">
+        <ows20:AllowedValues>
+          <ows20:Value>http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/</ows20:Value>
+          <ows20:Value>http://www.interlis.ch/INTERLIS2.3</ows20:Value>
+          <ows20:Value>http://www.opengis.net/cat/csw/3.0</ows20:Value>
+          <ows20:Value>http://www.opengis.net/cat/csw/csdgm</ows20:Value>
+          <ows20:Value>http://www.w3.org/2005/Atom</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+    </ows20:Operation>
+    <ows20:Operation name="GetRepositoryItem">
+      <ows20:DCP>
+        <ows20:HTTP>
+          <ows20:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg"/>
+        </ows20:HTTP>
+      </ows20:DCP>
+    </ows20:Operation>
+    <ows20:Parameter name="service">
+      <ows20:AllowedValues>
+        <ows20:Value>CSW</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Parameter>
+    <ows20:Parameter name="version">
+      <ows20:AllowedValues>
+        <ows20:Value>2.0.2</ows20:Value>
+        <ows20:Value>3.0.0</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Parameter>
+    <ows20:Constraint name="CoreQueryables">
+      <ows20:AllowedValues>
+        <ows20:Value>csw:AnyText</ows20:Value>
+        <ows20:Value>dc:contributor</ows20:Value>
+        <ows20:Value>dc:creator</ows20:Value>
+        <ows20:Value>dc:date</ows20:Value>
+        <ows20:Value>dc:format</ows20:Value>
+        <ows20:Value>dc:identifier</ows20:Value>
+        <ows20:Value>dc:language</ows20:Value>
+        <ows20:Value>dc:publisher</ows20:Value>
+        <ows20:Value>dc:relation</ows20:Value>
+        <ows20:Value>dc:rights</ows20:Value>
+        <ows20:Value>dc:source</ows20:Value>
+        <ows20:Value>dc:subject</ows20:Value>
+        <ows20:Value>dc:title</ows20:Value>
+        <ows20:Value>dc:type</ows20:Value>
+        <ows20:Value>dct:abstract</ows20:Value>
+        <ows20:Value>dct:modified</ows20:Value>
+        <ows20:Value>ows:BoundingBox</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="FederatedCatalogues">
+      <ows20:AllowedValues>
+        <ows20:Value>http://demo.pycsw.org/gisdata/csw</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="MaxRecordDefault">
+      <ows20:AllowedValues>
+        <ows20:Value>10</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="PostEncoding">
+      <ows20:AllowedValues>
+        <ows20:Value>SOAP</ows20:Value>
+        <ows20:Value>XML</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="XPathQueryables">
+      <ows20:AllowedValues>
+        <ows20:Value>allowed</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/CoreQueryables">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/CoreSortables">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/DefaultSortingAlgorithm">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Filter-CQL">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Filter-FES-KVP-Advanced">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Filter-FES-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetCapabilities-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetDomain-KVP">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetDomain-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetRecordById-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetRecords-Async-KVP">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetRecords-Async-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetRecords-Basic-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetRecords-Distributed-KVP">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetRecords-Distributed-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Harvest-Async-KVP">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Harvest-Async-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Harvest-Basic-KVP">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Harvest-Basic-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Harvest-Periodic-KVP">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Harvest-Periodic-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/OpenSearch">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/SupportedGMLVersions">
+      <ows20:AllowedValues>
+        <ows20:Value>http://www.opengis.net/gml</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Transaction">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+  </ows20:OperationsMetadata>
+  <ows20:Languages>
+    <ows20:Language>en</ows20:Language>
+  </ows20:Languages>
+  <fes20:Filter_Capabilities>
+    <fes20:Conformance>
+      <fes20:Constraint name="ImplementsQuery">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsAdHocQuery">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsFunctions">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsResourceld">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsMinStandardFilter">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsStandardFilter">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsMinSpatialFilter">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsSpatialFilter">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsMinTemporalFilter">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsTemporalFilter">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsVersionNav">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsSorting">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsExtendedOperators">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsMinimumXPath">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsSchemaElementFunc">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+    </fes20:Conformance>
+    <fes20:Id_Capabilities>
+      <fes20:ResourceIdentifier name="csw30:id"/>
+    </fes20:Id_Capabilities>
+    <fes20:Scalar_Capabilities>
+      <fes20:LogicalOperators/>
+      <fes20:ComparisonOperators>
+        <fes20:ComparisonOperator name="PropertyIsBetween"/>
+        <fes20:ComparisonOperator name="PropertyIsEqualTo"/>
+        <fes20:ComparisonOperator name="PropertyIsGreaterThan"/>
+        <fes20:ComparisonOperator name="PropertyIsGreaterThanOrEqualTo"/>
+        <fes20:ComparisonOperator name="PropertyIsLessThan"/>
+        <fes20:ComparisonOperator name="PropertyIsLessThanOrEqualTo"/>
+        <fes20:ComparisonOperator name="PropertyIsLike"/>
+        <fes20:ComparisonOperator name="PropertyIsNotEqualTo"/>
+        <fes20:ComparisonOperator name="PropertyIsNull"/>
+      </fes20:ComparisonOperators>
+    </fes20:Scalar_Capabilities>
+    <fes20:Spatial_Capabilities>
+      <fes20:GeometryOperands>
+        <fes20:GeometryOperand name="gml:Point"/>
+        <fes20:GeometryOperand name="gml:LineString"/>
+        <fes20:GeometryOperand name="gml:Polygon"/>
+        <fes20:GeometryOperand name="gml:Envelope"/>
+      </fes20:GeometryOperands>
+      <fes20:SpatialOperators>
+        <fes20:SpatialOperator name="BBOX"/>
+        <fes20:SpatialOperator name="Beyond"/>
+        <fes20:SpatialOperator name="Contains"/>
+        <fes20:SpatialOperator name="Crosses"/>
+        <fes20:SpatialOperator name="Disjoint"/>
+        <fes20:SpatialOperator name="DWithin"/>
+        <fes20:SpatialOperator name="Equals"/>
+        <fes20:SpatialOperator name="Intersects"/>
+        <fes20:SpatialOperator name="Overlaps"/>
+        <fes20:SpatialOperator name="Touches"/>
+        <fes20:SpatialOperator name="Within"/>
+      </fes20:SpatialOperators>
+    </fes20:Spatial_Capabilities>
+    <fes20:Functions>
+      <fes20:Function name="length">
+        <fes20:Returns>xs:string</fes20:Returns>
+      </fes20:Function>
+      <fes20:Function name="lower">
+        <fes20:Returns>xs:string</fes20:Returns>
+      </fes20:Function>
+      <fes20:Function name="ltrim">
+        <fes20:Returns>xs:string</fes20:Returns>
+      </fes20:Function>
+      <fes20:Function name="rtrim">
+        <fes20:Returns>xs:string</fes20:Returns>
+      </fes20:Function>
+      <fes20:Function name="trim">
+        <fes20:Returns>xs:string</fes20:Returns>
+      </fes20:Function>
+      <fes20:Function name="upper">
+        <fes20:Returns>xs:string</fes20:Returns>
+      </fes20:Function>
+    </fes20:Functions>
+  </fes20:Filter_Capabilities>
+</csw30:Capabilities>
diff --git a/tests/expected/suites_csw30_get_GetDomain-parameter.xml b/tests/expected/suites_csw30_get_GetDomain-parameter.xml
new file mode 100644
index 0000000..6b8227f
--- /dev/null
+++ b/tests/expected/suites_csw30_get_GetDomain-parameter.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- PYCSW_VERSION -->
+<csw30:GetDomainResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:csw30="http://www.opengis.net/cat/csw/3.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/cat/csw/3.0 http://sche [...]
+  <csw30:DomainValues resultType="available" type="csw30:Record">
+    <csw30:ParameterName>GetRecords.ElementSetName</csw30:ParameterName>
+    <csw30:ListOfValues>
+      <csw30:Value>brief</csw30:Value>
+      <csw30:Value>full</csw30:Value>
+      <csw30:Value>summary</csw30:Value>
+    </csw30:ListOfValues>
+  </csw30:DomainValues>
+</csw30:GetDomainResponse>
diff --git a/tests/expected/suites_csw30_get_GetDomain-value-reference.xml b/tests/expected/suites_csw30_get_GetDomain-value-reference.xml
new file mode 100644
index 0000000..3775ee2
--- /dev/null
+++ b/tests/expected/suites_csw30_get_GetDomain-value-reference.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- PYCSW_VERSION -->
+<csw30:GetDomainResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:csw30="http://www.opengis.net/cat/csw/3.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/cat/csw/3.0 http://sche [...]
+  <csw30:DomainValues resultType="available" type="csw30:Record">
+    <csw30:ValueReference>dc:title</csw30:ValueReference>
+    <csw30:ListOfValues>
+      <csw30:Value count="1">Aliquam fermentum purus quis arcu</csw30:Value>
+      <csw30:Value count="1">Fuscé vitae ligulä</csw30:Value>
+      <csw30:Value count="1">Lorem ipsum</csw30:Value>
+      <csw30:Value count="1">Lorem ipsum dolor sit amet</csw30:Value>
+      <csw30:Value count="1">Maecenas enim</csw30:Value>
+      <csw30:Value count="1">Mauris sed neque</csw30:Value>
+      <csw30:Value count="1">Ut facilisis justo ut lacus</csw30:Value>
+      <csw30:Value count="1">Vestibulum massa purus</csw30:Value>
+      <csw30:Value count="1">Ñunç elementum</csw30:Value>
+    </csw30:ListOfValues>
+  </csw30:DomainValues>
+</csw30:GetDomainResponse>
diff --git a/tests/expected/suites_csw30_get_GetRepositoryItem.xml b/tests/expected/suites_csw30_get_GetRepositoryItem.xml
new file mode 100644
index 0000000..862e439
--- /dev/null
+++ b/tests/expected/suites_csw30_get_GetRepositoryItem.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- PYCSW_VERSION -->
+<csw:Record xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:ows="http://www.opengis.net/ows" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/">
+    <dc:identifier>urn:uuid:19887a8a-f6b0-4a63-ae56-7fba0e17801f</dc:identifier>
+    <dc:type>http://purl.org/dc/dcmitype/Image</dc:type>
+    <dc:format>image/svg+xml</dc:format>
+    <dc:title>Lorem ipsum</dc:title>
+    <dct:spatial>GR-22</dct:spatial>
+    <dc:subject>Tourism--Greece</dc:subject>
+    <dct:abstract>Quisque lacus diam, placerat mollis, pharetra in, commodo sed, augue. Duis iaculis arcu vel arcu.</dct:abstract>
+</csw:Record>
diff --git a/tests/expected/suites_csw30_get_OpenSearch-description.xml b/tests/expected/suites_csw30_get_OpenSearch-description.xml
new file mode 100644
index 0000000..5aac092
--- /dev/null
+++ b/tests/expected/suites_csw30_get_OpenSearch-description.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- PYCSW_VERSION -->
+<os:OpenSearchDescription xmlns:geo="http://a9.com/-/opensearch/extensions/geo/1.0/" xmlns:os="http://a9.com/-/spec/opensearch/1.1/">
+  <os:ShortName>pycsw Geospatial</os:ShortName>
+  <os:LongName>pycsw Geospatial Catalogue</os:LongName>
+  <os:Description>pycsw is an OGC CSW server implementation written in Python</os:Description>
+  <os:Tags>catalogue discovery</os:Tags>
+  <os:Url type="application/xml" template="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg&service=CSW&version=3.0.0&request=GetRecords&elementsetname=full&typenames=csw:Record&resulttype=results&q={searchTerms?}&bbox={geo:box?}&time={time:start?}/{time:end?}&outputformat=application/xml&outputschema=http://www.opengis.net/cat/csw/3.0&startposition={startIndex?}&maxrecords={count?}&recordids={geo:uid}"/>
+  <os:Url type="application/atom+xml" template="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg&mode=opensearch&service=CSW&version=3.0.0&request=GetRecords&elementsetname=full&typenames=csw:Record&resulttype=results&q={searchTerms?}&bbox={geo:box?}&time={time:start?}/{time:end?}&outputformat=application/atom+xml&&startposition={startIndex?}&maxrecords={count?}&recordids={geo:uid}"/>
+  <os:Image type="image/vnd.microsoft.icon" width="16" height="16">http://pycsw.org/img/favicon.ico</os:Image>
+  <os:Query role="example" geo:box="-180,-90,180,90"/>
+  <os:Developer>Kralidis, Tom</os:Developer>
+  <os:Contact>tomkralidis at gmail.com</os:Contact>
+  <os:Attribution>pycsw</os:Attribution>
+</os:OpenSearchDescription>
diff --git a/tests/expected/suites_csw30_get_a2f18643-e24e-4fa5-b780-6de4a2dbc814.xml b/tests/expected/suites_csw30_get_a2f18643-e24e-4fa5-b780-6de4a2dbc814.xml
new file mode 100644
index 0000000..96afaaf
--- /dev/null
+++ b/tests/expected/suites_csw30_get_a2f18643-e24e-4fa5-b780-6de4a2dbc814.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- PYCSW_VERSION -->
+<atom:entry xmlns:atom="http://www.w3.org/2005/Atom" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.w3.org/2005/Atom http://www.kbcafe.com/rss/atom.xsd.xml">
+  <atom:id>urn:uuid:829babb0-b2f1-49e1-8cd5-7b489fe71a1e</atom:id>
+  <dc:identifier xmlns:dc="http://purl.org/dc/elements/1.1/">urn:uuid:829babb0-b2f1-49e1-8cd5-7b489fe71a1e</dc:identifier>
+  <atom:link href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg?service=CSW&version=2.0.2&request=GetRepositoryItem&id=urn:uuid:829babb0-b2f1-49e1-8cd5-7b489fe71a1e"/>
+  <atom:title>Vestibulum massa purus</atom:title>
+  <atom:updated>PYCSW_TIMESTAMP</atom:updated>
+</atom:entry>
diff --git a/tests/expected/suites_csw30_get_abc90c8c-5868-4405-a73e-64c849be3b2a.xml b/tests/expected/suites_csw30_get_abc90c8c-5868-4405-a73e-64c849be3b2a.xml
new file mode 100644
index 0000000..f0c8bac
--- /dev/null
+++ b/tests/expected/suites_csw30_get_abc90c8c-5868-4405-a73e-64c849be3b2a.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- PYCSW_VERSION -->
+<ows20:ExceptionReport xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:ows20="http://www.opengis.net/ows/2.0" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="3.0.0" xml:lang="en-US" xsi:schemaLocation="http://www.opengis. [...]
+  <ows20:Exception exceptionCode="InvalidParameterValue" locator="bbox">
+    <ows20:ExceptionText>4326 coordinates out of range: ['514432', '5429689', '529130', '5451619']</ows20:ExceptionText>
+  </ows20:Exception>
+</ows20:ExceptionReport>
diff --git a/tests/expected/suites_csw30_get_ad0c0571-09ed-436a-9a4f-a5de744c88fe.xml b/tests/expected/suites_csw30_get_ad0c0571-09ed-436a-9a4f-a5de744c88fe.xml
new file mode 100644
index 0000000..fb39b0b
--- /dev/null
+++ b/tests/expected/suites_csw30_get_ad0c0571-09ed-436a-9a4f-a5de744c88fe.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- PYCSW_VERSION -->
+<csw30:GetRecordsResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:csw30="http://www.opengis.net/cat/csw/3.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="3.0.0" xsi:schemaLocation="http://www.opengis.net/cat/cs [...]
+  <csw30:SearchStatus timestamp="PYCSW_TIMESTAMP"/>
+  <csw30:SearchResults expires="PYCSW_EXPIRES" nextRecord="5" numberOfRecordsMatched="12" numberOfRecordsReturned="2" recordSchema="http://www.opengis.net/cat/csw/3.0" status="subset" elementSet="summary" elapsedTime="PYCSW_ELAPSED_TIME">
+    <csw30:SummaryRecord>
+      <dc:identifier>urn:uuid:66ae76b7-54ba-489b-a582-0f0633d96493</dc:identifier>
+      <dc:title>Maecenas enim</dc:title>
+      <dc:type>http://purl.org/dc/dcmitype/Text</dc:type>
+      <dc:subject>Marine sediments</dc:subject>
+      <dc:format>application/xhtml+xml</dc:format>
+      <dct:abstract>Pellentesque tempus magna non sapien fringilla blandit.</dct:abstract>
+    </csw30:SummaryRecord>
+    <csw30:SummaryRecord>
+      <dc:identifier>urn:uuid:6a3de50b-fa66-4b58-a0e6-ca146fdd18d4</dc:identifier>
+      <dc:title>Ut facilisis justo ut lacus</dc:title>
+      <dc:type>http://purl.org/dc/dcmitype/Service</dc:type>
+      <dc:subject>Vegetation</dc:subject>
+      <dc:relation>urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63</dc:relation>
+    </csw30:SummaryRecord>
+  </csw30:SearchResults>
+</csw30:GetRecordsResponse>
diff --git a/tests/expected/suites_csw30_get_af502903-f4ee-47ee-b76e-af878d238bcc.xml b/tests/expected/suites_csw30_get_af502903-f4ee-47ee-b76e-af878d238bcc.xml
new file mode 100644
index 0000000..73b0f78
--- /dev/null
+++ b/tests/expected/suites_csw30_get_af502903-f4ee-47ee-b76e-af878d238bcc.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- PYCSW_VERSION -->
+<csw30:GetRecordsResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:csw30="http://www.opengis.net/cat/csw/3.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:ows20="http://www.opengis.net/ows/2.0" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="3.0.0" xsi: [...]
+  <csw30:SearchStatus timestamp="PYCSW_TIMESTAMP"/>
+  <csw30:SearchResults expires="PYCSW_EXPIRES" nextRecord="0" numberOfRecordsMatched="3" numberOfRecordsReturned="3" recordSchema="http://www.opengis.net/cat/csw/3.0" status="subset" elementSet="full" elapsedTime="PYCSW_ELAPSED_TIME">
+    <csw30:Record>
+      <dc:identifier>urn:uuid:1ef30a8b-876d-4828-9246-c37ab4510bbd</dc:identifier>
+      <dc:title></dc:title>
+      <dc:type>http://purl.org/dc/dcmitype/Service</dc:type>
+      <dct:abstract>Proin sit amet justo. In justo. Aenean adipiscing nulla id tellus.</dct:abstract>
+      <ows20:BoundingBox crs="http://www.opengis.net/def/crs/EPSG/0/4326" dimensions="2">
+        <ows20:LowerCorner>60.04 13.75</ows20:LowerCorner>
+        <ows20:UpperCorner>68.41 17.92</ows20:UpperCorner>
+      </ows20:BoundingBox>
+    </csw30:Record>
+    <csw30:Record>
+      <dc:identifier>urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63</dc:identifier>
+      <dc:title>Mauris sed neque</dc:title>
+      <dc:type>http://purl.org/dc/dcmitype/Dataset</dc:type>
+      <dc:subject>Vegetation-Cropland</dc:subject>
+      <dct:abstract>Curabitur lacinia, ante non porta tempus, mi lorem feugiat odio, eget suscipit eros pede ac velit.</dct:abstract>
+      <dc:date>2006-03-26</dc:date>
+      <ows20:BoundingBox crs="http://www.opengis.net/def/crs/EPSG/0/4326" dimensions="2">
+        <ows20:LowerCorner>47.59 -4.1</ows20:LowerCorner>
+        <ows20:UpperCorner>51.22 0.89</ows20:UpperCorner>
+      </ows20:BoundingBox>
+    </csw30:Record>
+    <csw30:Record>
+      <dc:identifier>urn:uuid:9a669547-b69b-469f-a11f-2d875366bbdc</dc:identifier>
+      <dc:title>Ñunç elementum</dc:title>
+      <dc:type>http://purl.org/dc/dcmitype/Dataset</dc:type>
+      <dc:subject>Hydrography-Oceanographic</dc:subject>
+      <dc:date>2005-10-24</dc:date>
+      <ows20:BoundingBox crs="http://www.opengis.net/def/crs/EPSG/0/4326" dimensions="2">
+        <ows20:LowerCorner>44.79 -6.17</ows20:LowerCorner>
+        <ows20:UpperCorner>51.13 -2.23</ows20:UpperCorner>
+      </ows20:BoundingBox>
+    </csw30:Record>
+  </csw30:SearchResults>
+</csw30:GetRecordsResponse>
diff --git a/tests/expected/suites_csw30_get_b2aafc3f-4f35-47bc-affd-08590972deae.xml b/tests/expected/suites_csw30_get_b2aafc3f-4f35-47bc-affd-08590972deae.xml
new file mode 100644
index 0000000..6a8e4b0
--- /dev/null
+++ b/tests/expected/suites_csw30_get_b2aafc3f-4f35-47bc-affd-08590972deae.xml
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- PYCSW_VERSION -->
+<atom:feed xmlns:atom="http://www.w3.org/2005/Atom" xmlns:os="http://a9.com/-/spec/opensearch/1.1/">
+  <atom:id>http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg</atom:id>
+  <atom:title>pycsw Geospatial Catalogue</atom:title>
+  <atom:author>
+    <atom:name>pycsw</atom:name>
+  </atom:author>
+  <atom:link href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg&mode=opensearch&service=CSW&version=3.0.0&request=GetCapabilities" rel="search" type="application/opensearchdescription+xml"/>
+  <atom:updated>PYCSW_TIMESTAMP</atom:updated>
+  <os:Query role="request"/>
+  <os:totalResults>3</os:totalResults>
+  <os:startIndex>1</os:startIndex>
+  <os:itemsPerPage>3</os:itemsPerPage>
+  <atom:entry xmlns:georss="http://www.georss.org/georss" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:gml="http://www.opengis.net/gml" xsi:schemaLocation="http://www.w3.org/2005/Atom http://www.kbcafe.com/rss/atom.xsd.xml">
+    <atom:id>urn:uuid:1ef30a8b-876d-4828-9246-c37ab4510bbd</atom:id>
+    <dc:identifier>urn:uuid:1ef30a8b-876d-4828-9246-c37ab4510bbd</dc:identifier>
+    <atom:link href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg?service=CSW&version=2.0.2&request=GetRepositoryItem&id=urn:uuid:1ef30a8b-876d-4828-9246-c37ab4510bbd"/>
+    <atom:title/>
+    <atom:updated>PYCSW_TIMESTAMP</atom:updated>
+    <atom:summary>Proin sit amet justo. In justo. Aenean adipiscing nulla id tellus.</atom:summary>
+    <georss:where>
+      <gml:Envelope srsName="http://www.opengis.net/def/crs/EPSG/0/4326">
+        <gml:lowerCorner>60.04 13.75</gml:lowerCorner>
+        <gml:upperCorner>68.41 17.92</gml:upperCorner>
+      </gml:Envelope>
+    </georss:where>
+  </atom:entry>
+  <atom:entry xmlns:georss="http://www.georss.org/georss" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:gml="http://www.opengis.net/gml" xsi:schemaLocation="http://www.w3.org/2005/Atom http://www.kbcafe.com/rss/atom.xsd.xml">
+    <atom:category term="Vegetation-Cropland"/>
+    <atom:id>urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63</atom:id>
+    <dc:identifier>urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63</dc:identifier>
+    <atom:link href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg?service=CSW&version=2.0.2&request=GetRepositoryItem&id=urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63"/>
+    <atom:title>Mauris sed neque</atom:title>
+    <atom:updated>PYCSW_TIMESTAMP</atom:updated>
+    <atom:summary>Curabitur lacinia, ante non porta tempus, mi lorem feugiat odio, eget suscipit eros pede ac velit.</atom:summary>
+    <georss:where>
+      <gml:Envelope srsName="http://www.opengis.net/def/crs/EPSG/0/4326">
+        <gml:lowerCorner>47.59 -4.1</gml:lowerCorner>
+        <gml:upperCorner>51.22 0.89</gml:upperCorner>
+      </gml:Envelope>
+    </georss:where>
+  </atom:entry>
+  <atom:entry xmlns:georss="http://www.georss.org/georss" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:gml="http://www.opengis.net/gml" xsi:schemaLocation="http://www.w3.org/2005/Atom http://www.kbcafe.com/rss/atom.xsd.xml">
+    <atom:category term="Hydrography-Oceanographic"/>
+    <atom:id>urn:uuid:9a669547-b69b-469f-a11f-2d875366bbdc</atom:id>
+    <dc:identifier>urn:uuid:9a669547-b69b-469f-a11f-2d875366bbdc</dc:identifier>
+    <atom:link href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg?service=CSW&version=2.0.2&request=GetRepositoryItem&id=urn:uuid:9a669547-b69b-469f-a11f-2d875366bbdc"/>
+    <atom:title>Ñunç elementum</atom:title>
+    <atom:updated>PYCSW_TIMESTAMP</atom:updated>
+    <georss:where>
+      <gml:Envelope srsName="http://www.opengis.net/def/crs/EPSG/0/4326">
+        <gml:lowerCorner>44.79 -6.17</gml:lowerCorner>
+        <gml:upperCorner>51.13 -2.23</gml:upperCorner>
+      </gml:Envelope>
+    </georss:where>
+  </atom:entry>
+</atom:feed>
diff --git a/tests/expected/suites_csw30_get_b6069623-f7d8-4021-8582-98f0aea0f763.xml b/tests/expected/suites_csw30_get_b6069623-f7d8-4021-8582-98f0aea0f763.xml
new file mode 100644
index 0000000..0ed0b06
--- /dev/null
+++ b/tests/expected/suites_csw30_get_b6069623-f7d8-4021-8582-98f0aea0f763.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- PYCSW_VERSION -->
+<atom:feed xmlns:atom="http://www.w3.org/2005/Atom" xmlns:os="http://a9.com/-/spec/opensearch/1.1/">
+  <atom:id>http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg</atom:id>
+  <atom:title>pycsw Geospatial Catalogue</atom:title>
+  <atom:author>
+    <atom:name>pycsw</atom:name>
+  </atom:author>
+  <atom:link href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg&mode=opensearch&service=CSW&version=3.0.0&request=GetCapabilities" rel="search" type="application/opensearchdescription+xml"/>
+  <atom:updated>PYCSW_TIMESTAMP</atom:updated>
+  <os:Query role="request"/>
+  <os:totalResults>12</os:totalResults>
+  <os:startIndex>3</os:startIndex>
+  <os:itemsPerPage>4</os:itemsPerPage>
+  <atom:entry xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dc="http://purl.org/dc/elements/1.1/" xsi:schemaLocation="http://www.w3.org/2005/Atom http://www.kbcafe.com/rss/atom.xsd.xml">
+    <atom:category term="Marine sediments"/>
+    <atom:id>urn:uuid:66ae76b7-54ba-489b-a582-0f0633d96493</atom:id>
+    <dc:identifier>urn:uuid:66ae76b7-54ba-489b-a582-0f0633d96493</dc:identifier>
+    <atom:link href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg?service=CSW&version=2.0.2&request=GetRepositoryItem&id=urn:uuid:66ae76b7-54ba-489b-a582-0f0633d96493"/>
+    <atom:title>Maecenas enim</atom:title>
+    <atom:updated>PYCSW_TIMESTAMP</atom:updated>
+    <atom:summary>Pellentesque tempus magna non sapien fringilla blandit.</atom:summary>
+  </atom:entry>
+  <atom:entry xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dc="http://purl.org/dc/elements/1.1/" xsi:schemaLocation="http://www.w3.org/2005/Atom http://www.kbcafe.com/rss/atom.xsd.xml">
+    <atom:category term="Vegetation"/>
+    <atom:id>urn:uuid:6a3de50b-fa66-4b58-a0e6-ca146fdd18d4</atom:id>
+    <dc:identifier>urn:uuid:6a3de50b-fa66-4b58-a0e6-ca146fdd18d4</dc:identifier>
+    <atom:link href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg?service=CSW&version=2.0.2&request=GetRepositoryItem&id=urn:uuid:6a3de50b-fa66-4b58-a0e6-ca146fdd18d4"/>
+    <atom:title>Ut facilisis justo ut lacus</atom:title>
+    <atom:updated>PYCSW_TIMESTAMP</atom:updated>
+  </atom:entry>
+  <atom:entry xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dc="http://purl.org/dc/elements/1.1/" xsi:schemaLocation="http://www.w3.org/2005/Atom http://www.kbcafe.com/rss/atom.xsd.xml">
+    <atom:category term="Hydrography--Dictionaries"/>
+    <atom:id>urn:uuid:784e2afd-a9fd-44a6-9a92-a3848371c8ec</atom:id>
+    <dc:identifier>urn:uuid:784e2afd-a9fd-44a6-9a92-a3848371c8ec</dc:identifier>
+    <atom:link href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg?service=CSW&version=2.0.2&request=GetRepositoryItem&id=urn:uuid:784e2afd-a9fd-44a6-9a92-a3848371c8ec"/>
+    <atom:title>Aliquam fermentum purus quis arcu</atom:title>
+    <atom:updated>PYCSW_TIMESTAMP</atom:updated>
+    <atom:summary>Vestibulum quis ipsum sit amet metus imperdiet vehicula. Nulla scelerisque cursus mi.</atom:summary>
+  </atom:entry>
+  <atom:entry xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dc="http://purl.org/dc/elements/1.1/" xsi:schemaLocation="http://www.w3.org/2005/Atom http://www.kbcafe.com/rss/atom.xsd.xml">
+    <atom:id>urn:uuid:829babb0-b2f1-49e1-8cd5-7b489fe71a1e</atom:id>
+    <dc:identifier>urn:uuid:829babb0-b2f1-49e1-8cd5-7b489fe71a1e</dc:identifier>
+    <atom:link href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg?service=CSW&version=2.0.2&request=GetRepositoryItem&id=urn:uuid:829babb0-b2f1-49e1-8cd5-7b489fe71a1e"/>
+    <atom:title>Vestibulum massa purus</atom:title>
+    <atom:updated>PYCSW_TIMESTAMP</atom:updated>
+  </atom:entry>
+</atom:feed>
diff --git a/tests/expected/suites_csw30_get_b9a07a54-75a8-45bd-b341-2823600211e3.xml b/tests/expected/suites_csw30_get_b9a07a54-75a8-45bd-b341-2823600211e3.xml
new file mode 100644
index 0000000..93cf54a
--- /dev/null
+++ b/tests/expected/suites_csw30_get_b9a07a54-75a8-45bd-b341-2823600211e3.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- PYCSW_VERSION -->
+<ows20:ExceptionReport xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:ows20="http://www.opengis.net/ows/2.0" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="3.0.0" xml:lang="en-US" xsi:schemaLocation="http://www.opengis. [...]
+  <ows20:Exception exceptionCode="InvalidParameterValue" locator="bbox">
+    <ows20:ExceptionText>Invalid Filter query: Exception: document not valid.
+Error: Reprojection error: Invalid srsName "urn:ogc:def:crs:EPSG::0000": Invalid source projection.</ows20:ExceptionText>
+  </ows20:Exception>
+</ows20:ExceptionReport>
diff --git a/tests/expected/suites_csw30_get_baa4a7d0-0c01-42b6-adc3-0d03e9949fa3.xml b/tests/expected/suites_csw30_get_baa4a7d0-0c01-42b6-adc3-0d03e9949fa3.xml
new file mode 100644
index 0000000..4953497
--- /dev/null
+++ b/tests/expected/suites_csw30_get_baa4a7d0-0c01-42b6-adc3-0d03e9949fa3.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- PYCSW_VERSION -->
+<ows20:ExceptionReport xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:ows20="http://www.opengis.net/ows/2.0" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="3.0.0" xml:lang="en-US" xsi:schemaLocation="http://www.opengis. [...]
+  <ows20:Exception exceptionCode="InvalidParameterValue" locator="request">
+    <ows20:ExceptionText>Invalid value for request: getCapabilities</ows20:ExceptionText>
+  </ows20:Exception>
+</ows20:ExceptionReport>
diff --git a/tests/expected/suites_csw30_get_bfbe6409-f64a-4c89-acb3-50f260a5c743.xml b/tests/expected/suites_csw30_get_bfbe6409-f64a-4c89-acb3-50f260a5c743.xml
new file mode 100644
index 0000000..c6809c5
--- /dev/null
+++ b/tests/expected/suites_csw30_get_bfbe6409-f64a-4c89-acb3-50f260a5c743.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- PYCSW_VERSION -->
+<csw30:GetRecordsResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:csw30="http://www.opengis.net/cat/csw/3.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="3.0.0" xsi:schemaLocation="http://www.opengis.net/cat/cs [...]
+  <csw30:SearchStatus timestamp="PYCSW_TIMESTAMP"/>
+  <csw30:SearchResults expires="PYCSW_EXPIRES" nextRecord="0" numberOfRecordsMatched="1" numberOfRecordsReturned="1" recordSchema="http://www.opengis.net/cat/csw/3.0" status="subset" elementSet="summary" elapsedTime="PYCSW_ELAPSED_TIME">
+    <csw30:SummaryRecord>
+      <dc:identifier>urn:uuid:e9330592-0932-474b-be34-c3a3bb67c7db</dc:identifier>
+      <dc:title>Fuscé vitae ligulä</dc:title>
+      <dc:type>http://purl.org/dc/dcmitype/Text</dc:type>
+      <dc:subject>Land titles</dc:subject>
+      <dc:format>text/rtf</dc:format>
+      <dct:abstract>Morbi ultriçes, dui suscipit vestibulum prètium, velit ante pretium tortor, egët tincidunt pede odio ac nulla.</dct:abstract>
+    </csw30:SummaryRecord>
+  </csw30:SearchResults>
+</csw30:GetRecordsResponse>
diff --git a/tests/expected/suites_csw30_get_bfe20134-d1da-42ef-9c0f-8e1307bbf92b.xml b/tests/expected/suites_csw30_get_bfe20134-d1da-42ef-9c0f-8e1307bbf92b.xml
new file mode 100644
index 0000000..4dd6601
--- /dev/null
+++ b/tests/expected/suites_csw30_get_bfe20134-d1da-42ef-9c0f-8e1307bbf92b.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- PYCSW_VERSION -->
+<csw30:GetRecordsResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:csw30="http://www.opengis.net/cat/csw/3.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="3.0.0" xsi:schemaLocation="http://www.opengis.net/cat/cs [...]
+  <csw30:SearchStatus timestamp="PYCSW_TIMESTAMP"/>
+  <csw30:SearchResults expires="PYCSW_EXPIRES" nextRecord="7" numberOfRecordsMatched="12" numberOfRecordsReturned="4" recordSchema="http://www.opengis.net/cat/csw/3.0" status="subset" elementSet="full" elapsedTime="PYCSW_ELAPSED_TIME">
+    <csw30:Record>
+      <dc:identifier>urn:uuid:66ae76b7-54ba-489b-a582-0f0633d96493</dc:identifier>
+      <dc:title>Maecenas enim</dc:title>
+      <dc:type>http://purl.org/dc/dcmitype/Text</dc:type>
+      <dc:subject>Marine sediments</dc:subject>
+      <dc:format>application/xhtml+xml</dc:format>
+      <dct:abstract>Pellentesque tempus magna non sapien fringilla blandit.</dct:abstract>
+    </csw30:Record>
+    <csw30:Record>
+      <dc:identifier>urn:uuid:6a3de50b-fa66-4b58-a0e6-ca146fdd18d4</dc:identifier>
+      <dc:title>Ut facilisis justo ut lacus</dc:title>
+      <dc:type>http://purl.org/dc/dcmitype/Service</dc:type>
+      <dc:subject>Vegetation</dc:subject>
+      <dc:relation>urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63</dc:relation>
+    </csw30:Record>
+    <csw30:Record>
+      <dc:identifier>urn:uuid:784e2afd-a9fd-44a6-9a92-a3848371c8ec</dc:identifier>
+      <dc:title>Aliquam fermentum purus quis arcu</dc:title>
+      <dc:type>http://purl.org/dc/dcmitype/Text</dc:type>
+      <dc:subject>Hydrography--Dictionaries</dc:subject>
+      <dc:format>application/pdf</dc:format>
+      <dct:abstract>Vestibulum quis ipsum sit amet metus imperdiet vehicula. Nulla scelerisque cursus mi.</dct:abstract>
+      <dc:date>2006-05-12</dc:date>
+    </csw30:Record>
+    <csw30:Record>
+      <dc:identifier>urn:uuid:829babb0-b2f1-49e1-8cd5-7b489fe71a1e</dc:identifier>
+      <dc:title>Vestibulum massa purus</dc:title>
+      <dc:type>http://purl.org/dc/dcmitype/Image</dc:type>
+      <dc:format>image/jp2</dc:format>
+      <dc:relation>urn:uuid:9a669547-b69b-469f-a11f-2d875366bbdc</dc:relation>
+    </csw30:Record>
+  </csw30:SearchResults>
+</csw30:GetRecordsResponse>
diff --git a/tests/expected/suites_csw30_get_c03d173a-3f42-4956-89c8-1fe02c3a0873.xml b/tests/expected/suites_csw30_get_c03d173a-3f42-4956-89c8-1fe02c3a0873.xml
new file mode 100644
index 0000000..ce9c935
--- /dev/null
+++ b/tests/expected/suites_csw30_get_c03d173a-3f42-4956-89c8-1fe02c3a0873.xml
@@ -0,0 +1,491 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- PYCSW_VERSION -->
+<csw30:Capabilities xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:csw30="http://www.opengis.net/cat/csw/3.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:fes20="http://www.opengis.net/fes/2.0" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:ows11="http://www.opengis.net/ows/1.1" xmlns:ows20="http://www.opengis.net/ows/2.0" xmlns:xlink="http://www.w3.org/199 [...]
+  <ows20:ServiceIdentification>
+    <ows20:Title>pycsw Geospatial Catalogue</ows20:Title>
+    <ows20:Abstract>pycsw is an OGC CSW server implementation written in Python</ows20:Abstract>
+    <ows20:Keywords>
+      <ows20:Keyword>catalogue</ows20:Keyword>
+      <ows20:Keyword>discovery</ows20:Keyword>
+      <ows20:Type codeSpace="ISOTC211/19115">theme</ows20:Type>
+    </ows20:Keywords>
+    <ows20:ServiceType codeSpace="OGC">CSW</ows20:ServiceType>
+    <ows20:ServiceTypeVersion>2.0.2</ows20:ServiceTypeVersion>
+    <ows20:ServiceTypeVersion>3.0.0</ows20:ServiceTypeVersion>
+    <ows20:Fees>None</ows20:Fees>
+    <ows20:AccessConstraints>None</ows20:AccessConstraints>
+  </ows20:ServiceIdentification>
+  <ows20:ServiceProvider>
+    <ows20:ProviderName>pycsw</ows20:ProviderName>
+    <ows20:ProviderSite xlink:type="simple" xlink:href="http://pycsw.org/"/>
+    <ows20:ServiceContact>
+      <ows20:IndividualName>Kralidis, Tom</ows20:IndividualName>
+      <ows20:PositionName>Senior Systems Scientist</ows20:PositionName>
+      <ows20:ContactInfo>
+        <ows20:Phone>
+          <ows20:Voice>+01-416-xxx-xxxx</ows20:Voice>
+          <ows20:Facsimile>+01-416-xxx-xxxx</ows20:Facsimile>
+        </ows20:Phone>
+        <ows20:Address>
+          <ows20:DeliveryPoint>TBA</ows20:DeliveryPoint>
+          <ows20:City>Toronto</ows20:City>
+          <ows20:AdministrativeArea>Ontario</ows20:AdministrativeArea>
+          <ows20:PostalCode>M9C 3Z9</ows20:PostalCode>
+          <ows20:Country>Canada</ows20:Country>
+          <ows20:ElectronicMailAddress>tomkralidis at gmail.com</ows20:ElectronicMailAddress>
+        </ows20:Address>
+        <ows20:OnlineResource xlink:type="simple" xlink:href="http://kralidis.ca/"/>
+        <ows20:HoursOfService>0800h - 1600h EST</ows20:HoursOfService>
+        <ows20:ContactInstructions>During hours of service.  Off on weekends.</ows20:ContactInstructions>
+      </ows20:ContactInfo>
+      <ows20:Role codeSpace="ISOTC211/19115">pointOfContact</ows20:Role>
+    </ows20:ServiceContact>
+  </ows20:ServiceProvider>
+  <ows20:OperationsMetadata>
+    <ows20:Operation name="GetCapabilities">
+      <ows20:DCP>
+        <ows20:HTTP>
+          <ows20:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg"/>
+          <ows20:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg"/>
+        </ows20:HTTP>
+      </ows20:DCP>
+      <ows20:Parameter name="acceptFormats">
+        <ows20:AllowedValues>
+          <ows20:Value>application/xml</ows20:Value>
+          <ows20:Value>text/xml</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Parameter name="acceptVersions">
+        <ows20:AllowedValues>
+          <ows20:Value>2.0.2</ows20:Value>
+          <ows20:Value>3.0.0</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Parameter name="sections">
+        <ows20:AllowedValues>
+          <ows20:Value>All</ows20:Value>
+          <ows20:Value>Filter_Capabilities</ows20:Value>
+          <ows20:Value>OperationsMetadata</ows20:Value>
+          <ows20:Value>ServiceIdentification</ows20:Value>
+          <ows20:Value>ServiceProvider</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+    </ows20:Operation>
+    <ows20:Operation name="GetDomain">
+      <ows20:DCP>
+        <ows20:HTTP>
+          <ows20:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg"/>
+          <ows20:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg"/>
+        </ows20:HTTP>
+      </ows20:DCP>
+      <ows20:Parameter name="ParameterName">
+        <ows20:AllowedValues>
+          <ows20:Value>GetCapabilities.acceptFormats</ows20:Value>
+          <ows20:Value>GetCapabilities.acceptVersions</ows20:Value>
+          <ows20:Value>GetCapabilities.sections</ows20:Value>
+          <ows20:Value>GetRecordById.ElementSetName</ows20:Value>
+          <ows20:Value>GetRecordById.outputFormat</ows20:Value>
+          <ows20:Value>GetRecordById.outputSchema</ows20:Value>
+          <ows20:Value>GetRecords.CONSTRAINTLANGUAGE</ows20:Value>
+          <ows20:Value>GetRecords.ElementSetName</ows20:Value>
+          <ows20:Value>GetRecords.outputFormat</ows20:Value>
+          <ows20:Value>GetRecords.outputSchema</ows20:Value>
+          <ows20:Value>GetRecords.typeNames</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+    </ows20:Operation>
+    <ows20:Operation name="GetRecords">
+      <ows20:DCP>
+        <ows20:HTTP>
+          <ows20:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg"/>
+          <ows20:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg"/>
+        </ows20:HTTP>
+      </ows20:DCP>
+      <ows20:Parameter name="CONSTRAINTLANGUAGE">
+        <ows20:AllowedValues>
+          <ows20:Value>CQL_TEXT</ows20:Value>
+          <ows20:Value>FILTER</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Parameter name="ElementSetName">
+        <ows20:AllowedValues>
+          <ows20:Value>brief</ows20:Value>
+          <ows20:Value>full</ows20:Value>
+          <ows20:Value>summary</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Parameter name="outputFormat">
+        <ows20:AllowedValues>
+          <ows20:Value>application/atom+xml</ows20:Value>
+          <ows20:Value>application/json</ows20:Value>
+          <ows20:Value>application/xml</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Parameter name="outputSchema">
+        <ows20:AllowedValues>
+          <ows20:Value>http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/</ows20:Value>
+          <ows20:Value>http://www.interlis.ch/INTERLIS2.3</ows20:Value>
+          <ows20:Value>http://www.opengis.net/cat/csw/3.0</ows20:Value>
+          <ows20:Value>http://www.opengis.net/cat/csw/csdgm</ows20:Value>
+          <ows20:Value>http://www.w3.org/2005/Atom</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Parameter name="typeNames">
+        <ows20:AllowedValues>
+          <ows20:Value>csw:Record</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Constraint name="MaxRecordDefault">
+        <ows20:AllowedValues>
+          <ows20:Value>10</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Constraint>
+      <ows20:Constraint name="OpenSearchDescriptionDocument">
+        <ows20:AllowedValues>
+          <ows20:Value>http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg?mode=opensearch&service=CSW&version=3.0.0&request=GetCapabilities</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Constraint>
+      <ows20:Constraint name="FederatedCatalogues">
+        <ows20:AllowedValues>
+          <ows20:Value>http://demo.pycsw.org/gisdata/csw</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Constraint>
+    </ows20:Operation>
+    <ows20:Operation name="GetRecordById">
+      <ows20:DCP>
+        <ows20:HTTP>
+          <ows20:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg"/>
+          <ows20:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg"/>
+        </ows20:HTTP>
+      </ows20:DCP>
+      <ows20:Parameter name="ElementSetName">
+        <ows20:AllowedValues>
+          <ows20:Value>brief</ows20:Value>
+          <ows20:Value>full</ows20:Value>
+          <ows20:Value>summary</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Parameter name="outputFormat">
+        <ows20:AllowedValues>
+          <ows20:Value>application/atom+xml</ows20:Value>
+          <ows20:Value>application/json</ows20:Value>
+          <ows20:Value>application/xml</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Parameter name="outputSchema">
+        <ows20:AllowedValues>
+          <ows20:Value>http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/</ows20:Value>
+          <ows20:Value>http://www.interlis.ch/INTERLIS2.3</ows20:Value>
+          <ows20:Value>http://www.opengis.net/cat/csw/3.0</ows20:Value>
+          <ows20:Value>http://www.opengis.net/cat/csw/csdgm</ows20:Value>
+          <ows20:Value>http://www.w3.org/2005/Atom</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+    </ows20:Operation>
+    <ows20:Operation name="GetRepositoryItem">
+      <ows20:DCP>
+        <ows20:HTTP>
+          <ows20:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg"/>
+        </ows20:HTTP>
+      </ows20:DCP>
+    </ows20:Operation>
+    <ows20:Parameter name="service">
+      <ows20:AllowedValues>
+        <ows20:Value>CSW</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Parameter>
+    <ows20:Parameter name="version">
+      <ows20:AllowedValues>
+        <ows20:Value>2.0.2</ows20:Value>
+        <ows20:Value>3.0.0</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Parameter>
+    <ows20:Constraint name="CoreQueryables">
+      <ows20:AllowedValues>
+        <ows20:Value>csw:AnyText</ows20:Value>
+        <ows20:Value>dc:contributor</ows20:Value>
+        <ows20:Value>dc:creator</ows20:Value>
+        <ows20:Value>dc:date</ows20:Value>
+        <ows20:Value>dc:format</ows20:Value>
+        <ows20:Value>dc:identifier</ows20:Value>
+        <ows20:Value>dc:language</ows20:Value>
+        <ows20:Value>dc:publisher</ows20:Value>
+        <ows20:Value>dc:relation</ows20:Value>
+        <ows20:Value>dc:rights</ows20:Value>
+        <ows20:Value>dc:source</ows20:Value>
+        <ows20:Value>dc:subject</ows20:Value>
+        <ows20:Value>dc:title</ows20:Value>
+        <ows20:Value>dc:type</ows20:Value>
+        <ows20:Value>dct:abstract</ows20:Value>
+        <ows20:Value>dct:modified</ows20:Value>
+        <ows20:Value>ows:BoundingBox</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="FederatedCatalogues">
+      <ows20:AllowedValues>
+        <ows20:Value>http://demo.pycsw.org/gisdata/csw</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="MaxRecordDefault">
+      <ows20:AllowedValues>
+        <ows20:Value>10</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="PostEncoding">
+      <ows20:AllowedValues>
+        <ows20:Value>SOAP</ows20:Value>
+        <ows20:Value>XML</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="XPathQueryables">
+      <ows20:AllowedValues>
+        <ows20:Value>allowed</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/CoreQueryables">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/CoreSortables">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/DefaultSortingAlgorithm">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Filter-CQL">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Filter-FES-KVP-Advanced">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Filter-FES-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetCapabilities-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetDomain-KVP">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetDomain-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetRecordById-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetRecords-Async-KVP">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetRecords-Async-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetRecords-Basic-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetRecords-Distributed-KVP">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetRecords-Distributed-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Harvest-Async-KVP">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Harvest-Async-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Harvest-Basic-KVP">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Harvest-Basic-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Harvest-Periodic-KVP">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Harvest-Periodic-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/OpenSearch">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/SupportedGMLVersions">
+      <ows20:AllowedValues>
+        <ows20:Value>http://www.opengis.net/gml</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Transaction">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+  </ows20:OperationsMetadata>
+  <ows20:Languages>
+    <ows20:Language>en</ows20:Language>
+  </ows20:Languages>
+  <fes20:Filter_Capabilities>
+    <fes20:Conformance>
+      <fes20:Constraint name="ImplementsQuery">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsAdHocQuery">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsFunctions">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsResourceld">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsMinStandardFilter">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsStandardFilter">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsMinSpatialFilter">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsSpatialFilter">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsMinTemporalFilter">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsTemporalFilter">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsVersionNav">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsSorting">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsExtendedOperators">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsMinimumXPath">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsSchemaElementFunc">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+    </fes20:Conformance>
+    <fes20:Id_Capabilities>
+      <fes20:ResourceIdentifier name="csw30:id"/>
+    </fes20:Id_Capabilities>
+    <fes20:Scalar_Capabilities>
+      <fes20:LogicalOperators/>
+      <fes20:ComparisonOperators>
+        <fes20:ComparisonOperator name="PropertyIsBetween"/>
+        <fes20:ComparisonOperator name="PropertyIsEqualTo"/>
+        <fes20:ComparisonOperator name="PropertyIsGreaterThan"/>
+        <fes20:ComparisonOperator name="PropertyIsGreaterThanOrEqualTo"/>
+        <fes20:ComparisonOperator name="PropertyIsLessThan"/>
+        <fes20:ComparisonOperator name="PropertyIsLessThanOrEqualTo"/>
+        <fes20:ComparisonOperator name="PropertyIsLike"/>
+        <fes20:ComparisonOperator name="PropertyIsNotEqualTo"/>
+        <fes20:ComparisonOperator name="PropertyIsNull"/>
+      </fes20:ComparisonOperators>
+    </fes20:Scalar_Capabilities>
+    <fes20:Spatial_Capabilities>
+      <fes20:GeometryOperands>
+        <fes20:GeometryOperand name="gml:Point"/>
+        <fes20:GeometryOperand name="gml:LineString"/>
+        <fes20:GeometryOperand name="gml:Polygon"/>
+        <fes20:GeometryOperand name="gml:Envelope"/>
+      </fes20:GeometryOperands>
+      <fes20:SpatialOperators>
+        <fes20:SpatialOperator name="BBOX"/>
+        <fes20:SpatialOperator name="Beyond"/>
+        <fes20:SpatialOperator name="Contains"/>
+        <fes20:SpatialOperator name="Crosses"/>
+        <fes20:SpatialOperator name="Disjoint"/>
+        <fes20:SpatialOperator name="DWithin"/>
+        <fes20:SpatialOperator name="Equals"/>
+        <fes20:SpatialOperator name="Intersects"/>
+        <fes20:SpatialOperator name="Overlaps"/>
+        <fes20:SpatialOperator name="Touches"/>
+        <fes20:SpatialOperator name="Within"/>
+      </fes20:SpatialOperators>
+    </fes20:Spatial_Capabilities>
+    <fes20:Functions>
+      <fes20:Function name="length">
+        <fes20:Returns>xs:string</fes20:Returns>
+      </fes20:Function>
+      <fes20:Function name="lower">
+        <fes20:Returns>xs:string</fes20:Returns>
+      </fes20:Function>
+      <fes20:Function name="ltrim">
+        <fes20:Returns>xs:string</fes20:Returns>
+      </fes20:Function>
+      <fes20:Function name="rtrim">
+        <fes20:Returns>xs:string</fes20:Returns>
+      </fes20:Function>
+      <fes20:Function name="trim">
+        <fes20:Returns>xs:string</fes20:Returns>
+      </fes20:Function>
+      <fes20:Function name="upper">
+        <fes20:Returns>xs:string</fes20:Returns>
+      </fes20:Function>
+    </fes20:Functions>
+  </fes20:Filter_Capabilities>
+</csw30:Capabilities>
diff --git a/tests/expected/suites_csw30_get_cb43d8c3-e14c-4a9f-9231-4384b7dd21f3.xml b/tests/expected/suites_csw30_get_cb43d8c3-e14c-4a9f-9231-4384b7dd21f3.xml
new file mode 100644
index 0000000..8affab5
--- /dev/null
+++ b/tests/expected/suites_csw30_get_cb43d8c3-e14c-4a9f-9231-4384b7dd21f3.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- PYCSW_VERSION -->
+<ows20:ExceptionReport xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:ows20="http://www.opengis.net/ows/2.0" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="3.0.0" xml:lang="en-US" xsi:schemaLocation="http://www.opengis. [...]
+  <ows20:Exception exceptionCode="InvalidParameterValue" locator="elementname">
+    <ows20:ExceptionText>Invalid ElementName parameter value: u</ows20:ExceptionText>
+  </ows20:Exception>
+</ows20:ExceptionReport>
diff --git a/tests/expected/suites_csw30_get_d03c6fd3-e821-4a26-b62f-d20a474e25af.xml b/tests/expected/suites_csw30_get_d03c6fd3-e821-4a26-b62f-d20a474e25af.xml
new file mode 100644
index 0000000..770e62f
--- /dev/null
+++ b/tests/expected/suites_csw30_get_d03c6fd3-e821-4a26-b62f-d20a474e25af.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- PYCSW_VERSION -->
+<csw30:Capabilities xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:csw30="http://www.opengis.net/cat/csw/3.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:ows20="http://www.opengis.net/ows/2.0" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XML [...]
+  <ows20:ServiceProvider>
+    <ows20:ProviderName>pycsw</ows20:ProviderName>
+    <ows20:ProviderSite xlink:type="simple" xlink:href="http://pycsw.org/"/>
+    <ows20:ServiceContact>
+      <ows20:IndividualName>Kralidis, Tom</ows20:IndividualName>
+      <ows20:PositionName>Senior Systems Scientist</ows20:PositionName>
+      <ows20:ContactInfo>
+        <ows20:Phone>
+          <ows20:Voice>+01-416-xxx-xxxx</ows20:Voice>
+          <ows20:Facsimile>+01-416-xxx-xxxx</ows20:Facsimile>
+        </ows20:Phone>
+        <ows20:Address>
+          <ows20:DeliveryPoint>TBA</ows20:DeliveryPoint>
+          <ows20:City>Toronto</ows20:City>
+          <ows20:AdministrativeArea>Ontario</ows20:AdministrativeArea>
+          <ows20:PostalCode>M9C 3Z9</ows20:PostalCode>
+          <ows20:Country>Canada</ows20:Country>
+          <ows20:ElectronicMailAddress>tomkralidis at gmail.com</ows20:ElectronicMailAddress>
+        </ows20:Address>
+        <ows20:OnlineResource xlink:type="simple" xlink:href="http://kralidis.ca/"/>
+        <ows20:HoursOfService>0800h - 1600h EST</ows20:HoursOfService>
+        <ows20:ContactInstructions>During hours of service.  Off on weekends.</ows20:ContactInstructions>
+      </ows20:ContactInfo>
+      <ows20:Role codeSpace="ISOTC211/19115">pointOfContact</ows20:Role>
+    </ows20:ServiceContact>
+  </ows20:ServiceProvider>
+</csw30:Capabilities>
diff --git a/tests/expected/suites_csw30_get_d4ccbf96-a529-480e-a53d-5b88dc1dea7f.xml b/tests/expected/suites_csw30_get_d4ccbf96-a529-480e-a53d-5b88dc1dea7f.xml
new file mode 100644
index 0000000..faf07a5
--- /dev/null
+++ b/tests/expected/suites_csw30_get_d4ccbf96-a529-480e-a53d-5b88dc1dea7f.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- PYCSW_VERSION -->
+<ows20:ExceptionReport xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:ows20="http://www.opengis.net/ows/2.0" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="3.0.0" xml:lang="en-US" xsi:schemaLocation="http://www.opengis. [...]
+  <ows20:Exception exceptionCode="NotFound" locator="recordids">
+    <ows20:ExceptionText>No records found for 'uid-bc5017e6-5cc8-4b03-aee7-d88f88caba0a'</ows20:ExceptionText>
+  </ows20:Exception>
+</ows20:ExceptionReport>
diff --git a/tests/expected/suites_csw30_get_d94c801a-1207-4897-b84a-53f3a192515b.xml b/tests/expected/suites_csw30_get_d94c801a-1207-4897-b84a-53f3a192515b.xml
new file mode 100644
index 0000000..d91c31b
--- /dev/null
+++ b/tests/expected/suites_csw30_get_d94c801a-1207-4897-b84a-53f3a192515b.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- PYCSW_VERSION -->
+<csw30:GetRecordsResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:csw30="http://www.opengis.net/cat/csw/3.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="3.0.0" xsi:schemaLocation="http://www.opengis.net/cat/cs [...]
+  <csw30:SearchStatus timestamp="PYCSW_TIMESTAMP"/>
+  <csw30:SearchResults expires="PYCSW_EXPIRES" nextRecord="0" numberOfRecordsMatched="0" numberOfRecordsReturned="0" recordSchema="http://www.opengis.net/cat/csw/3.0" status="subset" elementSet="full" elapsedTime="PYCSW_ELAPSED_TIME"/>
+</csw30:GetRecordsResponse>
diff --git a/tests/expected/suites_csw30_get_da859e34-91fc-495a-8c09-285a40c0900b.xml b/tests/expected/suites_csw30_get_da859e34-91fc-495a-8c09-285a40c0900b.xml
new file mode 100644
index 0000000..d85e801
--- /dev/null
+++ b/tests/expected/suites_csw30_get_da859e34-91fc-495a-8c09-285a40c0900b.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- PYCSW_VERSION -->
+<csw30:Record xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:csw30="http://www.opengis.net/cat/csw/3.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:ows20="http://www.opengis.net/ows/2.0" xmlns:xs="http://www.w3.org/2001/XMLSchema">
+  <dc:identifier>urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63</dc:identifier>
+  <dc:title>Mauris sed neque</dc:title>
+  <dc:type>http://purl.org/dc/dcmitype/Dataset</dc:type>
+  <dc:subject>Vegetation-Cropland</dc:subject>
+  <dct:abstract>Curabitur lacinia, ante non porta tempus, mi lorem feugiat odio, eget suscipit eros pede ac velit.</dct:abstract>
+  <dc:date>2006-03-26</dc:date>
+  <ows20:BoundingBox crs="http://www.opengis.net/def/crs/EPSG/0/4326" dimensions="2">
+    <ows20:LowerCorner>47.59 -4.1</ows20:LowerCorner>
+    <ows20:UpperCorner>51.22 0.89</ows20:UpperCorner>
+  </ows20:BoundingBox>
+</csw30:Record>
diff --git a/tests/expected/suites_csw30_get_dc246fb8-5af5-4fda-82bb-c18b3ecd439c.xml b/tests/expected/suites_csw30_get_dc246fb8-5af5-4fda-82bb-c18b3ecd439c.xml
new file mode 100644
index 0000000..530b79b
--- /dev/null
+++ b/tests/expected/suites_csw30_get_dc246fb8-5af5-4fda-82bb-c18b3ecd439c.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- PYCSW_VERSION -->
+<atom:feed xmlns:atom="http://www.w3.org/2005/Atom" xmlns:os="http://a9.com/-/spec/opensearch/1.1/">
+  <atom:id>http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg</atom:id>
+  <atom:title>pycsw Geospatial Catalogue</atom:title>
+  <atom:author>
+    <atom:name>pycsw</atom:name>
+  </atom:author>
+  <atom:link href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg&mode=opensearch&service=CSW&version=3.0.0&request=GetCapabilities" rel="search" type="application/opensearchdescription+xml"/>
+  <atom:updated>PYCSW_TIMESTAMP</atom:updated>
+  <os:Query role="request"/>
+  <os:totalResults>3</os:totalResults>
+  <os:startIndex>1</os:startIndex>
+  <os:itemsPerPage>3</os:itemsPerPage>
+  <atom:entry xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dc="http://purl.org/dc/elements/1.1/" xsi:schemaLocation="http://www.w3.org/2005/Atom http://www.kbcafe.com/rss/atom.xsd.xml">
+    <atom:category term="Tourism--Greece"/>
+    <atom:id>urn:uuid:19887a8a-f6b0-4a63-ae56-7fba0e17801f</atom:id>
+    <dc:identifier>urn:uuid:19887a8a-f6b0-4a63-ae56-7fba0e17801f</dc:identifier>
+    <atom:link href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg?service=CSW&version=2.0.2&request=GetRepositoryItem&id=urn:uuid:19887a8a-f6b0-4a63-ae56-7fba0e17801f"/>
+    <atom:title>Lorem ipsum</atom:title>
+    <atom:updated>PYCSW_TIMESTAMP</atom:updated>
+    <atom:summary>Quisque lacus diam, placerat mollis, pharetra in, commodo sed, augue. Duis iaculis arcu vel arcu.</atom:summary>
+  </atom:entry>
+  <atom:entry xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dc="http://purl.org/dc/elements/1.1/" xsi:schemaLocation="http://www.w3.org/2005/Atom http://www.kbcafe.com/rss/atom.xsd.xml">
+    <atom:category term="Hydrography--Dictionaries"/>
+    <atom:id>urn:uuid:784e2afd-a9fd-44a6-9a92-a3848371c8ec</atom:id>
+    <dc:identifier>urn:uuid:784e2afd-a9fd-44a6-9a92-a3848371c8ec</dc:identifier>
+    <atom:link href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg?service=CSW&version=2.0.2&request=GetRepositoryItem&id=urn:uuid:784e2afd-a9fd-44a6-9a92-a3848371c8ec"/>
+    <atom:title>Aliquam fermentum purus quis arcu</atom:title>
+    <atom:updated>PYCSW_TIMESTAMP</atom:updated>
+    <atom:summary>Vestibulum quis ipsum sit amet metus imperdiet vehicula. Nulla scelerisque cursus mi.</atom:summary>
+  </atom:entry>
+  <atom:entry xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dc="http://purl.org/dc/elements/1.1/" xsi:schemaLocation="http://www.w3.org/2005/Atom http://www.kbcafe.com/rss/atom.xsd.xml">
+    <atom:id>urn:uuid:a06af396-3105-442d-8b40-22b57a90d2f2</atom:id>
+    <dc:identifier>urn:uuid:a06af396-3105-442d-8b40-22b57a90d2f2</dc:identifier>
+    <atom:link href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg?service=CSW&version=2.0.2&request=GetRepositoryItem&id=urn:uuid:a06af396-3105-442d-8b40-22b57a90d2f2"/>
+    <atom:title>Lorem ipsum dolor sit amet</atom:title>
+    <atom:updated>PYCSW_TIMESTAMP</atom:updated>
+  </atom:entry>
+</atom:feed>
diff --git a/tests/expected/suites_csw30_get_de016645-6d5c-4855-943c-2db07ae9f49a.xml b/tests/expected/suites_csw30_get_de016645-6d5c-4855-943c-2db07ae9f49a.xml
new file mode 100644
index 0000000..4cdb061
--- /dev/null
+++ b/tests/expected/suites_csw30_get_de016645-6d5c-4855-943c-2db07ae9f49a.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- PYCSW_VERSION -->
+<atom:feed xmlns:atom="http://www.w3.org/2005/Atom" xmlns:os="http://a9.com/-/spec/opensearch/1.1/">
+  <atom:id>http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg</atom:id>
+  <atom:title>pycsw Geospatial Catalogue</atom:title>
+  <atom:author>
+    <atom:name>pycsw</atom:name>
+  </atom:author>
+  <atom:link href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg&mode=opensearch&service=CSW&version=3.0.0&request=GetCapabilities" rel="search" type="application/opensearchdescription+xml"/>
+  <atom:updated>PYCSW_TIMESTAMP</atom:updated>
+  <os:Query role="request"/>
+  <os:totalResults>1</os:totalResults>
+  <os:startIndex>1</os:startIndex>
+  <os:itemsPerPage>1</os:itemsPerPage>
+  <atom:entry xmlns:georss="http://www.georss.org/georss" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:gml="http://www.opengis.net/gml" xsi:schemaLocation="http://www.w3.org/2005/Atom http://www.kbcafe.com/rss/atom.xsd.xml">
+    <atom:category term="Vegetation-Cropland"/>
+    <atom:id>urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63</atom:id>
+    <dc:identifier>urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63</dc:identifier>
+    <atom:link href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg?service=CSW&version=2.0.2&request=GetRepositoryItem&id=urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63"/>
+    <atom:title>Mauris sed neque</atom:title>
+    <atom:updated>PYCSW_TIMESTAMP</atom:updated>
+    <atom:summary>Curabitur lacinia, ante non porta tempus, mi lorem feugiat odio, eget suscipit eros pede ac velit.</atom:summary>
+    <georss:where>
+      <gml:Envelope srsName="http://www.opengis.net/def/crs/EPSG/0/4326">
+        <gml:lowerCorner>47.59 -4.1</gml:lowerCorner>
+        <gml:upperCorner>51.22 0.89</gml:upperCorner>
+      </gml:Envelope>
+    </georss:where>
+  </atom:entry>
+</atom:feed>
diff --git a/tests/expected/suites_cite_post_6e736fd0-c266-4852-9eb3-0656f5d0f5c4.xml b/tests/expected/suites_csw30_get_dff3ec6b-bb2d-4887-bd17-8fcf15def042.xml
similarity index 59%
copy from tests/expected/suites_cite_post_6e736fd0-c266-4852-9eb3-0656f5d0f5c4.xml
copy to tests/expected/suites_csw30_get_dff3ec6b-bb2d-4887-bd17-8fcf15def042.xml
index f704008..8140919 100644
--- a/tests/expected/suites_cite_post_6e736fd0-c266-4852-9eb3-0656f5d0f5c4.xml
+++ b/tests/expected/suites_csw30_get_dff3ec6b-bb2d-4887-bd17-8fcf15def042.xml
@@ -1,89 +1,89 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<csw:GetRecordsResponse xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ows="http://www.opengis.net/ows" xmlns:fgdc="http://www.opengis.net/cat/csw/csdg [...]
-  <csw:SearchStatus timestamp="PYCSW_TIMESTAMP"/>
-  <csw:SearchResults nextRecord="11" numberOfRecordsMatched="12" numberOfRecordsReturned="10" recordSchema="http://www.opengis.net/cat/csw/2.0.2" elementSet="summary">
-    <csw:SummaryRecord>
+<csw30:GetRecordsResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:csw30="http://www.opengis.net/cat/csw/3.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:ows20="http://www.opengis.net/ows/2.0" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="3.0.0" xsi: [...]
+  <csw30:SearchStatus timestamp="PYCSW_TIMESTAMP"/>
+  <csw30:SearchResults expires="PYCSW_EXPIRES" nextRecord="11" numberOfRecordsMatched="12" numberOfRecordsReturned="10" recordSchema="http://www.opengis.net/cat/csw/3.0" status="subset" elementSet="summary" elapsedTime="PYCSW_ELAPSED_TIME">
+    <csw30:SummaryRecord>
       <dc:identifier>urn:uuid:19887a8a-f6b0-4a63-ae56-7fba0e17801f</dc:identifier>
       <dc:title>Lorem ipsum</dc:title>
       <dc:type>http://purl.org/dc/dcmitype/Image</dc:type>
       <dc:subject>Tourism--Greece</dc:subject>
       <dc:format>image/svg+xml</dc:format>
       <dct:abstract>Quisque lacus diam, placerat mollis, pharetra in, commodo sed, augue. Duis iaculis arcu vel arcu.</dct:abstract>
-    </csw:SummaryRecord>
-    <csw:SummaryRecord>
+    </csw30:SummaryRecord>
+    <csw30:SummaryRecord>
       <dc:identifier>urn:uuid:1ef30a8b-876d-4828-9246-c37ab4510bbd</dc:identifier>
       <dc:title></dc:title>
       <dc:type>http://purl.org/dc/dcmitype/Service</dc:type>
       <dct:abstract>Proin sit amet justo. In justo. Aenean adipiscing nulla id tellus.</dct:abstract>
-      <ows:BoundingBox crs="urn:x-ogc:def:crs:EPSG:6.11:4326" dimensions="2">
-        <ows:LowerCorner>60.04 13.75</ows:LowerCorner>
-        <ows:UpperCorner>68.41 17.92</ows:UpperCorner>
-      </ows:BoundingBox>
-    </csw:SummaryRecord>
-    <csw:SummaryRecord>
+      <ows20:BoundingBox crs="http://www.opengis.net/def/crs/EPSG/0/4326" dimensions="2">
+        <ows20:LowerCorner>60.04 13.75</ows20:LowerCorner>
+        <ows20:UpperCorner>68.41 17.92</ows20:UpperCorner>
+      </ows20:BoundingBox>
+    </csw30:SummaryRecord>
+    <csw30:SummaryRecord>
       <dc:identifier>urn:uuid:66ae76b7-54ba-489b-a582-0f0633d96493</dc:identifier>
       <dc:title>Maecenas enim</dc:title>
       <dc:type>http://purl.org/dc/dcmitype/Text</dc:type>
       <dc:subject>Marine sediments</dc:subject>
       <dc:format>application/xhtml+xml</dc:format>
       <dct:abstract>Pellentesque tempus magna non sapien fringilla blandit.</dct:abstract>
-    </csw:SummaryRecord>
-    <csw:SummaryRecord>
+    </csw30:SummaryRecord>
+    <csw30:SummaryRecord>
       <dc:identifier>urn:uuid:6a3de50b-fa66-4b58-a0e6-ca146fdd18d4</dc:identifier>
       <dc:title>Ut facilisis justo ut lacus</dc:title>
       <dc:type>http://purl.org/dc/dcmitype/Service</dc:type>
       <dc:subject>Vegetation</dc:subject>
       <dc:relation>urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63</dc:relation>
-    </csw:SummaryRecord>
-    <csw:SummaryRecord>
+    </csw30:SummaryRecord>
+    <csw30:SummaryRecord>
       <dc:identifier>urn:uuid:784e2afd-a9fd-44a6-9a92-a3848371c8ec</dc:identifier>
       <dc:title>Aliquam fermentum purus quis arcu</dc:title>
       <dc:type>http://purl.org/dc/dcmitype/Text</dc:type>
       <dc:subject>Hydrography--Dictionaries</dc:subject>
       <dc:format>application/pdf</dc:format>
       <dct:abstract>Vestibulum quis ipsum sit amet metus imperdiet vehicula. Nulla scelerisque cursus mi.</dct:abstract>
-    </csw:SummaryRecord>
-    <csw:SummaryRecord>
+    </csw30:SummaryRecord>
+    <csw30:SummaryRecord>
       <dc:identifier>urn:uuid:829babb0-b2f1-49e1-8cd5-7b489fe71a1e</dc:identifier>
       <dc:title>Vestibulum massa purus</dc:title>
       <dc:type>http://purl.org/dc/dcmitype/Image</dc:type>
       <dc:format>image/jp2</dc:format>
       <dc:relation>urn:uuid:9a669547-b69b-469f-a11f-2d875366bbdc</dc:relation>
-    </csw:SummaryRecord>
-    <csw:SummaryRecord>
+    </csw30:SummaryRecord>
+    <csw30:SummaryRecord>
       <dc:identifier>urn:uuid:88247b56-4cbc-4df9-9860-db3f8042e357</dc:identifier>
       <dc:title></dc:title>
       <dc:type>http://purl.org/dc/dcmitype/Dataset</dc:type>
       <dc:subject>Physiography-Landforms</dc:subject>
       <dct:abstract>Donec scelerisque pede ut nisl luctus accumsan. Quisque ultrices, lorem eget feugiat fringilla, lorem dui porttitor ante, cursus ultrices magna odio eu neque.</dct:abstract>
-    </csw:SummaryRecord>
-    <csw:SummaryRecord>
+    </csw30:SummaryRecord>
+    <csw30:SummaryRecord>
       <dc:identifier>urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63</dc:identifier>
       <dc:title>Mauris sed neque</dc:title>
       <dc:type>http://purl.org/dc/dcmitype/Dataset</dc:type>
       <dc:subject>Vegetation-Cropland</dc:subject>
       <dct:abstract>Curabitur lacinia, ante non porta tempus, mi lorem feugiat odio, eget suscipit eros pede ac velit.</dct:abstract>
-      <ows:BoundingBox crs="urn:x-ogc:def:crs:EPSG:6.11:4326" dimensions="2">
-        <ows:LowerCorner>47.59 -4.1</ows:LowerCorner>
-        <ows:UpperCorner>51.22 0.89</ows:UpperCorner>
-      </ows:BoundingBox>
-    </csw:SummaryRecord>
-    <csw:SummaryRecord>
+      <ows20:BoundingBox crs="http://www.opengis.net/def/crs/EPSG/0/4326" dimensions="2">
+        <ows20:LowerCorner>47.59 -4.1</ows20:LowerCorner>
+        <ows20:UpperCorner>51.22 0.89</ows20:UpperCorner>
+      </ows20:BoundingBox>
+    </csw30:SummaryRecord>
+    <csw30:SummaryRecord>
       <dc:identifier>urn:uuid:9a669547-b69b-469f-a11f-2d875366bbdc</dc:identifier>
       <dc:title>Ñunç elementum</dc:title>
       <dc:type>http://purl.org/dc/dcmitype/Dataset</dc:type>
       <dc:subject>Hydrography-Oceanographic</dc:subject>
-      <ows:BoundingBox crs="urn:x-ogc:def:crs:EPSG:6.11:4326" dimensions="2">
-        <ows:LowerCorner>44.79 -6.17</ows:LowerCorner>
-        <ows:UpperCorner>51.13 -2.23</ows:UpperCorner>
-      </ows:BoundingBox>
-    </csw:SummaryRecord>
-    <csw:SummaryRecord>
+      <ows20:BoundingBox crs="http://www.opengis.net/def/crs/EPSG/0/4326" dimensions="2">
+        <ows20:LowerCorner>44.79 -6.17</ows20:LowerCorner>
+        <ows20:UpperCorner>51.13 -2.23</ows20:UpperCorner>
+      </ows20:BoundingBox>
+    </csw30:SummaryRecord>
+    <csw30:SummaryRecord>
       <dc:identifier>urn:uuid:a06af396-3105-442d-8b40-22b57a90d2f2</dc:identifier>
       <dc:title>Lorem ipsum dolor sit amet</dc:title>
       <dc:type>http://purl.org/dc/dcmitype/Image</dc:type>
       <dc:format>image/jpeg</dc:format>
-    </csw:SummaryRecord>
-  </csw:SearchResults>
-</csw:GetRecordsResponse>
+    </csw30:SummaryRecord>
+  </csw30:SearchResults>
+</csw30:GetRecordsResponse>
diff --git a/tests/expected/suites_csw30_get_e38e6bfb-8ac4-4ae4-8b87-0aafbc8d3c6b.xml b/tests/expected/suites_csw30_get_e38e6bfb-8ac4-4ae4-8b87-0aafbc8d3c6b.xml
new file mode 100644
index 0000000..2a3f20b
--- /dev/null
+++ b/tests/expected/suites_csw30_get_e38e6bfb-8ac4-4ae4-8b87-0aafbc8d3c6b.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- PYCSW_VERSION -->
+<csw30:BriefRecord xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:csw30="http://www.opengis.net/cat/csw/3.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:ows20="http://www.opengis.net/ows/2.0" xmlns:xs="http://www.w3.org/2001/XMLSchema">
+  <dc:identifier>urn:uuid:1ef30a8b-876d-4828-9246-c37ab4510bbd</dc:identifier>
+  <dc:title></dc:title>
+  <dc:type>http://purl.org/dc/dcmitype/Service</dc:type>
+  <ows20:BoundingBox crs="http://www.opengis.net/def/crs/EPSG/0/4326" dimensions="2">
+    <ows20:LowerCorner>60.04 13.75</ows20:LowerCorner>
+    <ows20:UpperCorner>68.41 17.92</ows20:UpperCorner>
+  </ows20:BoundingBox>
+</csw30:BriefRecord>
diff --git a/tests/expected/suites_csw30_get_e67ca935-d65d-4d8c-8302-1405333dded0.xml b/tests/expected/suites_csw30_get_e67ca935-d65d-4d8c-8302-1405333dded0.xml
new file mode 100644
index 0000000..ce9c935
--- /dev/null
+++ b/tests/expected/suites_csw30_get_e67ca935-d65d-4d8c-8302-1405333dded0.xml
@@ -0,0 +1,491 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- PYCSW_VERSION -->
+<csw30:Capabilities xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:csw30="http://www.opengis.net/cat/csw/3.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:fes20="http://www.opengis.net/fes/2.0" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:ows11="http://www.opengis.net/ows/1.1" xmlns:ows20="http://www.opengis.net/ows/2.0" xmlns:xlink="http://www.w3.org/199 [...]
+  <ows20:ServiceIdentification>
+    <ows20:Title>pycsw Geospatial Catalogue</ows20:Title>
+    <ows20:Abstract>pycsw is an OGC CSW server implementation written in Python</ows20:Abstract>
+    <ows20:Keywords>
+      <ows20:Keyword>catalogue</ows20:Keyword>
+      <ows20:Keyword>discovery</ows20:Keyword>
+      <ows20:Type codeSpace="ISOTC211/19115">theme</ows20:Type>
+    </ows20:Keywords>
+    <ows20:ServiceType codeSpace="OGC">CSW</ows20:ServiceType>
+    <ows20:ServiceTypeVersion>2.0.2</ows20:ServiceTypeVersion>
+    <ows20:ServiceTypeVersion>3.0.0</ows20:ServiceTypeVersion>
+    <ows20:Fees>None</ows20:Fees>
+    <ows20:AccessConstraints>None</ows20:AccessConstraints>
+  </ows20:ServiceIdentification>
+  <ows20:ServiceProvider>
+    <ows20:ProviderName>pycsw</ows20:ProviderName>
+    <ows20:ProviderSite xlink:type="simple" xlink:href="http://pycsw.org/"/>
+    <ows20:ServiceContact>
+      <ows20:IndividualName>Kralidis, Tom</ows20:IndividualName>
+      <ows20:PositionName>Senior Systems Scientist</ows20:PositionName>
+      <ows20:ContactInfo>
+        <ows20:Phone>
+          <ows20:Voice>+01-416-xxx-xxxx</ows20:Voice>
+          <ows20:Facsimile>+01-416-xxx-xxxx</ows20:Facsimile>
+        </ows20:Phone>
+        <ows20:Address>
+          <ows20:DeliveryPoint>TBA</ows20:DeliveryPoint>
+          <ows20:City>Toronto</ows20:City>
+          <ows20:AdministrativeArea>Ontario</ows20:AdministrativeArea>
+          <ows20:PostalCode>M9C 3Z9</ows20:PostalCode>
+          <ows20:Country>Canada</ows20:Country>
+          <ows20:ElectronicMailAddress>tomkralidis at gmail.com</ows20:ElectronicMailAddress>
+        </ows20:Address>
+        <ows20:OnlineResource xlink:type="simple" xlink:href="http://kralidis.ca/"/>
+        <ows20:HoursOfService>0800h - 1600h EST</ows20:HoursOfService>
+        <ows20:ContactInstructions>During hours of service.  Off on weekends.</ows20:ContactInstructions>
+      </ows20:ContactInfo>
+      <ows20:Role codeSpace="ISOTC211/19115">pointOfContact</ows20:Role>
+    </ows20:ServiceContact>
+  </ows20:ServiceProvider>
+  <ows20:OperationsMetadata>
+    <ows20:Operation name="GetCapabilities">
+      <ows20:DCP>
+        <ows20:HTTP>
+          <ows20:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg"/>
+          <ows20:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg"/>
+        </ows20:HTTP>
+      </ows20:DCP>
+      <ows20:Parameter name="acceptFormats">
+        <ows20:AllowedValues>
+          <ows20:Value>application/xml</ows20:Value>
+          <ows20:Value>text/xml</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Parameter name="acceptVersions">
+        <ows20:AllowedValues>
+          <ows20:Value>2.0.2</ows20:Value>
+          <ows20:Value>3.0.0</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Parameter name="sections">
+        <ows20:AllowedValues>
+          <ows20:Value>All</ows20:Value>
+          <ows20:Value>Filter_Capabilities</ows20:Value>
+          <ows20:Value>OperationsMetadata</ows20:Value>
+          <ows20:Value>ServiceIdentification</ows20:Value>
+          <ows20:Value>ServiceProvider</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+    </ows20:Operation>
+    <ows20:Operation name="GetDomain">
+      <ows20:DCP>
+        <ows20:HTTP>
+          <ows20:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg"/>
+          <ows20:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg"/>
+        </ows20:HTTP>
+      </ows20:DCP>
+      <ows20:Parameter name="ParameterName">
+        <ows20:AllowedValues>
+          <ows20:Value>GetCapabilities.acceptFormats</ows20:Value>
+          <ows20:Value>GetCapabilities.acceptVersions</ows20:Value>
+          <ows20:Value>GetCapabilities.sections</ows20:Value>
+          <ows20:Value>GetRecordById.ElementSetName</ows20:Value>
+          <ows20:Value>GetRecordById.outputFormat</ows20:Value>
+          <ows20:Value>GetRecordById.outputSchema</ows20:Value>
+          <ows20:Value>GetRecords.CONSTRAINTLANGUAGE</ows20:Value>
+          <ows20:Value>GetRecords.ElementSetName</ows20:Value>
+          <ows20:Value>GetRecords.outputFormat</ows20:Value>
+          <ows20:Value>GetRecords.outputSchema</ows20:Value>
+          <ows20:Value>GetRecords.typeNames</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+    </ows20:Operation>
+    <ows20:Operation name="GetRecords">
+      <ows20:DCP>
+        <ows20:HTTP>
+          <ows20:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg"/>
+          <ows20:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg"/>
+        </ows20:HTTP>
+      </ows20:DCP>
+      <ows20:Parameter name="CONSTRAINTLANGUAGE">
+        <ows20:AllowedValues>
+          <ows20:Value>CQL_TEXT</ows20:Value>
+          <ows20:Value>FILTER</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Parameter name="ElementSetName">
+        <ows20:AllowedValues>
+          <ows20:Value>brief</ows20:Value>
+          <ows20:Value>full</ows20:Value>
+          <ows20:Value>summary</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Parameter name="outputFormat">
+        <ows20:AllowedValues>
+          <ows20:Value>application/atom+xml</ows20:Value>
+          <ows20:Value>application/json</ows20:Value>
+          <ows20:Value>application/xml</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Parameter name="outputSchema">
+        <ows20:AllowedValues>
+          <ows20:Value>http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/</ows20:Value>
+          <ows20:Value>http://www.interlis.ch/INTERLIS2.3</ows20:Value>
+          <ows20:Value>http://www.opengis.net/cat/csw/3.0</ows20:Value>
+          <ows20:Value>http://www.opengis.net/cat/csw/csdgm</ows20:Value>
+          <ows20:Value>http://www.w3.org/2005/Atom</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Parameter name="typeNames">
+        <ows20:AllowedValues>
+          <ows20:Value>csw:Record</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Constraint name="MaxRecordDefault">
+        <ows20:AllowedValues>
+          <ows20:Value>10</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Constraint>
+      <ows20:Constraint name="OpenSearchDescriptionDocument">
+        <ows20:AllowedValues>
+          <ows20:Value>http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg?mode=opensearch&service=CSW&version=3.0.0&request=GetCapabilities</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Constraint>
+      <ows20:Constraint name="FederatedCatalogues">
+        <ows20:AllowedValues>
+          <ows20:Value>http://demo.pycsw.org/gisdata/csw</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Constraint>
+    </ows20:Operation>
+    <ows20:Operation name="GetRecordById">
+      <ows20:DCP>
+        <ows20:HTTP>
+          <ows20:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg"/>
+          <ows20:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg"/>
+        </ows20:HTTP>
+      </ows20:DCP>
+      <ows20:Parameter name="ElementSetName">
+        <ows20:AllowedValues>
+          <ows20:Value>brief</ows20:Value>
+          <ows20:Value>full</ows20:Value>
+          <ows20:Value>summary</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Parameter name="outputFormat">
+        <ows20:AllowedValues>
+          <ows20:Value>application/atom+xml</ows20:Value>
+          <ows20:Value>application/json</ows20:Value>
+          <ows20:Value>application/xml</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Parameter name="outputSchema">
+        <ows20:AllowedValues>
+          <ows20:Value>http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/</ows20:Value>
+          <ows20:Value>http://www.interlis.ch/INTERLIS2.3</ows20:Value>
+          <ows20:Value>http://www.opengis.net/cat/csw/3.0</ows20:Value>
+          <ows20:Value>http://www.opengis.net/cat/csw/csdgm</ows20:Value>
+          <ows20:Value>http://www.w3.org/2005/Atom</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+    </ows20:Operation>
+    <ows20:Operation name="GetRepositoryItem">
+      <ows20:DCP>
+        <ows20:HTTP>
+          <ows20:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg"/>
+        </ows20:HTTP>
+      </ows20:DCP>
+    </ows20:Operation>
+    <ows20:Parameter name="service">
+      <ows20:AllowedValues>
+        <ows20:Value>CSW</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Parameter>
+    <ows20:Parameter name="version">
+      <ows20:AllowedValues>
+        <ows20:Value>2.0.2</ows20:Value>
+        <ows20:Value>3.0.0</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Parameter>
+    <ows20:Constraint name="CoreQueryables">
+      <ows20:AllowedValues>
+        <ows20:Value>csw:AnyText</ows20:Value>
+        <ows20:Value>dc:contributor</ows20:Value>
+        <ows20:Value>dc:creator</ows20:Value>
+        <ows20:Value>dc:date</ows20:Value>
+        <ows20:Value>dc:format</ows20:Value>
+        <ows20:Value>dc:identifier</ows20:Value>
+        <ows20:Value>dc:language</ows20:Value>
+        <ows20:Value>dc:publisher</ows20:Value>
+        <ows20:Value>dc:relation</ows20:Value>
+        <ows20:Value>dc:rights</ows20:Value>
+        <ows20:Value>dc:source</ows20:Value>
+        <ows20:Value>dc:subject</ows20:Value>
+        <ows20:Value>dc:title</ows20:Value>
+        <ows20:Value>dc:type</ows20:Value>
+        <ows20:Value>dct:abstract</ows20:Value>
+        <ows20:Value>dct:modified</ows20:Value>
+        <ows20:Value>ows:BoundingBox</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="FederatedCatalogues">
+      <ows20:AllowedValues>
+        <ows20:Value>http://demo.pycsw.org/gisdata/csw</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="MaxRecordDefault">
+      <ows20:AllowedValues>
+        <ows20:Value>10</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="PostEncoding">
+      <ows20:AllowedValues>
+        <ows20:Value>SOAP</ows20:Value>
+        <ows20:Value>XML</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="XPathQueryables">
+      <ows20:AllowedValues>
+        <ows20:Value>allowed</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/CoreQueryables">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/CoreSortables">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/DefaultSortingAlgorithm">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Filter-CQL">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Filter-FES-KVP-Advanced">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Filter-FES-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetCapabilities-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetDomain-KVP">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetDomain-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetRecordById-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetRecords-Async-KVP">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetRecords-Async-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetRecords-Basic-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetRecords-Distributed-KVP">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetRecords-Distributed-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Harvest-Async-KVP">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Harvest-Async-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Harvest-Basic-KVP">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Harvest-Basic-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Harvest-Periodic-KVP">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Harvest-Periodic-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/OpenSearch">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/SupportedGMLVersions">
+      <ows20:AllowedValues>
+        <ows20:Value>http://www.opengis.net/gml</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Transaction">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+  </ows20:OperationsMetadata>
+  <ows20:Languages>
+    <ows20:Language>en</ows20:Language>
+  </ows20:Languages>
+  <fes20:Filter_Capabilities>
+    <fes20:Conformance>
+      <fes20:Constraint name="ImplementsQuery">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsAdHocQuery">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsFunctions">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsResourceld">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsMinStandardFilter">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsStandardFilter">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsMinSpatialFilter">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsSpatialFilter">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsMinTemporalFilter">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsTemporalFilter">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsVersionNav">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsSorting">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsExtendedOperators">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsMinimumXPath">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsSchemaElementFunc">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+    </fes20:Conformance>
+    <fes20:Id_Capabilities>
+      <fes20:ResourceIdentifier name="csw30:id"/>
+    </fes20:Id_Capabilities>
+    <fes20:Scalar_Capabilities>
+      <fes20:LogicalOperators/>
+      <fes20:ComparisonOperators>
+        <fes20:ComparisonOperator name="PropertyIsBetween"/>
+        <fes20:ComparisonOperator name="PropertyIsEqualTo"/>
+        <fes20:ComparisonOperator name="PropertyIsGreaterThan"/>
+        <fes20:ComparisonOperator name="PropertyIsGreaterThanOrEqualTo"/>
+        <fes20:ComparisonOperator name="PropertyIsLessThan"/>
+        <fes20:ComparisonOperator name="PropertyIsLessThanOrEqualTo"/>
+        <fes20:ComparisonOperator name="PropertyIsLike"/>
+        <fes20:ComparisonOperator name="PropertyIsNotEqualTo"/>
+        <fes20:ComparisonOperator name="PropertyIsNull"/>
+      </fes20:ComparisonOperators>
+    </fes20:Scalar_Capabilities>
+    <fes20:Spatial_Capabilities>
+      <fes20:GeometryOperands>
+        <fes20:GeometryOperand name="gml:Point"/>
+        <fes20:GeometryOperand name="gml:LineString"/>
+        <fes20:GeometryOperand name="gml:Polygon"/>
+        <fes20:GeometryOperand name="gml:Envelope"/>
+      </fes20:GeometryOperands>
+      <fes20:SpatialOperators>
+        <fes20:SpatialOperator name="BBOX"/>
+        <fes20:SpatialOperator name="Beyond"/>
+        <fes20:SpatialOperator name="Contains"/>
+        <fes20:SpatialOperator name="Crosses"/>
+        <fes20:SpatialOperator name="Disjoint"/>
+        <fes20:SpatialOperator name="DWithin"/>
+        <fes20:SpatialOperator name="Equals"/>
+        <fes20:SpatialOperator name="Intersects"/>
+        <fes20:SpatialOperator name="Overlaps"/>
+        <fes20:SpatialOperator name="Touches"/>
+        <fes20:SpatialOperator name="Within"/>
+      </fes20:SpatialOperators>
+    </fes20:Spatial_Capabilities>
+    <fes20:Functions>
+      <fes20:Function name="length">
+        <fes20:Returns>xs:string</fes20:Returns>
+      </fes20:Function>
+      <fes20:Function name="lower">
+        <fes20:Returns>xs:string</fes20:Returns>
+      </fes20:Function>
+      <fes20:Function name="ltrim">
+        <fes20:Returns>xs:string</fes20:Returns>
+      </fes20:Function>
+      <fes20:Function name="rtrim">
+        <fes20:Returns>xs:string</fes20:Returns>
+      </fes20:Function>
+      <fes20:Function name="trim">
+        <fes20:Returns>xs:string</fes20:Returns>
+      </fes20:Function>
+      <fes20:Function name="upper">
+        <fes20:Returns>xs:string</fes20:Returns>
+      </fes20:Function>
+    </fes20:Functions>
+  </fes20:Filter_Capabilities>
+</csw30:Capabilities>
diff --git a/tests/expected/suites_csw30_get_e7704509-3441-458f-8ef0-e333c6b6043f.xml b/tests/expected/suites_csw30_get_e7704509-3441-458f-8ef0-e333c6b6043f.xml
new file mode 100644
index 0000000..d1dbd3a
--- /dev/null
+++ b/tests/expected/suites_csw30_get_e7704509-3441-458f-8ef0-e333c6b6043f.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- PYCSW_VERSION -->
+<ows20:ExceptionReport xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:ows20="http://www.opengis.net/ows/2.0" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="3.0.0" xml:lang="en-US" xsi:schemaLocation="http://www.opengis. [...]
+  <ows20:Exception exceptionCode="NoApplicableCode" locator="elementsetname">
+    <ows20:ExceptionText>Only ONE of ElementSetName or ElementName parameter(s) is permitted</ows20:ExceptionText>
+  </ows20:Exception>
+</ows20:ExceptionReport>
diff --git a/tests/expected/suites_csw30_get_f1223a49-6d08-44ff-97fe-4c32cbbfad82.xml b/tests/expected/suites_csw30_get_f1223a49-6d08-44ff-97fe-4c32cbbfad82.xml
new file mode 100644
index 0000000..6520e52
--- /dev/null
+++ b/tests/expected/suites_csw30_get_f1223a49-6d08-44ff-97fe-4c32cbbfad82.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- PYCSW_VERSION -->
+<csw30:GetRecordsResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:csw30="http://www.opengis.net/cat/csw/3.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="3.0.0" xsi:schemaLocation="http://www.opengis.net/cat/cs [...]
+  <csw30:SearchStatus timestamp="PYCSW_TIMESTAMP"/>
+  <csw30:SearchResults expires="PYCSW_EXPIRES" nextRecord="0" numberOfRecordsMatched="1" numberOfRecordsReturned="0" recordSchema="http://www.opengis.net/cat/csw/3.0" status="subset" elementSet="summary" elapsedTime="PYCSW_ELAPSED_TIME"/>
+</csw30:GetRecordsResponse>
diff --git a/tests/expected/suites_csw30_get_f89dd4e1-3a81-4433-afd2-a3fa1bdb1e18.xml b/tests/expected/suites_csw30_get_f89dd4e1-3a81-4433-afd2-a3fa1bdb1e18.xml
new file mode 100644
index 0000000..2b52728
--- /dev/null
+++ b/tests/expected/suites_csw30_get_f89dd4e1-3a81-4433-afd2-a3fa1bdb1e18.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- PYCSW_VERSION -->
+<ows20:ExceptionReport xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:ows20="http://www.opengis.net/ows/2.0" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="3.0.0" xml:lang="en-US" xsi:schemaLocation="http://www.opengis. [...]
+  <ows20:Exception exceptionCode="InvalidParameterValue" locator="outputformat">
+    <ows20:ExceptionText>Invalid outputFormat parameter value: text/example</ows20:ExceptionText>
+  </ows20:Exception>
+</ows20:ExceptionReport>
diff --git a/tests/expected/suites_csw30_post_Exception-GetDomain-parametername-bad.xml b/tests/expected/suites_csw30_post_Exception-GetDomain-parametername-bad.xml
new file mode 100644
index 0000000..759884f
--- /dev/null
+++ b/tests/expected/suites_csw30_post_Exception-GetDomain-parametername-bad.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- PYCSW_VERSION -->
+<csw30:GetDomainResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:csw30="http://www.opengis.net/cat/csw/3.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/cat/csw/3.0 http://sche [...]
+  <csw30:DomainValues resultType="available" type="csw30:Record">
+    <csw30:ParameterName>GetRecords.outputFormat-something</csw30:ParameterName>
+  </csw30:DomainValues>
+</csw30:GetDomainResponse>
diff --git a/tests/expected/suites_csw30_post_Exception-GetDomain-valuereference-bad.xml b/tests/expected/suites_csw30_post_Exception-GetDomain-valuereference-bad.xml
new file mode 100644
index 0000000..6aa6d9a
--- /dev/null
+++ b/tests/expected/suites_csw30_post_Exception-GetDomain-valuereference-bad.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- PYCSW_VERSION -->
+<csw30:GetDomainResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:csw30="http://www.opengis.net/cat/csw/3.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/cat/csw/3.0 http://sche [...]
+  <csw30:DomainValues resultType="available" type="csw30:Record">
+    <csw30:ValueReference>dc:titlena</csw30:ValueReference>
+  </csw30:DomainValues>
+</csw30:GetDomainResponse>
diff --git a/tests/expected/suites_csw30_post_Exception-GetRecordById-404.xml b/tests/expected/suites_csw30_post_Exception-GetRecordById-404.xml
new file mode 100644
index 0000000..992d6f2
--- /dev/null
+++ b/tests/expected/suites_csw30_post_Exception-GetRecordById-404.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- PYCSW_VERSION -->
+<ows20:ExceptionReport xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:ows20="http://www.opengis.net/ows/2.0" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="3.0.0" xml:lang="en-US" xsi:schemaLocation="http://www.opengis. [...]
+  <ows20:Exception exceptionCode="NotFound" locator="id">
+    <ows20:ExceptionText>No repository item found for 'does_not_exist'</ows20:ExceptionText>
+  </ows20:Exception>
+</ows20:ExceptionReport>
diff --git a/tests/expected/suites_csw30_post_Exception-GetRecordById-bad-esn.xml b/tests/expected/suites_csw30_post_Exception-GetRecordById-bad-esn.xml
new file mode 100644
index 0000000..3b7e2b9
--- /dev/null
+++ b/tests/expected/suites_csw30_post_Exception-GetRecordById-bad-esn.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- PYCSW_VERSION -->
+<ows20:ExceptionReport xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:ows20="http://www.opengis.net/ows/2.0" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="3.0.0" xml:lang="en-US" xsi:schemaLocation="http://www.opengis. [...]
+  <ows20:Exception exceptionCode="InvalidParameterValue" locator="elementsetname">
+    <ows20:ExceptionText>Invalid elementsetname parameter bad</ows20:ExceptionText>
+  </ows20:Exception>
+</ows20:ExceptionReport>
diff --git a/tests/expected/suites_csw30_post_Exception-bad-xml.xml b/tests/expected/suites_csw30_post_Exception-bad-xml.xml
new file mode 100644
index 0000000..76e5b29
--- /dev/null
+++ b/tests/expected/suites_csw30_post_Exception-bad-xml.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- PYCSW_VERSION -->
+<ows20:ExceptionReport xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:ows20="http://www.opengis.net/ows/2.0" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="3.0.0" xml:lang="en-US" xsi:schemaLocation="http://www.opengis. [...]
+  <ows20:Exception exceptionCode="NoApplicableCode" locator="service">
+    <ows20:ExceptionText>Exception: document not well-formed.
+Error: Opening and ending tag mismatch: GetCapabilities line 2 and GetCapabilities-bad, line 9, column 29.</ows20:ExceptionText>
+  </ows20:Exception>
+</ows20:ExceptionReport>
diff --git a/tests/expected/suites_csw30_post_Exception-not-xml.xml b/tests/expected/suites_csw30_post_Exception-not-xml.xml
new file mode 100644
index 0000000..632a1d8
--- /dev/null
+++ b/tests/expected/suites_csw30_post_Exception-not-xml.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- PYCSW_VERSION -->
+<ows20:ExceptionReport xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:ows20="http://www.opengis.net/ows/2.0" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="3.0.0" xml:lang="en-US" xsi:schemaLocation="http://www.opengis. [...]
+  <ows20:Exception exceptionCode="NoApplicableCode" locator="service">
+    <ows20:ExceptionText>Exception: document not well-formed.
+Error: Start tag expected, '<' not found, line 1, column 1.</ows20:ExceptionText>
+  </ows20:Exception>
+</ows20:ExceptionReport>
diff --git a/tests/expected/suites_csw30_post_GetCapabilities.xml b/tests/expected/suites_csw30_post_GetCapabilities.xml
new file mode 100644
index 0000000..ce9c935
--- /dev/null
+++ b/tests/expected/suites_csw30_post_GetCapabilities.xml
@@ -0,0 +1,491 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- PYCSW_VERSION -->
+<csw30:Capabilities xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:csw30="http://www.opengis.net/cat/csw/3.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:fes20="http://www.opengis.net/fes/2.0" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:ows11="http://www.opengis.net/ows/1.1" xmlns:ows20="http://www.opengis.net/ows/2.0" xmlns:xlink="http://www.w3.org/199 [...]
+  <ows20:ServiceIdentification>
+    <ows20:Title>pycsw Geospatial Catalogue</ows20:Title>
+    <ows20:Abstract>pycsw is an OGC CSW server implementation written in Python</ows20:Abstract>
+    <ows20:Keywords>
+      <ows20:Keyword>catalogue</ows20:Keyword>
+      <ows20:Keyword>discovery</ows20:Keyword>
+      <ows20:Type codeSpace="ISOTC211/19115">theme</ows20:Type>
+    </ows20:Keywords>
+    <ows20:ServiceType codeSpace="OGC">CSW</ows20:ServiceType>
+    <ows20:ServiceTypeVersion>2.0.2</ows20:ServiceTypeVersion>
+    <ows20:ServiceTypeVersion>3.0.0</ows20:ServiceTypeVersion>
+    <ows20:Fees>None</ows20:Fees>
+    <ows20:AccessConstraints>None</ows20:AccessConstraints>
+  </ows20:ServiceIdentification>
+  <ows20:ServiceProvider>
+    <ows20:ProviderName>pycsw</ows20:ProviderName>
+    <ows20:ProviderSite xlink:type="simple" xlink:href="http://pycsw.org/"/>
+    <ows20:ServiceContact>
+      <ows20:IndividualName>Kralidis, Tom</ows20:IndividualName>
+      <ows20:PositionName>Senior Systems Scientist</ows20:PositionName>
+      <ows20:ContactInfo>
+        <ows20:Phone>
+          <ows20:Voice>+01-416-xxx-xxxx</ows20:Voice>
+          <ows20:Facsimile>+01-416-xxx-xxxx</ows20:Facsimile>
+        </ows20:Phone>
+        <ows20:Address>
+          <ows20:DeliveryPoint>TBA</ows20:DeliveryPoint>
+          <ows20:City>Toronto</ows20:City>
+          <ows20:AdministrativeArea>Ontario</ows20:AdministrativeArea>
+          <ows20:PostalCode>M9C 3Z9</ows20:PostalCode>
+          <ows20:Country>Canada</ows20:Country>
+          <ows20:ElectronicMailAddress>tomkralidis at gmail.com</ows20:ElectronicMailAddress>
+        </ows20:Address>
+        <ows20:OnlineResource xlink:type="simple" xlink:href="http://kralidis.ca/"/>
+        <ows20:HoursOfService>0800h - 1600h EST</ows20:HoursOfService>
+        <ows20:ContactInstructions>During hours of service.  Off on weekends.</ows20:ContactInstructions>
+      </ows20:ContactInfo>
+      <ows20:Role codeSpace="ISOTC211/19115">pointOfContact</ows20:Role>
+    </ows20:ServiceContact>
+  </ows20:ServiceProvider>
+  <ows20:OperationsMetadata>
+    <ows20:Operation name="GetCapabilities">
+      <ows20:DCP>
+        <ows20:HTTP>
+          <ows20:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg"/>
+          <ows20:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg"/>
+        </ows20:HTTP>
+      </ows20:DCP>
+      <ows20:Parameter name="acceptFormats">
+        <ows20:AllowedValues>
+          <ows20:Value>application/xml</ows20:Value>
+          <ows20:Value>text/xml</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Parameter name="acceptVersions">
+        <ows20:AllowedValues>
+          <ows20:Value>2.0.2</ows20:Value>
+          <ows20:Value>3.0.0</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Parameter name="sections">
+        <ows20:AllowedValues>
+          <ows20:Value>All</ows20:Value>
+          <ows20:Value>Filter_Capabilities</ows20:Value>
+          <ows20:Value>OperationsMetadata</ows20:Value>
+          <ows20:Value>ServiceIdentification</ows20:Value>
+          <ows20:Value>ServiceProvider</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+    </ows20:Operation>
+    <ows20:Operation name="GetDomain">
+      <ows20:DCP>
+        <ows20:HTTP>
+          <ows20:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg"/>
+          <ows20:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg"/>
+        </ows20:HTTP>
+      </ows20:DCP>
+      <ows20:Parameter name="ParameterName">
+        <ows20:AllowedValues>
+          <ows20:Value>GetCapabilities.acceptFormats</ows20:Value>
+          <ows20:Value>GetCapabilities.acceptVersions</ows20:Value>
+          <ows20:Value>GetCapabilities.sections</ows20:Value>
+          <ows20:Value>GetRecordById.ElementSetName</ows20:Value>
+          <ows20:Value>GetRecordById.outputFormat</ows20:Value>
+          <ows20:Value>GetRecordById.outputSchema</ows20:Value>
+          <ows20:Value>GetRecords.CONSTRAINTLANGUAGE</ows20:Value>
+          <ows20:Value>GetRecords.ElementSetName</ows20:Value>
+          <ows20:Value>GetRecords.outputFormat</ows20:Value>
+          <ows20:Value>GetRecords.outputSchema</ows20:Value>
+          <ows20:Value>GetRecords.typeNames</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+    </ows20:Operation>
+    <ows20:Operation name="GetRecords">
+      <ows20:DCP>
+        <ows20:HTTP>
+          <ows20:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg"/>
+          <ows20:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg"/>
+        </ows20:HTTP>
+      </ows20:DCP>
+      <ows20:Parameter name="CONSTRAINTLANGUAGE">
+        <ows20:AllowedValues>
+          <ows20:Value>CQL_TEXT</ows20:Value>
+          <ows20:Value>FILTER</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Parameter name="ElementSetName">
+        <ows20:AllowedValues>
+          <ows20:Value>brief</ows20:Value>
+          <ows20:Value>full</ows20:Value>
+          <ows20:Value>summary</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Parameter name="outputFormat">
+        <ows20:AllowedValues>
+          <ows20:Value>application/atom+xml</ows20:Value>
+          <ows20:Value>application/json</ows20:Value>
+          <ows20:Value>application/xml</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Parameter name="outputSchema">
+        <ows20:AllowedValues>
+          <ows20:Value>http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/</ows20:Value>
+          <ows20:Value>http://www.interlis.ch/INTERLIS2.3</ows20:Value>
+          <ows20:Value>http://www.opengis.net/cat/csw/3.0</ows20:Value>
+          <ows20:Value>http://www.opengis.net/cat/csw/csdgm</ows20:Value>
+          <ows20:Value>http://www.w3.org/2005/Atom</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Parameter name="typeNames">
+        <ows20:AllowedValues>
+          <ows20:Value>csw:Record</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Constraint name="MaxRecordDefault">
+        <ows20:AllowedValues>
+          <ows20:Value>10</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Constraint>
+      <ows20:Constraint name="OpenSearchDescriptionDocument">
+        <ows20:AllowedValues>
+          <ows20:Value>http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg?mode=opensearch&service=CSW&version=3.0.0&request=GetCapabilities</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Constraint>
+      <ows20:Constraint name="FederatedCatalogues">
+        <ows20:AllowedValues>
+          <ows20:Value>http://demo.pycsw.org/gisdata/csw</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Constraint>
+    </ows20:Operation>
+    <ows20:Operation name="GetRecordById">
+      <ows20:DCP>
+        <ows20:HTTP>
+          <ows20:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg"/>
+          <ows20:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg"/>
+        </ows20:HTTP>
+      </ows20:DCP>
+      <ows20:Parameter name="ElementSetName">
+        <ows20:AllowedValues>
+          <ows20:Value>brief</ows20:Value>
+          <ows20:Value>full</ows20:Value>
+          <ows20:Value>summary</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Parameter name="outputFormat">
+        <ows20:AllowedValues>
+          <ows20:Value>application/atom+xml</ows20:Value>
+          <ows20:Value>application/json</ows20:Value>
+          <ows20:Value>application/xml</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+      <ows20:Parameter name="outputSchema">
+        <ows20:AllowedValues>
+          <ows20:Value>http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/</ows20:Value>
+          <ows20:Value>http://www.interlis.ch/INTERLIS2.3</ows20:Value>
+          <ows20:Value>http://www.opengis.net/cat/csw/3.0</ows20:Value>
+          <ows20:Value>http://www.opengis.net/cat/csw/csdgm</ows20:Value>
+          <ows20:Value>http://www.w3.org/2005/Atom</ows20:Value>
+        </ows20:AllowedValues>
+      </ows20:Parameter>
+    </ows20:Operation>
+    <ows20:Operation name="GetRepositoryItem">
+      <ows20:DCP>
+        <ows20:HTTP>
+          <ows20:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg"/>
+        </ows20:HTTP>
+      </ows20:DCP>
+    </ows20:Operation>
+    <ows20:Parameter name="service">
+      <ows20:AllowedValues>
+        <ows20:Value>CSW</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Parameter>
+    <ows20:Parameter name="version">
+      <ows20:AllowedValues>
+        <ows20:Value>2.0.2</ows20:Value>
+        <ows20:Value>3.0.0</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Parameter>
+    <ows20:Constraint name="CoreQueryables">
+      <ows20:AllowedValues>
+        <ows20:Value>csw:AnyText</ows20:Value>
+        <ows20:Value>dc:contributor</ows20:Value>
+        <ows20:Value>dc:creator</ows20:Value>
+        <ows20:Value>dc:date</ows20:Value>
+        <ows20:Value>dc:format</ows20:Value>
+        <ows20:Value>dc:identifier</ows20:Value>
+        <ows20:Value>dc:language</ows20:Value>
+        <ows20:Value>dc:publisher</ows20:Value>
+        <ows20:Value>dc:relation</ows20:Value>
+        <ows20:Value>dc:rights</ows20:Value>
+        <ows20:Value>dc:source</ows20:Value>
+        <ows20:Value>dc:subject</ows20:Value>
+        <ows20:Value>dc:title</ows20:Value>
+        <ows20:Value>dc:type</ows20:Value>
+        <ows20:Value>dct:abstract</ows20:Value>
+        <ows20:Value>dct:modified</ows20:Value>
+        <ows20:Value>ows:BoundingBox</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="FederatedCatalogues">
+      <ows20:AllowedValues>
+        <ows20:Value>http://demo.pycsw.org/gisdata/csw</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="MaxRecordDefault">
+      <ows20:AllowedValues>
+        <ows20:Value>10</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="PostEncoding">
+      <ows20:AllowedValues>
+        <ows20:Value>SOAP</ows20:Value>
+        <ows20:Value>XML</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="XPathQueryables">
+      <ows20:AllowedValues>
+        <ows20:Value>allowed</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/CoreQueryables">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/CoreSortables">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/DefaultSortingAlgorithm">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Filter-CQL">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Filter-FES-KVP-Advanced">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Filter-FES-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetCapabilities-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetDomain-KVP">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetDomain-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetRecordById-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetRecords-Async-KVP">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetRecords-Async-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetRecords-Basic-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetRecords-Distributed-KVP">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/GetRecords-Distributed-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Harvest-Async-KVP">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Harvest-Async-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Harvest-Basic-KVP">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Harvest-Basic-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Harvest-Periodic-KVP">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Harvest-Periodic-XML">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/OpenSearch">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/SupportedGMLVersions">
+      <ows20:AllowedValues>
+        <ows20:Value>http://www.opengis.net/gml</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+    <ows20:Constraint name="http://www.opengis.net/spec/csw/3.0/conf/Transaction">
+      <ows20:AllowedValues>
+        <ows20:Value>TRUE</ows20:Value>
+      </ows20:AllowedValues>
+    </ows20:Constraint>
+  </ows20:OperationsMetadata>
+  <ows20:Languages>
+    <ows20:Language>en</ows20:Language>
+  </ows20:Languages>
+  <fes20:Filter_Capabilities>
+    <fes20:Conformance>
+      <fes20:Constraint name="ImplementsQuery">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsAdHocQuery">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsFunctions">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsResourceld">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsMinStandardFilter">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsStandardFilter">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsMinSpatialFilter">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsSpatialFilter">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsMinTemporalFilter">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsTemporalFilter">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsVersionNav">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsSorting">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsExtendedOperators">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsMinimumXPath">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+      <fes20:Constraint name="ImplementsSchemaElementFunc">
+        <ows11:NoValues/>
+        <ows11:DefaultValue>TRUE</ows11:DefaultValue>
+      </fes20:Constraint>
+    </fes20:Conformance>
+    <fes20:Id_Capabilities>
+      <fes20:ResourceIdentifier name="csw30:id"/>
+    </fes20:Id_Capabilities>
+    <fes20:Scalar_Capabilities>
+      <fes20:LogicalOperators/>
+      <fes20:ComparisonOperators>
+        <fes20:ComparisonOperator name="PropertyIsBetween"/>
+        <fes20:ComparisonOperator name="PropertyIsEqualTo"/>
+        <fes20:ComparisonOperator name="PropertyIsGreaterThan"/>
+        <fes20:ComparisonOperator name="PropertyIsGreaterThanOrEqualTo"/>
+        <fes20:ComparisonOperator name="PropertyIsLessThan"/>
+        <fes20:ComparisonOperator name="PropertyIsLessThanOrEqualTo"/>
+        <fes20:ComparisonOperator name="PropertyIsLike"/>
+        <fes20:ComparisonOperator name="PropertyIsNotEqualTo"/>
+        <fes20:ComparisonOperator name="PropertyIsNull"/>
+      </fes20:ComparisonOperators>
+    </fes20:Scalar_Capabilities>
+    <fes20:Spatial_Capabilities>
+      <fes20:GeometryOperands>
+        <fes20:GeometryOperand name="gml:Point"/>
+        <fes20:GeometryOperand name="gml:LineString"/>
+        <fes20:GeometryOperand name="gml:Polygon"/>
+        <fes20:GeometryOperand name="gml:Envelope"/>
+      </fes20:GeometryOperands>
+      <fes20:SpatialOperators>
+        <fes20:SpatialOperator name="BBOX"/>
+        <fes20:SpatialOperator name="Beyond"/>
+        <fes20:SpatialOperator name="Contains"/>
+        <fes20:SpatialOperator name="Crosses"/>
+        <fes20:SpatialOperator name="Disjoint"/>
+        <fes20:SpatialOperator name="DWithin"/>
+        <fes20:SpatialOperator name="Equals"/>
+        <fes20:SpatialOperator name="Intersects"/>
+        <fes20:SpatialOperator name="Overlaps"/>
+        <fes20:SpatialOperator name="Touches"/>
+        <fes20:SpatialOperator name="Within"/>
+      </fes20:SpatialOperators>
+    </fes20:Spatial_Capabilities>
+    <fes20:Functions>
+      <fes20:Function name="length">
+        <fes20:Returns>xs:string</fes20:Returns>
+      </fes20:Function>
+      <fes20:Function name="lower">
+        <fes20:Returns>xs:string</fes20:Returns>
+      </fes20:Function>
+      <fes20:Function name="ltrim">
+        <fes20:Returns>xs:string</fes20:Returns>
+      </fes20:Function>
+      <fes20:Function name="rtrim">
+        <fes20:Returns>xs:string</fes20:Returns>
+      </fes20:Function>
+      <fes20:Function name="trim">
+        <fes20:Returns>xs:string</fes20:Returns>
+      </fes20:Function>
+      <fes20:Function name="upper">
+        <fes20:Returns>xs:string</fes20:Returns>
+      </fes20:Function>
+    </fes20:Functions>
+  </fes20:Filter_Capabilities>
+</csw30:Capabilities>
diff --git a/tests/expected/suites_csw30_post_GetDomain-parametername.xml b/tests/expected/suites_csw30_post_GetDomain-parametername.xml
new file mode 100644
index 0000000..d9cd1c6
--- /dev/null
+++ b/tests/expected/suites_csw30_post_GetDomain-parametername.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- PYCSW_VERSION -->
+<csw30:GetDomainResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:csw30="http://www.opengis.net/cat/csw/3.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/cat/csw/3.0 http://sche [...]
+  <csw30:DomainValues resultType="available" type="csw30:Record">
+    <csw30:ParameterName>GetRecords.outputFormat</csw30:ParameterName>
+    <csw30:ListOfValues>
+      <csw30:Value>application/atom+xml</csw30:Value>
+      <csw30:Value>application/json</csw30:Value>
+      <csw30:Value>application/xml</csw30:Value>
+    </csw30:ListOfValues>
+  </csw30:DomainValues>
+</csw30:GetDomainResponse>
diff --git a/tests/expected/suites_csw30_post_GetDomain-valuereference.xml b/tests/expected/suites_csw30_post_GetDomain-valuereference.xml
new file mode 100644
index 0000000..3775ee2
--- /dev/null
+++ b/tests/expected/suites_csw30_post_GetDomain-valuereference.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- PYCSW_VERSION -->
+<csw30:GetDomainResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:csw30="http://www.opengis.net/cat/csw/3.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/cat/csw/3.0 http://sche [...]
+  <csw30:DomainValues resultType="available" type="csw30:Record">
+    <csw30:ValueReference>dc:title</csw30:ValueReference>
+    <csw30:ListOfValues>
+      <csw30:Value count="1">Aliquam fermentum purus quis arcu</csw30:Value>
+      <csw30:Value count="1">Fuscé vitae ligulä</csw30:Value>
+      <csw30:Value count="1">Lorem ipsum</csw30:Value>
+      <csw30:Value count="1">Lorem ipsum dolor sit amet</csw30:Value>
+      <csw30:Value count="1">Maecenas enim</csw30:Value>
+      <csw30:Value count="1">Mauris sed neque</csw30:Value>
+      <csw30:Value count="1">Ut facilisis justo ut lacus</csw30:Value>
+      <csw30:Value count="1">Vestibulum massa purus</csw30:Value>
+      <csw30:Value count="1">Ñunç elementum</csw30:Value>
+    </csw30:ListOfValues>
+  </csw30:DomainValues>
+</csw30:GetDomainResponse>
diff --git a/tests/expected/suites_csw30_post_GetRecordById-dc-full.xml b/tests/expected/suites_csw30_post_GetRecordById-dc-full.xml
new file mode 100644
index 0000000..ae4a178
--- /dev/null
+++ b/tests/expected/suites_csw30_post_GetRecordById-dc-full.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- PYCSW_VERSION -->
+<csw30:Record xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:csw30="http://www.opengis.net/cat/csw/3.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema">
+  <dc:identifier>urn:uuid:19887a8a-f6b0-4a63-ae56-7fba0e17801f</dc:identifier>
+  <dc:title>Lorem ipsum</dc:title>
+  <dc:type>http://purl.org/dc/dcmitype/Image</dc:type>
+  <dc:subject>Tourism--Greece</dc:subject>
+  <dc:format>image/svg+xml</dc:format>
+  <dct:abstract>Quisque lacus diam, placerat mollis, pharetra in, commodo sed, augue. Duis iaculis arcu vel arcu.</dct:abstract>
+</csw30:Record>
diff --git a/tests/expected/suites_csw30_post_GetRecordById-dc.xml b/tests/expected/suites_csw30_post_GetRecordById-dc.xml
new file mode 100644
index 0000000..731f3ba
--- /dev/null
+++ b/tests/expected/suites_csw30_post_GetRecordById-dc.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- PYCSW_VERSION -->
+<csw30:SummaryRecord xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:csw30="http://www.opengis.net/cat/csw/3.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema">
+  <dc:identifier>urn:uuid:19887a8a-f6b0-4a63-ae56-7fba0e17801f</dc:identifier>
+  <dc:title>Lorem ipsum</dc:title>
+  <dc:type>http://purl.org/dc/dcmitype/Image</dc:type>
+  <dc:subject>Tourism--Greece</dc:subject>
+  <dc:format>image/svg+xml</dc:format>
+  <dct:abstract>Quisque lacus diam, placerat mollis, pharetra in, commodo sed, augue. Duis iaculis arcu vel arcu.</dct:abstract>
+</csw30:SummaryRecord>
diff --git a/tests/expected/suites_default_get_Exception-GetRepositoryItem-notfound.xml b/tests/expected/suites_default_get_Exception-GetRepositoryItem-notfound.xml
new file mode 100644
index 0000000..5607c75
--- /dev/null
+++ b/tests/expected/suites_default_get_Exception-GetRepositoryItem-notfound.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- PYCSW_VERSION -->
+<ows:ExceptionReport xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" language="en-US" version="1.2.0" xsi:schemaLocation="http://www.opengis.net/ows http://schemas.opengis.net/ows/1.0.0/ow [...]
+  <ows:Exception exceptionCode="NotFound" locator="id">
+    <ows:ExceptionText>No repository item found for '['NOTFOUND']'</ows:ExceptionText>
+  </ows:Exception>
+</ows:ExceptionReport>
diff --git a/tests/expected/suites_default_get_GetCapabilities-invalid-request.xml b/tests/expected/suites_default_get_GetCapabilities-invalid-request.xml
index 57576eb..03450eb 100644
--- a/tests/expected/suites_default_get_GetCapabilities-invalid-request.xml
+++ b/tests/expected/suites_default_get_GetCapabilities-invalid-request.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<ows:ExceptionReport xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ows="http://www.opengis.net/ows" xmlns:fgdc="http://www.opengis.net/cat/csw/csdgm"  [...]
+<ows:ExceptionReport xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" language="en-US" version="1.2.0" xsi:schemaLocation="http://www.opengis.net/ows http://schemas.opengis.net/ows/1.0.0/ow [...]
   <ows:Exception exceptionCode="InvalidParameterValue" locator="request">
     <ows:ExceptionText>Invalid value for request: GetCapabilitiese</ows:ExceptionText>
   </ows:Exception>
diff --git a/tests/expected/suites_default_get_GetCapabilities.xml b/tests/expected/suites_default_get_GetCapabilities.xml
index 2172598..8026e1b 100644
--- a/tests/expected/suites_default_get_GetCapabilities.xml
+++ b/tests/expected/suites_default_get_GetCapabilities.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<csw:Capabilities xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ows="http://www.opengis.net/ows" xmlns:fgdc="http://www.opengis.net/cat/csw/csdgm" xml [...]
+<csw:Capabilities xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ogc="http://www.opengis.net/ogc" xmlns:ows="http://www.opengis.net/ows" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" updateSequence="PYCSW_UPDATESEQUENCE" ve [...]
   <ows:ServiceIdentification>
     <ows:Title>pycsw Geospatial Catalogue</ows:Title>
     <ows:Abstract>pycsw is an OGC CSW server implementation written in Python</ows:Abstract>
@@ -11,6 +11,7 @@
     </ows:Keywords>
     <ows:ServiceType codeSpace="OGC">CSW</ows:ServiceType>
     <ows:ServiceTypeVersion>2.0.2</ows:ServiceTypeVersion>
+    <ows:ServiceTypeVersion>3.0.0</ows:ServiceTypeVersion>
     <ows:Fees>None</ows:Fees>
     <ows:AccessConstraints>None</ows:AccessConstraints>
   </ows:ServiceIdentification>
@@ -49,19 +50,12 @@
         </ows:HTTP>
       </ows:DCP>
       <ows:Parameter name="sections">
+        <ows:Value>Filter_Capabilities</ows:Value>
+        <ows:Value>OperationsMetadata</ows:Value>
         <ows:Value>ServiceIdentification</ows:Value>
         <ows:Value>ServiceProvider</ows:Value>
-        <ows:Value>OperationsMetadata</ows:Value>
-        <ows:Value>Filter_Capabilities</ows:Value>
       </ows:Parameter>
     </ows:Operation>
-    <ows:Operation name="GetRepositoryItem">
-      <ows:DCP>
-        <ows:HTTP>
-          <ows:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/default/default.cfg"/>
-        </ows:HTTP>
-      </ows:DCP>
-    </ows:Operation>
     <ows:Operation name="DescribeRecord">
       <ows:DCP>
         <ows:HTTP>
@@ -69,14 +63,14 @@
           <ows:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/default/default.cfg"/>
         </ows:HTTP>
       </ows:DCP>
-      <ows:Parameter name="schemaLanguage">
-        <ows:Value>http://www.w3.org/XML/Schema</ows:Value>
-        <ows:Value>http://www.w3.org/TR/xmlschema-1/</ows:Value>
-        <ows:Value>http://www.w3.org/2001/XMLSchema</ows:Value>
-      </ows:Parameter>
       <ows:Parameter name="outputFormat">
-        <ows:Value>application/xml</ows:Value>
         <ows:Value>application/json</ows:Value>
+        <ows:Value>application/xml</ows:Value>
+      </ows:Parameter>
+      <ows:Parameter name="schemaLanguage">
+        <ows:Value>http://www.w3.org/2001/XMLSchema</ows:Value>
+        <ows:Value>http://www.w3.org/TR/xmlschema-1/</ows:Value>
+        <ows:Value>http://www.w3.org/XML/Schema</ows:Value>
       </ows:Parameter>
       <ows:Parameter name="typeName">
         <ows:Value>csw:Record</ows:Value>
@@ -90,64 +84,47 @@
         </ows:HTTP>
       </ows:DCP>
       <ows:Parameter name="ParameterName">
+        <ows:Value>DescribeRecord.outputFormat</ows:Value>
+        <ows:Value>DescribeRecord.schemaLanguage</ows:Value>
+        <ows:Value>DescribeRecord.typeName</ows:Value>
+        <ows:Value>GetCapabilities.sections</ows:Value>
+        <ows:Value>GetRecordById.ElementSetName</ows:Value>
+        <ows:Value>GetRecordById.outputFormat</ows:Value>
+        <ows:Value>GetRecordById.outputSchema</ows:Value>
+        <ows:Value>GetRecords.CONSTRAINTLANGUAGE</ows:Value>
+        <ows:Value>GetRecords.ElementSetName</ows:Value>
         <ows:Value>GetRecords.outputFormat</ows:Value>
         <ows:Value>GetRecords.outputSchema</ows:Value>
-        <ows:Value>GetRecords.CONSTRAINTLANGUAGE</ows:Value>
         <ows:Value>GetRecords.resultType</ows:Value>
         <ows:Value>GetRecords.typeNames</ows:Value>
-        <ows:Value>GetRecords.ElementSetName</ows:Value>
-        <ows:Value>GetCapabilities.sections</ows:Value>
-        <ows:Value>GetRecordById.outputFormat</ows:Value>
-        <ows:Value>GetRecordById.outputSchema</ows:Value>
-        <ows:Value>GetRecordById.ElementSetName</ows:Value>
-        <ows:Value>DescribeRecord.schemaLanguage</ows:Value>
-        <ows:Value>DescribeRecord.outputFormat</ows:Value>
-        <ows:Value>DescribeRecord.typeName</ows:Value>
       </ows:Parameter>
     </ows:Operation>
-    <ows:Operation name="GetRecordById">
+    <ows:Operation name="GetRecords">
       <ows:DCP>
         <ows:HTTP>
           <ows:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/default/default.cfg"/>
           <ows:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/default/default.cfg"/>
         </ows:HTTP>
       </ows:DCP>
-      <ows:Parameter name="outputFormat">
-        <ows:Value>application/xml</ows:Value>
-        <ows:Value>application/json</ows:Value>
-      </ows:Parameter>
-      <ows:Parameter name="outputSchema">
-        <ows:Value>http://www.opengis.net/cat/csw/2.0.2</ows:Value>
-        <ows:Value>http://www.w3.org/2005/Atom</ows:Value>
-        <ows:Value>http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/</ows:Value>
-        <ows:Value>http://www.opengis.net/cat/csw/csdgm</ows:Value>
+      <ows:Parameter name="CONSTRAINTLANGUAGE">
+        <ows:Value>CQL_TEXT</ows:Value>
+        <ows:Value>FILTER</ows:Value>
       </ows:Parameter>
       <ows:Parameter name="ElementSetName">
         <ows:Value>brief</ows:Value>
-        <ows:Value>summary</ows:Value>
         <ows:Value>full</ows:Value>
+        <ows:Value>summary</ows:Value>
       </ows:Parameter>
-    </ows:Operation>
-    <ows:Operation name="GetRecords">
-      <ows:DCP>
-        <ows:HTTP>
-          <ows:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/default/default.cfg"/>
-          <ows:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/default/default.cfg"/>
-        </ows:HTTP>
-      </ows:DCP>
       <ows:Parameter name="outputFormat">
-        <ows:Value>application/xml</ows:Value>
         <ows:Value>application/json</ows:Value>
+        <ows:Value>application/xml</ows:Value>
       </ows:Parameter>
       <ows:Parameter name="outputSchema">
-        <ows:Value>http://www.opengis.net/cat/csw/2.0.2</ows:Value>
-        <ows:Value>http://www.w3.org/2005/Atom</ows:Value>
         <ows:Value>http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/</ows:Value>
+        <ows:Value>http://www.interlis.ch/INTERLIS2.3</ows:Value>
+        <ows:Value>http://www.opengis.net/cat/csw/2.0.2</ows:Value>
         <ows:Value>http://www.opengis.net/cat/csw/csdgm</ows:Value>
-      </ows:Parameter>
-      <ows:Parameter name="CONSTRAINTLANGUAGE">
-        <ows:Value>FILTER</ows:Value>
-        <ows:Value>CQL_TEXT</ows:Value>
+        <ows:Value>http://www.w3.org/2005/Atom</ows:Value>
       </ows:Parameter>
       <ows:Parameter name="resultType">
         <ows:Value>hits</ows:Value>
@@ -157,39 +134,66 @@
       <ows:Parameter name="typeNames">
         <ows:Value>csw:Record</ows:Value>
       </ows:Parameter>
-      <ows:Parameter name="ElementSetName">
-        <ows:Value>brief</ows:Value>
-        <ows:Value>summary</ows:Value>
-        <ows:Value>full</ows:Value>
-      </ows:Parameter>
       <ows:Constraint name="SupportedDublinCoreQueryables">
+        <ows:Value>csw:AnyText</ows:Value>
         <ows:Value>dc:contributor</ows:Value>
-        <ows:Value>dc:source</ows:Value>
-        <ows:Value>dc:language</ows:Value>
-        <ows:Value>dc:title</ows:Value>
-        <ows:Value>dc:subject</ows:Value>
         <ows:Value>dc:creator</ows:Value>
-        <ows:Value>dc:type</ows:Value>
-        <ows:Value>ows:BoundingBox</ows:Value>
-        <ows:Value>dct:modified</ows:Value>
-        <ows:Value>dct:abstract</ows:Value>
-        <ows:Value>dc:relation</ows:Value>
         <ows:Value>dc:date</ows:Value>
+        <ows:Value>dc:format</ows:Value>
         <ows:Value>dc:identifier</ows:Value>
+        <ows:Value>dc:language</ows:Value>
         <ows:Value>dc:publisher</ows:Value>
-        <ows:Value>dc:format</ows:Value>
-        <ows:Value>csw:AnyText</ows:Value>
+        <ows:Value>dc:relation</ows:Value>
         <ows:Value>dc:rights</ows:Value>
+        <ows:Value>dc:source</ows:Value>
+        <ows:Value>dc:subject</ows:Value>
+        <ows:Value>dc:title</ows:Value>
+        <ows:Value>dc:type</ows:Value>
+        <ows:Value>dct:abstract</ows:Value>
+        <ows:Value>dct:modified</ows:Value>
+        <ows:Value>ows:BoundingBox</ows:Value>
       </ows:Constraint>
     </ows:Operation>
-    <ows:Parameter name="version">
-      <ows:Value>2.0.2</ows:Value>
-    </ows:Parameter>
+    <ows:Operation name="GetRecordById">
+      <ows:DCP>
+        <ows:HTTP>
+          <ows:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/default/default.cfg"/>
+          <ows:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/default/default.cfg"/>
+        </ows:HTTP>
+      </ows:DCP>
+      <ows:Parameter name="ElementSetName">
+        <ows:Value>brief</ows:Value>
+        <ows:Value>full</ows:Value>
+        <ows:Value>summary</ows:Value>
+      </ows:Parameter>
+      <ows:Parameter name="outputFormat">
+        <ows:Value>application/json</ows:Value>
+        <ows:Value>application/xml</ows:Value>
+      </ows:Parameter>
+      <ows:Parameter name="outputSchema">
+        <ows:Value>http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/</ows:Value>
+        <ows:Value>http://www.interlis.ch/INTERLIS2.3</ows:Value>
+        <ows:Value>http://www.opengis.net/cat/csw/2.0.2</ows:Value>
+        <ows:Value>http://www.opengis.net/cat/csw/csdgm</ows:Value>
+        <ows:Value>http://www.w3.org/2005/Atom</ows:Value>
+      </ows:Parameter>
+    </ows:Operation>
+    <ows:Operation name="GetRepositoryItem">
+      <ows:DCP>
+        <ows:HTTP>
+          <ows:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/default/default.cfg"/>
+        </ows:HTTP>
+      </ows:DCP>
+    </ows:Operation>
     <ows:Parameter name="service">
       <ows:Value>CSW</ows:Value>
     </ows:Parameter>
-    <ows:Constraint name="XPathQueryables">
-      <ows:Value>allowed</ows:Value>
+    <ows:Parameter name="version">
+      <ows:Value>2.0.2</ows:Value>
+      <ows:Value>3.0.0</ows:Value>
+    </ows:Parameter>
+    <ows:Constraint name="FederatedCatalogues">
+      <ows:Value>http://demo.pycsw.org/gisdata/csw</ows:Value>
     </ows:Constraint>
     <ows:Constraint name="MaxRecordDefault">
       <ows:Value>10</ows:Value>
@@ -198,8 +202,8 @@
       <ows:Value>XML</ows:Value>
       <ows:Value>SOAP</ows:Value>
     </ows:Constraint>
-    <ows:Constraint name="FederatedCatalogues">
-      <ows:Value>http://demo.pycsw.org/gisdata/csw</ows:Value>
+    <ows:Constraint name="XPathQueryables">
+      <ows:Value>allowed</ows:Value>
     </ows:Constraint>
   </ows:OperationsMetadata>
   <ogc:Filter_Capabilities>
@@ -229,11 +233,11 @@
       <ogc:ComparisonOperators>
         <ogc:ComparisonOperator>Between</ogc:ComparisonOperator>
         <ogc:ComparisonOperator>EqualTo</ogc:ComparisonOperator>
-        <ogc:ComparisonOperator>LessThanEqualTo</ogc:ComparisonOperator>
         <ogc:ComparisonOperator>GreaterThan</ogc:ComparisonOperator>
-        <ogc:ComparisonOperator>Like</ogc:ComparisonOperator>
-        <ogc:ComparisonOperator>LessThan</ogc:ComparisonOperator>
         <ogc:ComparisonOperator>GreaterThanEqualTo</ogc:ComparisonOperator>
+        <ogc:ComparisonOperator>LessThan</ogc:ComparisonOperator>
+        <ogc:ComparisonOperator>LessThanEqualTo</ogc:ComparisonOperator>
+        <ogc:ComparisonOperator>Like</ogc:ComparisonOperator>
         <ogc:ComparisonOperator>NotEqualTo</ogc:ComparisonOperator>
         <ogc:ComparisonOperator>NullCheck</ogc:ComparisonOperator>
       </ogc:ComparisonOperators>
diff --git a/tests/expected/suites_default_get_GetRecords-all.xml b/tests/expected/suites_default_get_GetRecords-all.xml
index 41e198c..9b45c78 100644
--- a/tests/expected/suites_default_get_GetRecords-all.xml
+++ b/tests/expected/suites_default_get_GetRecords-all.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<csw:GetRecordsResponse xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ows="http://www.opengis.net/ows" xmlns:fgdc="http://www.opengis.net/cat/csw/csdg [...]
+<csw:GetRecordsResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.0.2" xsi:schemaLocation="http://www.opengis.net/cat/csw/2.0.2 http://schemas.opengis.net/csw/2.0.2/CSW-di [...]
   <csw:SearchStatus timestamp="PYCSW_TIMESTAMP"/>
   <csw:SearchResults nextRecord="11" numberOfRecordsMatched="12" numberOfRecordsReturned="10" recordSchema="http://www.opengis.net/cat/csw/2.0.2" elementSet="full"/>
 </csw:GetRecordsResponse>
diff --git a/tests/expected/suites_default_get_GetRecords-empty-maxrecords.xml b/tests/expected/suites_default_get_GetRecords-empty-maxrecords.xml
new file mode 100644
index 0000000..9b45c78
--- /dev/null
+++ b/tests/expected/suites_default_get_GetRecords-empty-maxrecords.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- PYCSW_VERSION -->
+<csw:GetRecordsResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.0.2" xsi:schemaLocation="http://www.opengis.net/cat/csw/2.0.2 http://schemas.opengis.net/csw/2.0.2/CSW-di [...]
+  <csw:SearchStatus timestamp="PYCSW_TIMESTAMP"/>
+  <csw:SearchResults nextRecord="11" numberOfRecordsMatched="12" numberOfRecordsReturned="10" recordSchema="http://www.opengis.net/cat/csw/2.0.2" elementSet="full"/>
+</csw:GetRecordsResponse>
diff --git a/tests/expected/suites_default_get_GetRecords-filter.xml b/tests/expected/suites_default_get_GetRecords-filter.xml
index 25e208e..163bcd6 100644
--- a/tests/expected/suites_default_get_GetRecords-filter.xml
+++ b/tests/expected/suites_default_get_GetRecords-filter.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<csw:GetRecordsResponse xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ows="http://www.opengis.net/ows" xmlns:fgdc="http://www.opengis.net/cat/csw/csdg [...]
+<csw:GetRecordsResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.0.2" xsi:schemaLocation="http://www.opengis.net/cat/csw/2.0.2 http://schemas.opengis.net/csw/2.0.2/CSW-di [...]
   <csw:SearchStatus timestamp="PYCSW_TIMESTAMP"/>
   <csw:SearchResults nextRecord="0" numberOfRecordsMatched="1" numberOfRecordsReturned="1" recordSchema="http://www.opengis.net/cat/csw/2.0.2" elementSet="full">
     <csw:Record>
diff --git a/tests/expected/suites_default_get_GetRecords-sortby-asc.xml b/tests/expected/suites_default_get_GetRecords-sortby-asc.xml
index d8910e3..9a5c0f9 100644
--- a/tests/expected/suites_default_get_GetRecords-sortby-asc.xml
+++ b/tests/expected/suites_default_get_GetRecords-sortby-asc.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<csw:GetRecordsResponse xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ows="http://www.opengis.net/ows" xmlns:fgdc="http://www.opengis.net/cat/csw/csdg [...]
+<csw:GetRecordsResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.0.2" xsi:schemaLocation="http://www.opengis.net/cat/csw/2.0.2 http://schemas.opengis.net/csw/2.0.2/CSW-di [...]
   <csw:SearchStatus timestamp="PYCSW_TIMESTAMP"/>
   <csw:SearchResults nextRecord="11" numberOfRecordsMatched="12" numberOfRecordsReturned="10" recordSchema="http://www.opengis.net/cat/csw/2.0.2" elementSet="full">
     <csw:Record>
diff --git a/tests/expected/suites_default_get_GetRecords-sortby-desc.xml b/tests/expected/suites_default_get_GetRecords-sortby-desc.xml
index 6a9ff42..1bf8d4e 100644
--- a/tests/expected/suites_default_get_GetRecords-sortby-desc.xml
+++ b/tests/expected/suites_default_get_GetRecords-sortby-desc.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<csw:GetRecordsResponse xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ows="http://www.opengis.net/ows" xmlns:fgdc="http://www.opengis.net/cat/csw/csdg [...]
+<csw:GetRecordsResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.0.2" xsi:schemaLocation="http://www.opengis.net/cat/csw/2.0.2 http://schemas.opengis.net/csw/2.0.2/CSW-di [...]
   <csw:SearchStatus timestamp="PYCSW_TIMESTAMP"/>
   <csw:SearchResults nextRecord="11" numberOfRecordsMatched="12" numberOfRecordsReturned="10" recordSchema="http://www.opengis.net/cat/csw/2.0.2" elementSet="full">
     <csw:Record>
diff --git a/tests/expected/suites_default_get_GetRecords-sortby-invalid-order.xml b/tests/expected/suites_default_get_GetRecords-sortby-invalid-order.xml
index f03af88..85457f6 100644
--- a/tests/expected/suites_default_get_GetRecords-sortby-invalid-order.xml
+++ b/tests/expected/suites_default_get_GetRecords-sortby-invalid-order.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<ows:ExceptionReport xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ows="http://www.opengis.net/ows" xmlns:fgdc="http://www.opengis.net/cat/csw/csdgm"  [...]
+<ows:ExceptionReport xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" language="en-US" version="1.2.0" xsi:schemaLocation="http://www.opengis.net/ows http://schemas.opengis.net/ows/1.0.0/ow [...]
   <ows:Exception exceptionCode="InvalidParameterValue" locator="sortby">
     <ows:ExceptionText>Invalid SortBy value: sort order must be "A" or "D"</ows:ExceptionText>
   </ows:Exception>
diff --git a/tests/expected/suites_default_get_GetRecords-sortby-invalid-propertyname.xml b/tests/expected/suites_default_get_GetRecords-sortby-invalid-propertyname.xml
index d289193..25c7b6f 100644
--- a/tests/expected/suites_default_get_GetRecords-sortby-invalid-propertyname.xml
+++ b/tests/expected/suites_default_get_GetRecords-sortby-invalid-propertyname.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<ows:ExceptionReport xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ows="http://www.opengis.net/ows" xmlns:fgdc="http://www.opengis.net/cat/csw/csdgm"  [...]
+<ows:ExceptionReport xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" language="en-US" version="1.2.0" xsi:schemaLocation="http://www.opengis.net/ows http://schemas.opengis.net/ows/1.0.0/ow [...]
   <ows:Exception exceptionCode="InvalidParameterValue" locator="sortby">
     <ows:ExceptionText>Invalid SortBy propertyname: dc:titlei</ows:ExceptionText>
   </ows:Exception>
diff --git a/tests/expected/suites_default_get_GetRepositoryItem.xml b/tests/expected/suites_default_get_GetRepositoryItem.xml
new file mode 100644
index 0000000..77fae8b
--- /dev/null
+++ b/tests/expected/suites_default_get_GetRepositoryItem.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- PYCSW_VERSION -->
+<csw:Record xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:ows="http://www.opengis.net/ows" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/">
+    <dc:identifier>urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63</dc:identifier>
+    <dc:type>http://purl.org/dc/dcmitype/Dataset</dc:type>
+    <dc:title>Mauris sed neque</dc:title>
+    <dc:subject scheme="http://www.digest.org/2.1">Vegetation-Cropland</dc:subject>
+    <dct:abstract>Curabitur lacinia, ante non porta tempus, mi lorem feugiat odio, eget suscipit eros pede ac velit.</dct:abstract>
+    <dc:date>2006-03-26</dc:date>
+    <ows:BoundingBox crs="urn:x-ogc:def:crs:EPSG:6.11:4326">
+      <ows:LowerCorner>47.595 -4.097</ows:LowerCorner>
+      <ows:UpperCorner>51.217 0.889</ows:UpperCorner>
+    </ows:BoundingBox>
+</csw:Record>
diff --git a/tests/expected/suites_default_post_DescribeRecord-json.xml b/tests/expected/suites_default_post_DescribeRecord-json.xml
index 753cad5..f83952e 100644
--- a/tests/expected/suites_default_post_DescribeRecord-json.xml
+++ b/tests/expected/suites_default_post_DescribeRecord-json.xml
@@ -1,408 +1,231 @@
 {
-    "attributes": {
-        "xsi:schemaLocation": "http://www.opengis.net/cat/csw/2.0.2 http://schemas.opengis.net/csw/2.0.2/CSW-discovery.xsd"
-    }, 
-    "tag": "csw:DescribeRecordResponse", 
-    "children": [
-        {
-            "attributes": {
-                "schemaLanguage": "XMLSCHEMA", 
-                "targetNamespace": "http://www.opengis.net/cat/csw/2.0.2"
-            }, 
-            "tag": "csw:SchemaComponent", 
-            "children": [
-                {
-                    "attributes": {
-                        "version": "2.0.2 2010-01-22", 
-                        "targetNamespace": "http://www.opengis.net/cat/csw/2.0.2", 
-                        "id": "csw-record", 
-                        "elementFormDefault": "qualified"
-                    }, 
-                    "tag": "xs:schema", 
-                    "children": [
-                        {
-                            "tag": "xs:annotation", 
-                            "children": [
-                                {
-                                    "tag": "xs:appinfo", 
-                                    "children": [
-                                        {
-                                            "text": "http://schemas.opengis.net/csw/2.0.2/record.xsd", 
-                                            "tag": "dc:identifier"
-                                        }
-                                    ]
-                                }, 
-                                {
-                                    "attributes": {
-                                        "lang": "en"
-                                    }, 
-                                    "tag": "xs:documentation"
+    "csw:DescribeRecordResponse": {
+        "@http://www.w3.org/2001/XMLSchema-instance:schemaLocation": "http://www.opengis.net/cat/csw/2.0.2 http://schemas.opengis.net/csw/2.0.2/CSW-discovery.xsd",
+        "csw:SchemaComponent": {
+            "@schemaLanguage": "XMLSCHEMA",
+            "@targetNamespace": "http://www.opengis.net/cat/csw/2.0.2",
+            "xs:schema": {
+                "@id": "csw-record",
+                "@targetNamespace": "http://www.opengis.net/cat/csw/2.0.2",
+                "@elementFormDefault": "qualified",
+                "@version": "2.0.2 2010-01-22",
+                "xs:annotation": {
+                    "xs:appinfo": {
+                        "dc:identifier": "http://schemas.opengis.net/csw/2.0.2/record.xsd"
+                    },
+                    "xs:documentation": {
+                        "@http://www.w3.org/XML/1998/namespace:lang": "en",
+                        "#text": "This schema defines the basic record types that must be supported\n         by all CSW implementations. These correspond to full, summary, and\n         brief views based on DCMI metadata terms.\n         \n         CSW is an OGC Standard.\n         Copyright (c) 2004,2010 Open Geospatial Consortium, Inc. All Rights Reserved.\n         To obtain additional rights of use, visit http://www.opengeospatial.org/legal/ ."
+                    }
+                },
+                "xs:import": [
+                    {
+                        "@namespace": "http://purl.org/dc/terms/",
+                        "@schemaLocation": "rec-dcterms.xsd"
+                    },
+                    {
+                        "@namespace": "http://purl.org/dc/elements/1.1/",
+                        "@schemaLocation": "rec-dcmes.xsd"
+                    },
+                    {
+                        "@namespace": "http://www.opengis.net/ows",
+                        "@schemaLocation": "../../ows/1.0.0/owsAll.xsd"
+                    }
+                ],
+                "xs:element": [
+                    {
+                        "@name": "AbstractRecord",
+                        "@id": "AbstractRecord",
+                        "@type": "csw:AbstractRecordType",
+                        "@abstract": "true"
+                    },
+                    {
+                        "@name": "DCMIRecord",
+                        "@type": "csw:DCMIRecordType",
+                        "@substitutionGroup": "csw:AbstractRecord"
+                    },
+                    {
+                        "@name": "BriefRecord",
+                        "@type": "csw:BriefRecordType",
+                        "@substitutionGroup": "csw:AbstractRecord"
+                    },
+                    {
+                        "@name": "SummaryRecord",
+                        "@type": "csw:SummaryRecordType",
+                        "@substitutionGroup": "csw:AbstractRecord"
+                    },
+                    {
+                        "@name": "Record",
+                        "@type": "csw:RecordType",
+                        "@substitutionGroup": "csw:AbstractRecord"
+                    }
+                ],
+                "xs:complexType": [
+                    {
+                        "@name": "AbstractRecordType",
+                        "@id": "AbstractRecordType",
+                        "@abstract": "true"
+                    },
+                    {
+                        "@name": "DCMIRecordType",
+                        "xs:annotation": {
+                            "xs:documentation": {
+                                "@http://www.w3.org/XML/1998/namespace:lang": "en",
+                                "#text": "This type encapsulates all of the standard DCMI metadata terms,\n            including the Dublin Core refinements; these terms may be mapped\n            to the profile-specific information model."
+                            }
+                        },
+                        "xs:complexContent": {
+                            "xs:extension": {
+                                "@base": "csw:AbstractRecordType",
+                                "xs:sequence": {
+                                    "xs:group": {
+                                        "@ref": "dct:DCMI-terms"
+                                    }
                                 }
-                            ]
-                        }, 
-                        {
-                            "attributes": {
-                                "schemaLocation": "rec-dcterms.xsd", 
-                                "namespace": "http://purl.org/dc/terms/"
-                            }, 
-                            "tag": "xs:import"
-                        }, 
-                        {
-                            "attributes": {
-                                "schemaLocation": "rec-dcmes.xsd", 
-                                "namespace": "http://purl.org/dc/elements/1.1/"
-                            }, 
-                            "tag": "xs:import"
-                        }, 
-                        {
-                            "attributes": {
-                                "schemaLocation": "../../ows/1.0.0/owsAll.xsd", 
-                                "namespace": "http://www.opengis.net/ows"
-                            }, 
-                            "tag": "xs:import"
-                        }, 
-                        {
-                            "attributes": {
-                                "abstract": "true", 
-                                "type": "csw:AbstractRecordType", 
-                                "name": "AbstractRecord", 
-                                "id": "AbstractRecord"
-                            }, 
-                            "tag": "xs:element"
-                        }, 
-                        {
-                            "attributes": {
-                                "abstract": "true", 
-                                "name": "AbstractRecordType", 
-                                "id": "AbstractRecordType"
-                            }, 
-                            "tag": "xs:complexType"
-                        }, 
-                        {
-                            "attributes": {
-                                "substitutionGroup": "csw:AbstractRecord", 
-                                "type": "csw:DCMIRecordType", 
-                                "name": "DCMIRecord"
-                            }, 
-                            "tag": "xs:element"
-                        }, 
-                        {
-                            "attributes": {
-                                "name": "DCMIRecordType"
-                            }, 
-                            "tag": "xs:complexType", 
-                            "children": [
-                                {
-                                    "tag": "xs:annotation", 
-                                    "children": [
+                            }
+                        }
+                    },
+                    {
+                        "@name": "BriefRecordType",
+                        "@final": "#all",
+                        "xs:annotation": {
+                            "xs:documentation": {
+                                "@http://www.w3.org/XML/1998/namespace:lang": "en",
+                                "#text": "This type defines a brief representation of the common record\n            format.  It extends AbstractRecordType to include only the\n             dc:identifier and dc:type properties."
+                            }
+                        },
+                        "xs:complexContent": {
+                            "xs:extension": {
+                                "@base": "csw:AbstractRecordType",
+                                "xs:sequence": {
+                                    "xs:element": [
                                         {
-                                            "attributes": {
-                                                "lang": "en"
-                                            }, 
-                                            "tag": "xs:documentation"
-                                        }
-                                    ]
-                                }, 
-                                {
-                                    "tag": "xs:complexContent", 
-                                    "children": [
+                                            "@ref": "dc:identifier",
+                                            "@minOccurs": "1",
+                                            "@maxOccurs": "unbounded"
+                                        },
                                         {
-                                            "attributes": {
-                                                "base": "csw:AbstractRecordType"
-                                            }, 
-                                            "tag": "xs:extension", 
-                                            "children": [
-                                                {
-                                                    "tag": "xs:sequence", 
-                                                    "children": [
-                                                        {
-                                                            "attributes": {
-                                                                "ref": "dct:DCMI-terms"
-                                                            }, 
-                                                            "tag": "xs:group"
-                                                        }
-                                                    ]
-                                                }
-                                            ]
-                                        }
-                                    ]
-                                }
-                            ]
-                        }, 
-                        {
-                            "attributes": {
-                                "substitutionGroup": "csw:AbstractRecord", 
-                                "type": "csw:BriefRecordType", 
-                                "name": "BriefRecord"
-                            }, 
-                            "tag": "xs:element"
-                        }, 
-                        {
-                            "attributes": {
-                                "name": "BriefRecordType", 
-                                "final": "#all"
-                            }, 
-                            "tag": "xs:complexType", 
-                            "children": [
-                                {
-                                    "tag": "xs:annotation", 
-                                    "children": [
+                                            "@ref": "dc:title",
+                                            "@minOccurs": "1",
+                                            "@maxOccurs": "unbounded"
+                                        },
                                         {
-                                            "attributes": {
-                                                "lang": "en"
-                                            }, 
-                                            "tag": "xs:documentation"
-                                        }
-                                    ]
-                                }, 
-                                {
-                                    "tag": "xs:complexContent", 
-                                    "children": [
+                                            "@ref": "dc:type",
+                                            "@minOccurs": "0"
+                                        },
                                         {
-                                            "attributes": {
-                                                "base": "csw:AbstractRecordType"
-                                            }, 
-                                            "tag": "xs:extension", 
-                                            "children": [
-                                                {
-                                                    "tag": "xs:sequence", 
-                                                    "children": [
-                                                        {
-                                                            "attributes": {
-                                                                "maxOccurs": "unbounded", 
-                                                                "ref": "dc:identifier", 
-                                                                "minOccurs": "1"
-                                                            }, 
-                                                            "tag": "xs:element"
-                                                        }, 
-                                                        {
-                                                            "attributes": {
-                                                                "maxOccurs": "unbounded", 
-                                                                "ref": "dc:title", 
-                                                                "minOccurs": "1"
-                                                            }, 
-                                                            "tag": "xs:element"
-                                                        }, 
-                                                        {
-                                                            "attributes": {
-                                                                "ref": "dc:type", 
-                                                                "minOccurs": "0"
-                                                            }, 
-                                                            "tag": "xs:element"
-                                                        }, 
-                                                        {
-                                                            "attributes": {
-                                                                "maxOccurs": "unbounded", 
-                                                                "ref": "ows:BoundingBox", 
-                                                                "minOccurs": "0"
-                                                            }, 
-                                                            "tag": "xs:element"
-                                                        }
-                                                    ]
-                                                }
-                                            ]
+                                            "@ref": "ows:BoundingBox",
+                                            "@minOccurs": "0",
+                                            "@maxOccurs": "unbounded"
                                         }
                                     ]
                                 }
-                            ]
-                        }, 
-                        {
-                            "attributes": {
-                                "substitutionGroup": "csw:AbstractRecord", 
-                                "type": "csw:SummaryRecordType", 
-                                "name": "SummaryRecord"
-                            }, 
-                            "tag": "xs:element"
-                        }, 
-                        {
-                            "attributes": {
-                                "name": "SummaryRecordType", 
-                                "final": "#all"
-                            }, 
-                            "tag": "xs:complexType", 
-                            "children": [
-                                {
-                                    "tag": "xs:annotation", 
-                                    "children": [
+                            }
+                        }
+                    },
+                    {
+                        "@name": "SummaryRecordType",
+                        "@final": "#all",
+                        "xs:annotation": {
+                            "xs:documentation": {
+                                "@http://www.w3.org/XML/1998/namespace:lang": "en",
+                                "#text": "This type defines a summary representation of the common record\n            format.  It extends AbstractRecordType to include the core\n            properties."
+                            }
+                        },
+                        "xs:complexContent": {
+                            "xs:extension": {
+                                "@base": "csw:AbstractRecordType",
+                                "xs:sequence": {
+                                    "xs:element": [
                                         {
-                                            "attributes": {
-                                                "lang": "en"
-                                            }, 
-                                            "tag": "xs:documentation"
-                                        }
-                                    ]
-                                }, 
-                                {
-                                    "tag": "xs:complexContent", 
-                                    "children": [
+                                            "@ref": "dc:identifier",
+                                            "@minOccurs": "1",
+                                            "@maxOccurs": "unbounded"
+                                        },
+                                        {
+                                            "@ref": "dc:title",
+                                            "@minOccurs": "1",
+                                            "@maxOccurs": "unbounded"
+                                        },
+                                        {
+                                            "@ref": "dc:type",
+                                            "@minOccurs": "0"
+                                        },
+                                        {
+                                            "@ref": "dc:subject",
+                                            "@minOccurs": "0",
+                                            "@maxOccurs": "unbounded"
+                                        },
+                                        {
+                                            "@ref": "dc:format",
+                                            "@minOccurs": "0",
+                                            "@maxOccurs": "unbounded"
+                                        },
+                                        {
+                                            "@ref": "dc:relation",
+                                            "@minOccurs": "0",
+                                            "@maxOccurs": "unbounded"
+                                        },
                                         {
-                                            "attributes": {
-                                                "base": "csw:AbstractRecordType"
-                                            }, 
-                                            "tag": "xs:extension", 
-                                            "children": [
-                                                {
-                                                    "tag": "xs:sequence", 
-                                                    "children": [
-                                                        {
-                                                            "attributes": {
-                                                                "maxOccurs": "unbounded", 
-                                                                "ref": "dc:identifier", 
-                                                                "minOccurs": "1"
-                                                            }, 
-                                                            "tag": "xs:element"
-                                                        }, 
-                                                        {
-                                                            "attributes": {
-                                                                "maxOccurs": "unbounded", 
-                                                                "ref": "dc:title", 
-                                                                "minOccurs": "1"
-                                                            }, 
-                                                            "tag": "xs:element"
-                                                        }, 
-                                                        {
-                                                            "attributes": {
-                                                                "ref": "dc:type", 
-                                                                "minOccurs": "0"
-                                                            }, 
-                                                            "tag": "xs:element"
-                                                        }, 
-                                                        {
-                                                            "attributes": {
-                                                                "maxOccurs": "unbounded", 
-                                                                "ref": "dc:subject", 
-                                                                "minOccurs": "0"
-                                                            }, 
-                                                            "tag": "xs:element"
-                                                        }, 
-                                                        {
-                                                            "attributes": {
-                                                                "maxOccurs": "unbounded", 
-                                                                "ref": "dc:format", 
-                                                                "minOccurs": "0"
-                                                            }, 
-                                                            "tag": "xs:element"
-                                                        }, 
-                                                        {
-                                                            "attributes": {
-                                                                "maxOccurs": "unbounded", 
-                                                                "ref": "dc:relation", 
-                                                                "minOccurs": "0"
-                                                            }, 
-                                                            "tag": "xs:element"
-                                                        }, 
-                                                        {
-                                                            "attributes": {
-                                                                "maxOccurs": "unbounded", 
-                                                                "ref": "dct:modified", 
-                                                                "minOccurs": "0"
-                                                            }, 
-                                                            "tag": "xs:element"
-                                                        }, 
-                                                        {
-                                                            "attributes": {
-                                                                "maxOccurs": "unbounded", 
-                                                                "ref": "dct:abstract", 
-                                                                "minOccurs": "0"
-                                                            }, 
-                                                            "tag": "xs:element"
-                                                        }, 
-                                                        {
-                                                            "attributes": {
-                                                                "maxOccurs": "unbounded", 
-                                                                "ref": "dct:spatial", 
-                                                                "minOccurs": "0"
-                                                            }, 
-                                                            "tag": "xs:element"
-                                                        }, 
-                                                        {
-                                                            "attributes": {
-                                                                "maxOccurs": "unbounded", 
-                                                                "ref": "ows:BoundingBox", 
-                                                                "minOccurs": "0"
-                                                            }, 
-                                                            "tag": "xs:element"
-                                                        }
-                                                    ]
-                                                }
-                                            ]
+                                            "@ref": "dct:modified",
+                                            "@minOccurs": "0",
+                                            "@maxOccurs": "unbounded"
+                                        },
+                                        {
+                                            "@ref": "dct:abstract",
+                                            "@minOccurs": "0",
+                                            "@maxOccurs": "unbounded"
+                                        },
+                                        {
+                                            "@ref": "dct:spatial",
+                                            "@minOccurs": "0",
+                                            "@maxOccurs": "unbounded"
+                                        },
+                                        {
+                                            "@ref": "ows:BoundingBox",
+                                            "@minOccurs": "0",
+                                            "@maxOccurs": "unbounded"
                                         }
                                     ]
                                 }
-                            ]
-                        }, 
-                        {
-                            "attributes": {
-                                "substitutionGroup": "csw:AbstractRecord", 
-                                "type": "csw:RecordType", 
-                                "name": "Record"
-                            }, 
-                            "tag": "xs:element"
-                        }, 
-                        {
-                            "attributes": {
-                                "name": "RecordType", 
-                                "final": "#all"
-                            }, 
-                            "tag": "xs:complexType", 
-                            "children": [
-                                {
-                                    "tag": "xs:annotation", 
-                                    "children": [
+                            }
+                        }
+                    },
+                    {
+                        "@name": "RecordType",
+                        "@final": "#all",
+                        "xs:annotation": {
+                            "xs:documentation": {
+                                "@http://www.w3.org/XML/1998/namespace:lang": "en",
+                                "#text": "This type extends DCMIRecordType to add ows:BoundingBox;\n            it may be used to specify a spatial envelope for the\n            catalogued resource."
+                            }
+                        },
+                        "xs:complexContent": {
+                            "xs:extension": {
+                                "@base": "csw:DCMIRecordType",
+                                "xs:sequence": {
+                                    "xs:element": [
                                         {
-                                            "attributes": {
-                                                "lang": "en"
-                                            }, 
-                                            "tag": "xs:documentation"
-                                        }
-                                    ]
-                                }, 
-                                {
-                                    "tag": "xs:complexContent", 
-                                    "children": [
+                                            "@name": "AnyText",
+                                            "@type": "csw:EmptyType",
+                                            "@minOccurs": "0",
+                                            "@maxOccurs": "unbounded"
+                                        },
                                         {
-                                            "attributes": {
-                                                "base": "csw:DCMIRecordType"
-                                            }, 
-                                            "tag": "xs:extension", 
-                                            "children": [
-                                                {
-                                                    "tag": "xs:sequence", 
-                                                    "children": [
-                                                        {
-                                                            "attributes": {
-                                                                "maxOccurs": "unbounded", 
-                                                                "type": "csw:EmptyType", 
-                                                                "name": "AnyText", 
-                                                                "minOccurs": "0"
-                                                            }, 
-                                                            "tag": "xs:element"
-                                                        }, 
-                                                        {
-                                                            "attributes": {
-                                                                "maxOccurs": "unbounded", 
-                                                                "ref": "ows:BoundingBox", 
-                                                                "minOccurs": "0"
-                                                            }, 
-                                                            "tag": "xs:element"
-                                                        }
-                                                    ]
-                                                }
-                                            ]
+                                            "@ref": "ows:BoundingBox",
+                                            "@minOccurs": "0",
+                                            "@maxOccurs": "unbounded"
                                         }
                                     ]
                                 }
-                            ]
-                        }, 
-                        {
-                            "attributes": {
-                                "name": "EmptyType"
-                            }, 
-                            "tag": "xs:complexType"
+                            }
                         }
-                    ]
-                }
-            ]
+                    },
+                    {
+                        "@name": "EmptyType"
+                    }
+                ]
+            }
         }
-    ]
+    }
 }
\ No newline at end of file
diff --git a/tests/expected/suites_default_post_DescribeRecord.xml b/tests/expected/suites_default_post_DescribeRecord.xml
index 7ee77c7..76101a6 100644
--- a/tests/expected/suites_default_post_DescribeRecord.xml
+++ b/tests/expected/suites_default_post_DescribeRecord.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<csw:DescribeRecordResponse xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ows="http://www.opengis.net/ows" xmlns:fgdc="http://www.opengis.net/cat/csw/ [...]
+<csw:DescribeRecordResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/cat/csw/2.0.2 http://schemas.opengis.net/csw/2.0.2/CSW-discovery.xsd">
   <csw:SchemaComponent schemaLanguage="XMLSCHEMA" targetNamespace="http://www.opengis.net/cat/csw/2.0.2">
     <xs:schema id="csw-record" targetNamespace="http://www.opengis.net/cat/csw/2.0.2" elementFormDefault="qualified" version="2.0.2 2010-01-22">
    <xs:annotation>
diff --git a/tests/expected/suites_default_post_Exception-GetRecords-badsrsname.xml b/tests/expected/suites_default_post_Exception-GetRecords-badsrsname.xml
index 3829071..fe0c923 100644
--- a/tests/expected/suites_default_post_Exception-GetRecords-badsrsname.xml
+++ b/tests/expected/suites_default_post_Exception-GetRecords-badsrsname.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<ows:ExceptionReport xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ows="http://www.opengis.net/ows" xmlns:fgdc="http://www.opengis.net/cat/csw/csdgm"  [...]
+<ows:ExceptionReport xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" language="en-US" version="1.2.0" xsi:schemaLocation="http://www.opengis.net/ows http://schemas.opengis.net/ows/1.0.0/ow [...]
   <ows:Exception exceptionCode="InvalidParameterValue" locator="service">
     <ows:ExceptionText>Invalid Constraint: Invalid Filter request: Reprojection error: Invalid srsName "EPSG:226": Invalid source projection</ows:ExceptionText>
   </ows:Exception>
diff --git a/tests/expected/suites_default_post_Exception-GetRecords-elementname.xml b/tests/expected/suites_default_post_Exception-GetRecords-elementname.xml
index dfe6ed6..3654684 100644
--- a/tests/expected/suites_default_post_Exception-GetRecords-elementname.xml
+++ b/tests/expected/suites_default_post_Exception-GetRecords-elementname.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<ows:ExceptionReport xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ows="http://www.opengis.net/ows" xmlns:fgdc="http://www.opengis.net/cat/csw/csdgm"  [...]
+<ows:ExceptionReport xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" language="en-US" version="1.2.0" xsi:schemaLocation="http://www.opengis.net/ows http://schemas.opengis.net/ows/1.0.0/ow [...]
   <ows:Exception exceptionCode="InvalidParameterValue" locator="elementname">
     <ows:ExceptionText>Invalid ElementName parameter value: dc:foo</ows:ExceptionText>
   </ows:Exception>
diff --git a/tests/expected/suites_default_post_Exception-GetRecords-invalid-xml.xml b/tests/expected/suites_default_post_Exception-GetRecords-invalid-xml.xml
index 662c29e..f21f6db 100644
--- a/tests/expected/suites_default_post_Exception-GetRecords-invalid-xml.xml
+++ b/tests/expected/suites_default_post_Exception-GetRecords-invalid-xml.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<ows:ExceptionReport xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ows="http://www.opengis.net/ows" xmlns:fgdc="http://www.opengis.net/cat/csw/csdgm"  [...]
+<ows:ExceptionReport xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" language="en-US" version="1.2.0" xsi:schemaLocation="http://www.opengis.net/ows http://schemas.opengis.net/ows/1.0.0/ow [...]
   <ows:Exception exceptionCode="NoApplicableCode" locator="service">
     <ows:ExceptionText>Exception: the document is not valid.
 Error: Element '{http://www.opengis.net/cat/csw/2.0.2}ElementNamefoo': This element is not expected. Expected is one of ( {http://www.opengis.net/cat/csw/2.0.2}ElementSetName, {http://www.opengis.net/cat/csw/2.0.2}ElementName ).</ows:ExceptionText>
diff --git a/tests/expected/suites_default_post_GetCapabilities-SOAP.xml b/tests/expected/suites_default_post_GetCapabilities-SOAP.xml
index fcf84f9..ae7b310 100644
--- a/tests/expected/suites_default_post_GetCapabilities-SOAP.xml
+++ b/tests/expected/suites_default_post_GetCapabilities-SOAP.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<soapenv:Envelope xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ows="http://www.opengis.net/ows" xmlns:fgdc="http://www.opengis.net/cat/csw/csdgm" xml [...]
+<soapenv:Envelope xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ogc="http://www.opengis.net/ogc" xmlns:ows="http://www.opengis.net/ows" xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLS [...]
   <soapenv:Body>
     <csw:Capabilities updateSequence="PYCSW_UPDATESEQUENCE" version="2.0.2" xsi:schemaLocation="http://www.opengis.net/cat/csw/2.0.2 http://schemas.opengis.net/csw/2.0.2/CSW-discovery.xsd">
       <ows:ServiceIdentification>
@@ -13,6 +13,7 @@
         </ows:Keywords>
         <ows:ServiceType codeSpace="OGC">CSW</ows:ServiceType>
         <ows:ServiceTypeVersion>2.0.2</ows:ServiceTypeVersion>
+        <ows:ServiceTypeVersion>3.0.0</ows:ServiceTypeVersion>
         <ows:Fees>None</ows:Fees>
         <ows:AccessConstraints>None</ows:AccessConstraints>
       </ows:ServiceIdentification>
@@ -51,19 +52,12 @@
             </ows:HTTP>
           </ows:DCP>
           <ows:Parameter name="sections">
+            <ows:Value>Filter_Capabilities</ows:Value>
+            <ows:Value>OperationsMetadata</ows:Value>
             <ows:Value>ServiceIdentification</ows:Value>
             <ows:Value>ServiceProvider</ows:Value>
-            <ows:Value>OperationsMetadata</ows:Value>
-            <ows:Value>Filter_Capabilities</ows:Value>
           </ows:Parameter>
         </ows:Operation>
-        <ows:Operation name="GetRepositoryItem">
-          <ows:DCP>
-            <ows:HTTP>
-              <ows:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/default/default.cfg"/>
-            </ows:HTTP>
-          </ows:DCP>
-        </ows:Operation>
         <ows:Operation name="DescribeRecord">
           <ows:DCP>
             <ows:HTTP>
@@ -71,14 +65,14 @@
               <ows:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/default/default.cfg"/>
             </ows:HTTP>
           </ows:DCP>
-          <ows:Parameter name="schemaLanguage">
-            <ows:Value>http://www.w3.org/XML/Schema</ows:Value>
-            <ows:Value>http://www.w3.org/TR/xmlschema-1/</ows:Value>
-            <ows:Value>http://www.w3.org/2001/XMLSchema</ows:Value>
-          </ows:Parameter>
           <ows:Parameter name="outputFormat">
-            <ows:Value>application/xml</ows:Value>
             <ows:Value>application/json</ows:Value>
+            <ows:Value>application/xml</ows:Value>
+          </ows:Parameter>
+          <ows:Parameter name="schemaLanguage">
+            <ows:Value>http://www.w3.org/2001/XMLSchema</ows:Value>
+            <ows:Value>http://www.w3.org/TR/xmlschema-1/</ows:Value>
+            <ows:Value>http://www.w3.org/XML/Schema</ows:Value>
           </ows:Parameter>
           <ows:Parameter name="typeName">
             <ows:Value>csw:Record</ows:Value>
@@ -92,64 +86,47 @@
             </ows:HTTP>
           </ows:DCP>
           <ows:Parameter name="ParameterName">
+            <ows:Value>DescribeRecord.outputFormat</ows:Value>
+            <ows:Value>DescribeRecord.schemaLanguage</ows:Value>
+            <ows:Value>DescribeRecord.typeName</ows:Value>
+            <ows:Value>GetCapabilities.sections</ows:Value>
+            <ows:Value>GetRecordById.ElementSetName</ows:Value>
+            <ows:Value>GetRecordById.outputFormat</ows:Value>
+            <ows:Value>GetRecordById.outputSchema</ows:Value>
+            <ows:Value>GetRecords.CONSTRAINTLANGUAGE</ows:Value>
+            <ows:Value>GetRecords.ElementSetName</ows:Value>
             <ows:Value>GetRecords.outputFormat</ows:Value>
             <ows:Value>GetRecords.outputSchema</ows:Value>
-            <ows:Value>GetRecords.CONSTRAINTLANGUAGE</ows:Value>
             <ows:Value>GetRecords.resultType</ows:Value>
             <ows:Value>GetRecords.typeNames</ows:Value>
-            <ows:Value>GetRecords.ElementSetName</ows:Value>
-            <ows:Value>GetCapabilities.sections</ows:Value>
-            <ows:Value>GetRecordById.outputFormat</ows:Value>
-            <ows:Value>GetRecordById.outputSchema</ows:Value>
-            <ows:Value>GetRecordById.ElementSetName</ows:Value>
-            <ows:Value>DescribeRecord.schemaLanguage</ows:Value>
-            <ows:Value>DescribeRecord.outputFormat</ows:Value>
-            <ows:Value>DescribeRecord.typeName</ows:Value>
           </ows:Parameter>
         </ows:Operation>
-        <ows:Operation name="GetRecordById">
+        <ows:Operation name="GetRecords">
           <ows:DCP>
             <ows:HTTP>
               <ows:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/default/default.cfg"/>
               <ows:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/default/default.cfg"/>
             </ows:HTTP>
           </ows:DCP>
-          <ows:Parameter name="outputFormat">
-            <ows:Value>application/xml</ows:Value>
-            <ows:Value>application/json</ows:Value>
-          </ows:Parameter>
-          <ows:Parameter name="outputSchema">
-            <ows:Value>http://www.opengis.net/cat/csw/2.0.2</ows:Value>
-            <ows:Value>http://www.w3.org/2005/Atom</ows:Value>
-            <ows:Value>http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/</ows:Value>
-            <ows:Value>http://www.opengis.net/cat/csw/csdgm</ows:Value>
+          <ows:Parameter name="CONSTRAINTLANGUAGE">
+            <ows:Value>CQL_TEXT</ows:Value>
+            <ows:Value>FILTER</ows:Value>
           </ows:Parameter>
           <ows:Parameter name="ElementSetName">
             <ows:Value>brief</ows:Value>
-            <ows:Value>summary</ows:Value>
             <ows:Value>full</ows:Value>
+            <ows:Value>summary</ows:Value>
           </ows:Parameter>
-        </ows:Operation>
-        <ows:Operation name="GetRecords">
-          <ows:DCP>
-            <ows:HTTP>
-              <ows:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/default/default.cfg"/>
-              <ows:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/default/default.cfg"/>
-            </ows:HTTP>
-          </ows:DCP>
           <ows:Parameter name="outputFormat">
-            <ows:Value>application/xml</ows:Value>
             <ows:Value>application/json</ows:Value>
+            <ows:Value>application/xml</ows:Value>
           </ows:Parameter>
           <ows:Parameter name="outputSchema">
-            <ows:Value>http://www.opengis.net/cat/csw/2.0.2</ows:Value>
-            <ows:Value>http://www.w3.org/2005/Atom</ows:Value>
             <ows:Value>http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/</ows:Value>
+            <ows:Value>http://www.interlis.ch/INTERLIS2.3</ows:Value>
+            <ows:Value>http://www.opengis.net/cat/csw/2.0.2</ows:Value>
             <ows:Value>http://www.opengis.net/cat/csw/csdgm</ows:Value>
-          </ows:Parameter>
-          <ows:Parameter name="CONSTRAINTLANGUAGE">
-            <ows:Value>FILTER</ows:Value>
-            <ows:Value>CQL_TEXT</ows:Value>
+            <ows:Value>http://www.w3.org/2005/Atom</ows:Value>
           </ows:Parameter>
           <ows:Parameter name="resultType">
             <ows:Value>hits</ows:Value>
@@ -159,39 +136,66 @@
           <ows:Parameter name="typeNames">
             <ows:Value>csw:Record</ows:Value>
           </ows:Parameter>
-          <ows:Parameter name="ElementSetName">
-            <ows:Value>brief</ows:Value>
-            <ows:Value>summary</ows:Value>
-            <ows:Value>full</ows:Value>
-          </ows:Parameter>
           <ows:Constraint name="SupportedDublinCoreQueryables">
+            <ows:Value>csw:AnyText</ows:Value>
             <ows:Value>dc:contributor</ows:Value>
-            <ows:Value>dc:source</ows:Value>
-            <ows:Value>dc:language</ows:Value>
-            <ows:Value>dc:title</ows:Value>
-            <ows:Value>dc:subject</ows:Value>
             <ows:Value>dc:creator</ows:Value>
-            <ows:Value>dc:type</ows:Value>
-            <ows:Value>ows:BoundingBox</ows:Value>
-            <ows:Value>dct:modified</ows:Value>
-            <ows:Value>dct:abstract</ows:Value>
-            <ows:Value>dc:relation</ows:Value>
             <ows:Value>dc:date</ows:Value>
+            <ows:Value>dc:format</ows:Value>
             <ows:Value>dc:identifier</ows:Value>
+            <ows:Value>dc:language</ows:Value>
             <ows:Value>dc:publisher</ows:Value>
-            <ows:Value>dc:format</ows:Value>
-            <ows:Value>csw:AnyText</ows:Value>
+            <ows:Value>dc:relation</ows:Value>
             <ows:Value>dc:rights</ows:Value>
+            <ows:Value>dc:source</ows:Value>
+            <ows:Value>dc:subject</ows:Value>
+            <ows:Value>dc:title</ows:Value>
+            <ows:Value>dc:type</ows:Value>
+            <ows:Value>dct:abstract</ows:Value>
+            <ows:Value>dct:modified</ows:Value>
+            <ows:Value>ows:BoundingBox</ows:Value>
           </ows:Constraint>
         </ows:Operation>
-        <ows:Parameter name="version">
-          <ows:Value>2.0.2</ows:Value>
-        </ows:Parameter>
+        <ows:Operation name="GetRecordById">
+          <ows:DCP>
+            <ows:HTTP>
+              <ows:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/default/default.cfg"/>
+              <ows:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/default/default.cfg"/>
+            </ows:HTTP>
+          </ows:DCP>
+          <ows:Parameter name="ElementSetName">
+            <ows:Value>brief</ows:Value>
+            <ows:Value>full</ows:Value>
+            <ows:Value>summary</ows:Value>
+          </ows:Parameter>
+          <ows:Parameter name="outputFormat">
+            <ows:Value>application/json</ows:Value>
+            <ows:Value>application/xml</ows:Value>
+          </ows:Parameter>
+          <ows:Parameter name="outputSchema">
+            <ows:Value>http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/</ows:Value>
+            <ows:Value>http://www.interlis.ch/INTERLIS2.3</ows:Value>
+            <ows:Value>http://www.opengis.net/cat/csw/2.0.2</ows:Value>
+            <ows:Value>http://www.opengis.net/cat/csw/csdgm</ows:Value>
+            <ows:Value>http://www.w3.org/2005/Atom</ows:Value>
+          </ows:Parameter>
+        </ows:Operation>
+        <ows:Operation name="GetRepositoryItem">
+          <ows:DCP>
+            <ows:HTTP>
+              <ows:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/default/default.cfg"/>
+            </ows:HTTP>
+          </ows:DCP>
+        </ows:Operation>
         <ows:Parameter name="service">
           <ows:Value>CSW</ows:Value>
         </ows:Parameter>
-        <ows:Constraint name="XPathQueryables">
-          <ows:Value>allowed</ows:Value>
+        <ows:Parameter name="version">
+          <ows:Value>2.0.2</ows:Value>
+          <ows:Value>3.0.0</ows:Value>
+        </ows:Parameter>
+        <ows:Constraint name="FederatedCatalogues">
+          <ows:Value>http://demo.pycsw.org/gisdata/csw</ows:Value>
         </ows:Constraint>
         <ows:Constraint name="MaxRecordDefault">
           <ows:Value>10</ows:Value>
@@ -200,8 +204,8 @@
           <ows:Value>XML</ows:Value>
           <ows:Value>SOAP</ows:Value>
         </ows:Constraint>
-        <ows:Constraint name="FederatedCatalogues">
-          <ows:Value>http://demo.pycsw.org/gisdata/csw</ows:Value>
+        <ows:Constraint name="XPathQueryables">
+          <ows:Value>allowed</ows:Value>
         </ows:Constraint>
       </ows:OperationsMetadata>
       <ogc:Filter_Capabilities>
@@ -231,11 +235,11 @@
           <ogc:ComparisonOperators>
             <ogc:ComparisonOperator>Between</ogc:ComparisonOperator>
             <ogc:ComparisonOperator>EqualTo</ogc:ComparisonOperator>
-            <ogc:ComparisonOperator>LessThanEqualTo</ogc:ComparisonOperator>
             <ogc:ComparisonOperator>GreaterThan</ogc:ComparisonOperator>
-            <ogc:ComparisonOperator>Like</ogc:ComparisonOperator>
-            <ogc:ComparisonOperator>LessThan</ogc:ComparisonOperator>
             <ogc:ComparisonOperator>GreaterThanEqualTo</ogc:ComparisonOperator>
+            <ogc:ComparisonOperator>LessThan</ogc:ComparisonOperator>
+            <ogc:ComparisonOperator>LessThanEqualTo</ogc:ComparisonOperator>
+            <ogc:ComparisonOperator>Like</ogc:ComparisonOperator>
             <ogc:ComparisonOperator>NotEqualTo</ogc:ComparisonOperator>
             <ogc:ComparisonOperator>NullCheck</ogc:ComparisonOperator>
           </ogc:ComparisonOperators>
diff --git a/tests/expected/suites_default_post_GetCapabilities-sections.xml b/tests/expected/suites_default_post_GetCapabilities-sections.xml
index 85bccd9..9c51855 100644
--- a/tests/expected/suites_default_post_GetCapabilities-sections.xml
+++ b/tests/expected/suites_default_post_GetCapabilities-sections.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<csw:Capabilities xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ows="http://www.opengis.net/ows" xmlns:fgdc="http://www.opengis.net/cat/csw/csdgm" xml [...]
+<csw:Capabilities xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ogc="http://www.opengis.net/ogc" xmlns:ows="http://www.opengis.net/ows" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" updateSequence="PYCSW_UPDATESEQUENCE" ve [...]
   <ows:ServiceProvider>
     <ows:ProviderName>pycsw</ows:ProviderName>
     <ows:ProviderSite xlink:type="simple" xlink:href="http://pycsw.org/"/>
@@ -54,11 +54,11 @@
       <ogc:ComparisonOperators>
         <ogc:ComparisonOperator>Between</ogc:ComparisonOperator>
         <ogc:ComparisonOperator>EqualTo</ogc:ComparisonOperator>
-        <ogc:ComparisonOperator>LessThanEqualTo</ogc:ComparisonOperator>
         <ogc:ComparisonOperator>GreaterThan</ogc:ComparisonOperator>
-        <ogc:ComparisonOperator>Like</ogc:ComparisonOperator>
-        <ogc:ComparisonOperator>LessThan</ogc:ComparisonOperator>
         <ogc:ComparisonOperator>GreaterThanEqualTo</ogc:ComparisonOperator>
+        <ogc:ComparisonOperator>LessThan</ogc:ComparisonOperator>
+        <ogc:ComparisonOperator>LessThanEqualTo</ogc:ComparisonOperator>
+        <ogc:ComparisonOperator>Like</ogc:ComparisonOperator>
         <ogc:ComparisonOperator>NotEqualTo</ogc:ComparisonOperator>
         <ogc:ComparisonOperator>NullCheck</ogc:ComparisonOperator>
       </ogc:ComparisonOperators>
diff --git a/tests/expected/suites_default_post_GetCapabilities-updatesequence.xml b/tests/expected/suites_default_post_GetCapabilities-updatesequence.xml
index 2172598..8026e1b 100644
--- a/tests/expected/suites_default_post_GetCapabilities-updatesequence.xml
+++ b/tests/expected/suites_default_post_GetCapabilities-updatesequence.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<csw:Capabilities xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ows="http://www.opengis.net/ows" xmlns:fgdc="http://www.opengis.net/cat/csw/csdgm" xml [...]
+<csw:Capabilities xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ogc="http://www.opengis.net/ogc" xmlns:ows="http://www.opengis.net/ows" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" updateSequence="PYCSW_UPDATESEQUENCE" ve [...]
   <ows:ServiceIdentification>
     <ows:Title>pycsw Geospatial Catalogue</ows:Title>
     <ows:Abstract>pycsw is an OGC CSW server implementation written in Python</ows:Abstract>
@@ -11,6 +11,7 @@
     </ows:Keywords>
     <ows:ServiceType codeSpace="OGC">CSW</ows:ServiceType>
     <ows:ServiceTypeVersion>2.0.2</ows:ServiceTypeVersion>
+    <ows:ServiceTypeVersion>3.0.0</ows:ServiceTypeVersion>
     <ows:Fees>None</ows:Fees>
     <ows:AccessConstraints>None</ows:AccessConstraints>
   </ows:ServiceIdentification>
@@ -49,19 +50,12 @@
         </ows:HTTP>
       </ows:DCP>
       <ows:Parameter name="sections">
+        <ows:Value>Filter_Capabilities</ows:Value>
+        <ows:Value>OperationsMetadata</ows:Value>
         <ows:Value>ServiceIdentification</ows:Value>
         <ows:Value>ServiceProvider</ows:Value>
-        <ows:Value>OperationsMetadata</ows:Value>
-        <ows:Value>Filter_Capabilities</ows:Value>
       </ows:Parameter>
     </ows:Operation>
-    <ows:Operation name="GetRepositoryItem">
-      <ows:DCP>
-        <ows:HTTP>
-          <ows:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/default/default.cfg"/>
-        </ows:HTTP>
-      </ows:DCP>
-    </ows:Operation>
     <ows:Operation name="DescribeRecord">
       <ows:DCP>
         <ows:HTTP>
@@ -69,14 +63,14 @@
           <ows:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/default/default.cfg"/>
         </ows:HTTP>
       </ows:DCP>
-      <ows:Parameter name="schemaLanguage">
-        <ows:Value>http://www.w3.org/XML/Schema</ows:Value>
-        <ows:Value>http://www.w3.org/TR/xmlschema-1/</ows:Value>
-        <ows:Value>http://www.w3.org/2001/XMLSchema</ows:Value>
-      </ows:Parameter>
       <ows:Parameter name="outputFormat">
-        <ows:Value>application/xml</ows:Value>
         <ows:Value>application/json</ows:Value>
+        <ows:Value>application/xml</ows:Value>
+      </ows:Parameter>
+      <ows:Parameter name="schemaLanguage">
+        <ows:Value>http://www.w3.org/2001/XMLSchema</ows:Value>
+        <ows:Value>http://www.w3.org/TR/xmlschema-1/</ows:Value>
+        <ows:Value>http://www.w3.org/XML/Schema</ows:Value>
       </ows:Parameter>
       <ows:Parameter name="typeName">
         <ows:Value>csw:Record</ows:Value>
@@ -90,64 +84,47 @@
         </ows:HTTP>
       </ows:DCP>
       <ows:Parameter name="ParameterName">
+        <ows:Value>DescribeRecord.outputFormat</ows:Value>
+        <ows:Value>DescribeRecord.schemaLanguage</ows:Value>
+        <ows:Value>DescribeRecord.typeName</ows:Value>
+        <ows:Value>GetCapabilities.sections</ows:Value>
+        <ows:Value>GetRecordById.ElementSetName</ows:Value>
+        <ows:Value>GetRecordById.outputFormat</ows:Value>
+        <ows:Value>GetRecordById.outputSchema</ows:Value>
+        <ows:Value>GetRecords.CONSTRAINTLANGUAGE</ows:Value>
+        <ows:Value>GetRecords.ElementSetName</ows:Value>
         <ows:Value>GetRecords.outputFormat</ows:Value>
         <ows:Value>GetRecords.outputSchema</ows:Value>
-        <ows:Value>GetRecords.CONSTRAINTLANGUAGE</ows:Value>
         <ows:Value>GetRecords.resultType</ows:Value>
         <ows:Value>GetRecords.typeNames</ows:Value>
-        <ows:Value>GetRecords.ElementSetName</ows:Value>
-        <ows:Value>GetCapabilities.sections</ows:Value>
-        <ows:Value>GetRecordById.outputFormat</ows:Value>
-        <ows:Value>GetRecordById.outputSchema</ows:Value>
-        <ows:Value>GetRecordById.ElementSetName</ows:Value>
-        <ows:Value>DescribeRecord.schemaLanguage</ows:Value>
-        <ows:Value>DescribeRecord.outputFormat</ows:Value>
-        <ows:Value>DescribeRecord.typeName</ows:Value>
       </ows:Parameter>
     </ows:Operation>
-    <ows:Operation name="GetRecordById">
+    <ows:Operation name="GetRecords">
       <ows:DCP>
         <ows:HTTP>
           <ows:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/default/default.cfg"/>
           <ows:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/default/default.cfg"/>
         </ows:HTTP>
       </ows:DCP>
-      <ows:Parameter name="outputFormat">
-        <ows:Value>application/xml</ows:Value>
-        <ows:Value>application/json</ows:Value>
-      </ows:Parameter>
-      <ows:Parameter name="outputSchema">
-        <ows:Value>http://www.opengis.net/cat/csw/2.0.2</ows:Value>
-        <ows:Value>http://www.w3.org/2005/Atom</ows:Value>
-        <ows:Value>http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/</ows:Value>
-        <ows:Value>http://www.opengis.net/cat/csw/csdgm</ows:Value>
+      <ows:Parameter name="CONSTRAINTLANGUAGE">
+        <ows:Value>CQL_TEXT</ows:Value>
+        <ows:Value>FILTER</ows:Value>
       </ows:Parameter>
       <ows:Parameter name="ElementSetName">
         <ows:Value>brief</ows:Value>
-        <ows:Value>summary</ows:Value>
         <ows:Value>full</ows:Value>
+        <ows:Value>summary</ows:Value>
       </ows:Parameter>
-    </ows:Operation>
-    <ows:Operation name="GetRecords">
-      <ows:DCP>
-        <ows:HTTP>
-          <ows:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/default/default.cfg"/>
-          <ows:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/default/default.cfg"/>
-        </ows:HTTP>
-      </ows:DCP>
       <ows:Parameter name="outputFormat">
-        <ows:Value>application/xml</ows:Value>
         <ows:Value>application/json</ows:Value>
+        <ows:Value>application/xml</ows:Value>
       </ows:Parameter>
       <ows:Parameter name="outputSchema">
-        <ows:Value>http://www.opengis.net/cat/csw/2.0.2</ows:Value>
-        <ows:Value>http://www.w3.org/2005/Atom</ows:Value>
         <ows:Value>http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/</ows:Value>
+        <ows:Value>http://www.interlis.ch/INTERLIS2.3</ows:Value>
+        <ows:Value>http://www.opengis.net/cat/csw/2.0.2</ows:Value>
         <ows:Value>http://www.opengis.net/cat/csw/csdgm</ows:Value>
-      </ows:Parameter>
-      <ows:Parameter name="CONSTRAINTLANGUAGE">
-        <ows:Value>FILTER</ows:Value>
-        <ows:Value>CQL_TEXT</ows:Value>
+        <ows:Value>http://www.w3.org/2005/Atom</ows:Value>
       </ows:Parameter>
       <ows:Parameter name="resultType">
         <ows:Value>hits</ows:Value>
@@ -157,39 +134,66 @@
       <ows:Parameter name="typeNames">
         <ows:Value>csw:Record</ows:Value>
       </ows:Parameter>
-      <ows:Parameter name="ElementSetName">
-        <ows:Value>brief</ows:Value>
-        <ows:Value>summary</ows:Value>
-        <ows:Value>full</ows:Value>
-      </ows:Parameter>
       <ows:Constraint name="SupportedDublinCoreQueryables">
+        <ows:Value>csw:AnyText</ows:Value>
         <ows:Value>dc:contributor</ows:Value>
-        <ows:Value>dc:source</ows:Value>
-        <ows:Value>dc:language</ows:Value>
-        <ows:Value>dc:title</ows:Value>
-        <ows:Value>dc:subject</ows:Value>
         <ows:Value>dc:creator</ows:Value>
-        <ows:Value>dc:type</ows:Value>
-        <ows:Value>ows:BoundingBox</ows:Value>
-        <ows:Value>dct:modified</ows:Value>
-        <ows:Value>dct:abstract</ows:Value>
-        <ows:Value>dc:relation</ows:Value>
         <ows:Value>dc:date</ows:Value>
+        <ows:Value>dc:format</ows:Value>
         <ows:Value>dc:identifier</ows:Value>
+        <ows:Value>dc:language</ows:Value>
         <ows:Value>dc:publisher</ows:Value>
-        <ows:Value>dc:format</ows:Value>
-        <ows:Value>csw:AnyText</ows:Value>
+        <ows:Value>dc:relation</ows:Value>
         <ows:Value>dc:rights</ows:Value>
+        <ows:Value>dc:source</ows:Value>
+        <ows:Value>dc:subject</ows:Value>
+        <ows:Value>dc:title</ows:Value>
+        <ows:Value>dc:type</ows:Value>
+        <ows:Value>dct:abstract</ows:Value>
+        <ows:Value>dct:modified</ows:Value>
+        <ows:Value>ows:BoundingBox</ows:Value>
       </ows:Constraint>
     </ows:Operation>
-    <ows:Parameter name="version">
-      <ows:Value>2.0.2</ows:Value>
-    </ows:Parameter>
+    <ows:Operation name="GetRecordById">
+      <ows:DCP>
+        <ows:HTTP>
+          <ows:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/default/default.cfg"/>
+          <ows:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/default/default.cfg"/>
+        </ows:HTTP>
+      </ows:DCP>
+      <ows:Parameter name="ElementSetName">
+        <ows:Value>brief</ows:Value>
+        <ows:Value>full</ows:Value>
+        <ows:Value>summary</ows:Value>
+      </ows:Parameter>
+      <ows:Parameter name="outputFormat">
+        <ows:Value>application/json</ows:Value>
+        <ows:Value>application/xml</ows:Value>
+      </ows:Parameter>
+      <ows:Parameter name="outputSchema">
+        <ows:Value>http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/</ows:Value>
+        <ows:Value>http://www.interlis.ch/INTERLIS2.3</ows:Value>
+        <ows:Value>http://www.opengis.net/cat/csw/2.0.2</ows:Value>
+        <ows:Value>http://www.opengis.net/cat/csw/csdgm</ows:Value>
+        <ows:Value>http://www.w3.org/2005/Atom</ows:Value>
+      </ows:Parameter>
+    </ows:Operation>
+    <ows:Operation name="GetRepositoryItem">
+      <ows:DCP>
+        <ows:HTTP>
+          <ows:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/default/default.cfg"/>
+        </ows:HTTP>
+      </ows:DCP>
+    </ows:Operation>
     <ows:Parameter name="service">
       <ows:Value>CSW</ows:Value>
     </ows:Parameter>
-    <ows:Constraint name="XPathQueryables">
-      <ows:Value>allowed</ows:Value>
+    <ows:Parameter name="version">
+      <ows:Value>2.0.2</ows:Value>
+      <ows:Value>3.0.0</ows:Value>
+    </ows:Parameter>
+    <ows:Constraint name="FederatedCatalogues">
+      <ows:Value>http://demo.pycsw.org/gisdata/csw</ows:Value>
     </ows:Constraint>
     <ows:Constraint name="MaxRecordDefault">
       <ows:Value>10</ows:Value>
@@ -198,8 +202,8 @@
       <ows:Value>XML</ows:Value>
       <ows:Value>SOAP</ows:Value>
     </ows:Constraint>
-    <ows:Constraint name="FederatedCatalogues">
-      <ows:Value>http://demo.pycsw.org/gisdata/csw</ows:Value>
+    <ows:Constraint name="XPathQueryables">
+      <ows:Value>allowed</ows:Value>
     </ows:Constraint>
   </ows:OperationsMetadata>
   <ogc:Filter_Capabilities>
@@ -229,11 +233,11 @@
       <ogc:ComparisonOperators>
         <ogc:ComparisonOperator>Between</ogc:ComparisonOperator>
         <ogc:ComparisonOperator>EqualTo</ogc:ComparisonOperator>
-        <ogc:ComparisonOperator>LessThanEqualTo</ogc:ComparisonOperator>
         <ogc:ComparisonOperator>GreaterThan</ogc:ComparisonOperator>
-        <ogc:ComparisonOperator>Like</ogc:ComparisonOperator>
-        <ogc:ComparisonOperator>LessThan</ogc:ComparisonOperator>
         <ogc:ComparisonOperator>GreaterThanEqualTo</ogc:ComparisonOperator>
+        <ogc:ComparisonOperator>LessThan</ogc:ComparisonOperator>
+        <ogc:ComparisonOperator>LessThanEqualTo</ogc:ComparisonOperator>
+        <ogc:ComparisonOperator>Like</ogc:ComparisonOperator>
         <ogc:ComparisonOperator>NotEqualTo</ogc:ComparisonOperator>
         <ogc:ComparisonOperator>NullCheck</ogc:ComparisonOperator>
       </ogc:ComparisonOperators>
diff --git a/tests/expected/suites_default_post_GetCapabilities.xml b/tests/expected/suites_default_post_GetCapabilities.xml
index 2172598..8026e1b 100644
--- a/tests/expected/suites_default_post_GetCapabilities.xml
+++ b/tests/expected/suites_default_post_GetCapabilities.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<csw:Capabilities xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ows="http://www.opengis.net/ows" xmlns:fgdc="http://www.opengis.net/cat/csw/csdgm" xml [...]
+<csw:Capabilities xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ogc="http://www.opengis.net/ogc" xmlns:ows="http://www.opengis.net/ows" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" updateSequence="PYCSW_UPDATESEQUENCE" ve [...]
   <ows:ServiceIdentification>
     <ows:Title>pycsw Geospatial Catalogue</ows:Title>
     <ows:Abstract>pycsw is an OGC CSW server implementation written in Python</ows:Abstract>
@@ -11,6 +11,7 @@
     </ows:Keywords>
     <ows:ServiceType codeSpace="OGC">CSW</ows:ServiceType>
     <ows:ServiceTypeVersion>2.0.2</ows:ServiceTypeVersion>
+    <ows:ServiceTypeVersion>3.0.0</ows:ServiceTypeVersion>
     <ows:Fees>None</ows:Fees>
     <ows:AccessConstraints>None</ows:AccessConstraints>
   </ows:ServiceIdentification>
@@ -49,19 +50,12 @@
         </ows:HTTP>
       </ows:DCP>
       <ows:Parameter name="sections">
+        <ows:Value>Filter_Capabilities</ows:Value>
+        <ows:Value>OperationsMetadata</ows:Value>
         <ows:Value>ServiceIdentification</ows:Value>
         <ows:Value>ServiceProvider</ows:Value>
-        <ows:Value>OperationsMetadata</ows:Value>
-        <ows:Value>Filter_Capabilities</ows:Value>
       </ows:Parameter>
     </ows:Operation>
-    <ows:Operation name="GetRepositoryItem">
-      <ows:DCP>
-        <ows:HTTP>
-          <ows:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/default/default.cfg"/>
-        </ows:HTTP>
-      </ows:DCP>
-    </ows:Operation>
     <ows:Operation name="DescribeRecord">
       <ows:DCP>
         <ows:HTTP>
@@ -69,14 +63,14 @@
           <ows:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/default/default.cfg"/>
         </ows:HTTP>
       </ows:DCP>
-      <ows:Parameter name="schemaLanguage">
-        <ows:Value>http://www.w3.org/XML/Schema</ows:Value>
-        <ows:Value>http://www.w3.org/TR/xmlschema-1/</ows:Value>
-        <ows:Value>http://www.w3.org/2001/XMLSchema</ows:Value>
-      </ows:Parameter>
       <ows:Parameter name="outputFormat">
-        <ows:Value>application/xml</ows:Value>
         <ows:Value>application/json</ows:Value>
+        <ows:Value>application/xml</ows:Value>
+      </ows:Parameter>
+      <ows:Parameter name="schemaLanguage">
+        <ows:Value>http://www.w3.org/2001/XMLSchema</ows:Value>
+        <ows:Value>http://www.w3.org/TR/xmlschema-1/</ows:Value>
+        <ows:Value>http://www.w3.org/XML/Schema</ows:Value>
       </ows:Parameter>
       <ows:Parameter name="typeName">
         <ows:Value>csw:Record</ows:Value>
@@ -90,64 +84,47 @@
         </ows:HTTP>
       </ows:DCP>
       <ows:Parameter name="ParameterName">
+        <ows:Value>DescribeRecord.outputFormat</ows:Value>
+        <ows:Value>DescribeRecord.schemaLanguage</ows:Value>
+        <ows:Value>DescribeRecord.typeName</ows:Value>
+        <ows:Value>GetCapabilities.sections</ows:Value>
+        <ows:Value>GetRecordById.ElementSetName</ows:Value>
+        <ows:Value>GetRecordById.outputFormat</ows:Value>
+        <ows:Value>GetRecordById.outputSchema</ows:Value>
+        <ows:Value>GetRecords.CONSTRAINTLANGUAGE</ows:Value>
+        <ows:Value>GetRecords.ElementSetName</ows:Value>
         <ows:Value>GetRecords.outputFormat</ows:Value>
         <ows:Value>GetRecords.outputSchema</ows:Value>
-        <ows:Value>GetRecords.CONSTRAINTLANGUAGE</ows:Value>
         <ows:Value>GetRecords.resultType</ows:Value>
         <ows:Value>GetRecords.typeNames</ows:Value>
-        <ows:Value>GetRecords.ElementSetName</ows:Value>
-        <ows:Value>GetCapabilities.sections</ows:Value>
-        <ows:Value>GetRecordById.outputFormat</ows:Value>
-        <ows:Value>GetRecordById.outputSchema</ows:Value>
-        <ows:Value>GetRecordById.ElementSetName</ows:Value>
-        <ows:Value>DescribeRecord.schemaLanguage</ows:Value>
-        <ows:Value>DescribeRecord.outputFormat</ows:Value>
-        <ows:Value>DescribeRecord.typeName</ows:Value>
       </ows:Parameter>
     </ows:Operation>
-    <ows:Operation name="GetRecordById">
+    <ows:Operation name="GetRecords">
       <ows:DCP>
         <ows:HTTP>
           <ows:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/default/default.cfg"/>
           <ows:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/default/default.cfg"/>
         </ows:HTTP>
       </ows:DCP>
-      <ows:Parameter name="outputFormat">
-        <ows:Value>application/xml</ows:Value>
-        <ows:Value>application/json</ows:Value>
-      </ows:Parameter>
-      <ows:Parameter name="outputSchema">
-        <ows:Value>http://www.opengis.net/cat/csw/2.0.2</ows:Value>
-        <ows:Value>http://www.w3.org/2005/Atom</ows:Value>
-        <ows:Value>http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/</ows:Value>
-        <ows:Value>http://www.opengis.net/cat/csw/csdgm</ows:Value>
+      <ows:Parameter name="CONSTRAINTLANGUAGE">
+        <ows:Value>CQL_TEXT</ows:Value>
+        <ows:Value>FILTER</ows:Value>
       </ows:Parameter>
       <ows:Parameter name="ElementSetName">
         <ows:Value>brief</ows:Value>
-        <ows:Value>summary</ows:Value>
         <ows:Value>full</ows:Value>
+        <ows:Value>summary</ows:Value>
       </ows:Parameter>
-    </ows:Operation>
-    <ows:Operation name="GetRecords">
-      <ows:DCP>
-        <ows:HTTP>
-          <ows:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/default/default.cfg"/>
-          <ows:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/default/default.cfg"/>
-        </ows:HTTP>
-      </ows:DCP>
       <ows:Parameter name="outputFormat">
-        <ows:Value>application/xml</ows:Value>
         <ows:Value>application/json</ows:Value>
+        <ows:Value>application/xml</ows:Value>
       </ows:Parameter>
       <ows:Parameter name="outputSchema">
-        <ows:Value>http://www.opengis.net/cat/csw/2.0.2</ows:Value>
-        <ows:Value>http://www.w3.org/2005/Atom</ows:Value>
         <ows:Value>http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/</ows:Value>
+        <ows:Value>http://www.interlis.ch/INTERLIS2.3</ows:Value>
+        <ows:Value>http://www.opengis.net/cat/csw/2.0.2</ows:Value>
         <ows:Value>http://www.opengis.net/cat/csw/csdgm</ows:Value>
-      </ows:Parameter>
-      <ows:Parameter name="CONSTRAINTLANGUAGE">
-        <ows:Value>FILTER</ows:Value>
-        <ows:Value>CQL_TEXT</ows:Value>
+        <ows:Value>http://www.w3.org/2005/Atom</ows:Value>
       </ows:Parameter>
       <ows:Parameter name="resultType">
         <ows:Value>hits</ows:Value>
@@ -157,39 +134,66 @@
       <ows:Parameter name="typeNames">
         <ows:Value>csw:Record</ows:Value>
       </ows:Parameter>
-      <ows:Parameter name="ElementSetName">
-        <ows:Value>brief</ows:Value>
-        <ows:Value>summary</ows:Value>
-        <ows:Value>full</ows:Value>
-      </ows:Parameter>
       <ows:Constraint name="SupportedDublinCoreQueryables">
+        <ows:Value>csw:AnyText</ows:Value>
         <ows:Value>dc:contributor</ows:Value>
-        <ows:Value>dc:source</ows:Value>
-        <ows:Value>dc:language</ows:Value>
-        <ows:Value>dc:title</ows:Value>
-        <ows:Value>dc:subject</ows:Value>
         <ows:Value>dc:creator</ows:Value>
-        <ows:Value>dc:type</ows:Value>
-        <ows:Value>ows:BoundingBox</ows:Value>
-        <ows:Value>dct:modified</ows:Value>
-        <ows:Value>dct:abstract</ows:Value>
-        <ows:Value>dc:relation</ows:Value>
         <ows:Value>dc:date</ows:Value>
+        <ows:Value>dc:format</ows:Value>
         <ows:Value>dc:identifier</ows:Value>
+        <ows:Value>dc:language</ows:Value>
         <ows:Value>dc:publisher</ows:Value>
-        <ows:Value>dc:format</ows:Value>
-        <ows:Value>csw:AnyText</ows:Value>
+        <ows:Value>dc:relation</ows:Value>
         <ows:Value>dc:rights</ows:Value>
+        <ows:Value>dc:source</ows:Value>
+        <ows:Value>dc:subject</ows:Value>
+        <ows:Value>dc:title</ows:Value>
+        <ows:Value>dc:type</ows:Value>
+        <ows:Value>dct:abstract</ows:Value>
+        <ows:Value>dct:modified</ows:Value>
+        <ows:Value>ows:BoundingBox</ows:Value>
       </ows:Constraint>
     </ows:Operation>
-    <ows:Parameter name="version">
-      <ows:Value>2.0.2</ows:Value>
-    </ows:Parameter>
+    <ows:Operation name="GetRecordById">
+      <ows:DCP>
+        <ows:HTTP>
+          <ows:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/default/default.cfg"/>
+          <ows:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/default/default.cfg"/>
+        </ows:HTTP>
+      </ows:DCP>
+      <ows:Parameter name="ElementSetName">
+        <ows:Value>brief</ows:Value>
+        <ows:Value>full</ows:Value>
+        <ows:Value>summary</ows:Value>
+      </ows:Parameter>
+      <ows:Parameter name="outputFormat">
+        <ows:Value>application/json</ows:Value>
+        <ows:Value>application/xml</ows:Value>
+      </ows:Parameter>
+      <ows:Parameter name="outputSchema">
+        <ows:Value>http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/</ows:Value>
+        <ows:Value>http://www.interlis.ch/INTERLIS2.3</ows:Value>
+        <ows:Value>http://www.opengis.net/cat/csw/2.0.2</ows:Value>
+        <ows:Value>http://www.opengis.net/cat/csw/csdgm</ows:Value>
+        <ows:Value>http://www.w3.org/2005/Atom</ows:Value>
+      </ows:Parameter>
+    </ows:Operation>
+    <ows:Operation name="GetRepositoryItem">
+      <ows:DCP>
+        <ows:HTTP>
+          <ows:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/default/default.cfg"/>
+        </ows:HTTP>
+      </ows:DCP>
+    </ows:Operation>
     <ows:Parameter name="service">
       <ows:Value>CSW</ows:Value>
     </ows:Parameter>
-    <ows:Constraint name="XPathQueryables">
-      <ows:Value>allowed</ows:Value>
+    <ows:Parameter name="version">
+      <ows:Value>2.0.2</ows:Value>
+      <ows:Value>3.0.0</ows:Value>
+    </ows:Parameter>
+    <ows:Constraint name="FederatedCatalogues">
+      <ows:Value>http://demo.pycsw.org/gisdata/csw</ows:Value>
     </ows:Constraint>
     <ows:Constraint name="MaxRecordDefault">
       <ows:Value>10</ows:Value>
@@ -198,8 +202,8 @@
       <ows:Value>XML</ows:Value>
       <ows:Value>SOAP</ows:Value>
     </ows:Constraint>
-    <ows:Constraint name="FederatedCatalogues">
-      <ows:Value>http://demo.pycsw.org/gisdata/csw</ows:Value>
+    <ows:Constraint name="XPathQueryables">
+      <ows:Value>allowed</ows:Value>
     </ows:Constraint>
   </ows:OperationsMetadata>
   <ogc:Filter_Capabilities>
@@ -229,11 +233,11 @@
       <ogc:ComparisonOperators>
         <ogc:ComparisonOperator>Between</ogc:ComparisonOperator>
         <ogc:ComparisonOperator>EqualTo</ogc:ComparisonOperator>
-        <ogc:ComparisonOperator>LessThanEqualTo</ogc:ComparisonOperator>
         <ogc:ComparisonOperator>GreaterThan</ogc:ComparisonOperator>
-        <ogc:ComparisonOperator>Like</ogc:ComparisonOperator>
-        <ogc:ComparisonOperator>LessThan</ogc:ComparisonOperator>
         <ogc:ComparisonOperator>GreaterThanEqualTo</ogc:ComparisonOperator>
+        <ogc:ComparisonOperator>LessThan</ogc:ComparisonOperator>
+        <ogc:ComparisonOperator>LessThanEqualTo</ogc:ComparisonOperator>
+        <ogc:ComparisonOperator>Like</ogc:ComparisonOperator>
         <ogc:ComparisonOperator>NotEqualTo</ogc:ComparisonOperator>
         <ogc:ComparisonOperator>NullCheck</ogc:ComparisonOperator>
       </ogc:ComparisonOperators>
diff --git a/tests/expected/suites_default_post_GetDomain-parameter.xml b/tests/expected/suites_default_post_GetDomain-parameter.xml
index 933f802..71bdb8a 100644
--- a/tests/expected/suites_default_post_GetDomain-parameter.xml
+++ b/tests/expected/suites_default_post_GetDomain-parameter.xml
@@ -1,11 +1,11 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<csw:GetDomainResponse xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ows="http://www.opengis.net/ows" xmlns:fgdc="http://www.opengis.net/cat/csw/csdgm [...]
+<csw:GetDomainResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/cat/csw/2.0.2 http://schemas.opengis.net/csw/2.0.2/CSW-discovery.xsd">
   <csw:DomainValues type="csw:Record">
     <csw:ParameterName>GetRecords.CONSTRAINTLANGUAGE</csw:ParameterName>
     <csw:ListOfValues>
-      <csw:Value>FILTER</csw:Value>
       <csw:Value>CQL_TEXT</csw:Value>
+      <csw:Value>FILTER</csw:Value>
     </csw:ListOfValues>
   </csw:DomainValues>
 </csw:GetDomainResponse>
diff --git a/tests/expected/suites_default_post_GetDomain-property.xml b/tests/expected/suites_default_post_GetDomain-property.xml
index f3876b9..2577260 100644
--- a/tests/expected/suites_default_post_GetDomain-property.xml
+++ b/tests/expected/suites_default_post_GetDomain-property.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<csw:GetDomainResponse xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ows="http://www.opengis.net/ows" xmlns:fgdc="http://www.opengis.net/cat/csw/csdgm [...]
+<csw:GetDomainResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/cat/csw/2.0.2 http://schemas.opengis.net/csw/2.0.2/CSW-discovery.xsd">
   <csw:DomainValues type="csw:Record">
     <csw:PropertyName>dc:title</csw:PropertyName>
     <csw:ListOfValues>
diff --git a/tests/expected/suites_default_post_GetRecordById-json.xml b/tests/expected/suites_default_post_GetRecordById-json.xml
index dcf76f2..a13b4e9 100644
--- a/tests/expected/suites_default_post_GetRecordById-json.xml
+++ b/tests/expected/suites_default_post_GetRecordById-json.xml
@@ -1,50 +1,18 @@
 {
-    "attributes": {
-        "xsi:schemaLocation": "http://www.opengis.net/cat/csw/2.0.2 http://schemas.opengis.net/csw/2.0.2/CSW-discovery.xsd"
-    }, 
-    "tag": "csw:GetRecordByIdResponse", 
-    "children": [
-        {
-            "tag": "csw:SummaryRecord", 
-            "children": [
-                {
-                    "text": "urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63", 
-                    "tag": "dc:identifier"
-                }, 
-                {
-                    "text": "Mauris sed neque", 
-                    "tag": "dc:title"
-                }, 
-                {
-                    "text": "http://purl.org/dc/dcmitype/Dataset", 
-                    "tag": "dc:type"
-                }, 
-                {
-                    "text": "Vegetation-Cropland", 
-                    "tag": "dc:subject"
-                }, 
-                {
-                    "text": "Curabitur lacinia, ante non porta tempus, mi lorem feugiat odio, eget suscipit eros pede ac velit.", 
-                    "tag": "dct:abstract"
-                }, 
-                {
-                    "attributes": {
-                        "crs": "urn:x-ogc:def:crs:EPSG:6.11:4326", 
-                        "dimensions": "2"
-                    }, 
-                    "tag": "ows:BoundingBox", 
-                    "children": [
-                        {
-                            "text": "47.59 -4.1", 
-                            "tag": "ows:LowerCorner"
-                        }, 
-                        {
-                            "text": "51.22 0.89", 
-                            "tag": "ows:UpperCorner"
-                        }
-                    ]
-                }
-            ]
+    "csw:GetRecordByIdResponse": {
+        "@http://www.w3.org/2001/XMLSchema-instance:schemaLocation": "http://www.opengis.net/cat/csw/2.0.2 http://schemas.opengis.net/csw/2.0.2/CSW-discovery.xsd",
+        "csw:SummaryRecord": {
+            "dc:identifier": "urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63",
+            "dc:title": "Mauris sed neque",
+            "dc:type": "http://purl.org/dc/dcmitype/Dataset",
+            "dc:subject": "Vegetation-Cropland",
+            "dct:abstract": "Curabitur lacinia, ante non porta tempus, mi lorem feugiat odio, eget suscipit eros pede ac velit.",
+            "ows:BoundingBox": {
+                "@crs": "urn:x-ogc:def:crs:EPSG:6.11:4326",
+                "@dimensions": "2",
+                "ows:LowerCorner": "47.59 -4.1",
+                "ows:UpperCorner": "51.22 0.89"
+            }
         }
-    ]
+    }
 }
\ No newline at end of file
diff --git a/tests/expected/suites_default_post_GetRecordById.xml b/tests/expected/suites_default_post_GetRecordById.xml
index 2682d35..6cddad9 100644
--- a/tests/expected/suites_default_post_GetRecordById.xml
+++ b/tests/expected/suites_default_post_GetRecordById.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<csw:GetRecordByIdResponse xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ows="http://www.opengis.net/ows" xmlns:fgdc="http://www.opengis.net/cat/csw/c [...]
+<csw:GetRecordByIdResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/cat/csw/2.0.2 http://schemas.opengis.net/csw/2.0.2/CSW-discovery.xsd">
   <csw:SummaryRecord>
     <dc:identifier>urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63</dc:identifier>
     <dc:title>Mauris sed neque</dc:title>
diff --git a/tests/expected/suites_default_post_GetRecords-all-json.xml b/tests/expected/suites_default_post_GetRecords-all-json.xml
index f38da6e..ba33ab6 100644
--- a/tests/expected/suites_default_post_GetRecords-all-json.xml
+++ b/tests/expected/suites_default_post_GetRecords-all-json.xml
@@ -1,183 +1,64 @@
 {
-    "attributes": {
-        "version": "2.0.2", 
-        "xsi:schemaLocation": "http://www.opengis.net/cat/csw/2.0.2 http://schemas.opengis.net/csw/2.0.2/CSW-discovery.xsd"
-    }, 
-    "tag": "csw:GetRecordsResponse", 
-    "children": [
-        {
-            "attributes": {
-                "timestamp": "PYCSW_TIMESTAMP"
-            }, 
-            "tag": "csw:SearchStatus"
-        }, 
-        {
-            "attributes": {
-                "numberOfRecordsReturned": "5", 
-                "nextRecord": "6", 
-                "numberOfRecordsMatched": "12", 
-                "elementSet": "full", 
-                "recordSchema": "http://www.opengis.net/cat/csw/2.0.2"
-            }, 
-            "tag": "csw:SearchResults", 
-            "children": [
+    "csw:GetRecordsResponse": {
+        "@version": "2.0.2",
+        "@http://www.w3.org/2001/XMLSchema-instance:schemaLocation": "http://www.opengis.net/cat/csw/2.0.2 http://schemas.opengis.net/csw/2.0.2/CSW-discovery.xsd",
+        "csw:SearchStatus": {
+            "@timestamp": "PYCSW_TIMESTAMP"
+        },
+        "csw:SearchResults": {
+            "@nextRecord": "6",
+            "@numberOfRecordsMatched": "12",
+            "@numberOfRecordsReturned": "5",
+            "@recordSchema": "http://www.opengis.net/cat/csw/2.0.2",
+            "@elementSet": "full",
+            "csw:Record": [
                 {
-                    "tag": "csw:Record", 
-                    "children": [
-                        {
-                            "text": "urn:uuid:19887a8a-f6b0-4a63-ae56-7fba0e17801f", 
-                            "tag": "dc:identifier"
-                        }, 
-                        {
-                            "text": "http://purl.org/dc/dcmitype/Image", 
-                            "tag": "dc:type"
-                        }, 
-                        {
-                            "text": "image/svg+xml", 
-                            "tag": "dc:format"
-                        }, 
-                        {
-                            "text": "Lorem ipsum", 
-                            "tag": "dc:title"
-                        }, 
-                        {
-                            "text": "GR-22", 
-                            "tag": "dct:spatial"
-                        }, 
-                        {
-                            "text": "Tourism--Greece", 
-                            "tag": "dc:subject"
-                        }, 
-                        {
-                            "text": "Quisque lacus diam, placerat mollis, pharetra in, commodo sed, augue. Duis iaculis arcu vel arcu.", 
-                            "tag": "dct:abstract"
-                        }
-                    ]
-                }, 
+                    "dc:identifier": "urn:uuid:19887a8a-f6b0-4a63-ae56-7fba0e17801f",
+                    "dc:type": "http://purl.org/dc/dcmitype/Image",
+                    "dc:format": "image/svg+xml",
+                    "dc:title": "Lorem ipsum",
+                    "dct:spatial": "GR-22",
+                    "dc:subject": "Tourism--Greece",
+                    "dct:abstract": "Quisque lacus diam, placerat mollis, pharetra in, commodo sed, augue. Duis iaculis arcu vel arcu."
+                },
                 {
-                    "tag": "csw:Record", 
-                    "children": [
-                        {
-                            "text": "urn:uuid:1ef30a8b-876d-4828-9246-c37ab4510bbd", 
-                            "tag": "dc:identifier"
-                        }, 
-                        {
-                            "text": "http://purl.org/dc/dcmitype/Service", 
-                            "tag": "dc:type"
-                        }, 
-                        {
-                            "text": "Proin sit amet justo. In justo. Aenean adipiscing nulla id tellus.", 
-                            "tag": "dct:abstract"
-                        }, 
-                        {
-                            "attributes": {
-                                "crs": "urn:x-ogc:def:crs:EPSG:6.11:4326"
-                            }, 
-                            "tag": "ows:BoundingBox", 
-                            "children": [
-                                {
-                                    "text": "60.042 13.754", 
-                                    "tag": "ows:LowerCorner"
-                                }, 
-                                {
-                                    "text": "68.410 17.920", 
-                                    "tag": "ows:UpperCorner"
-                                }
-                            ]
-                        }
-                    ]
-                }, 
+                    "dc:identifier": "urn:uuid:1ef30a8b-876d-4828-9246-c37ab4510bbd",
+                    "dc:type": "http://purl.org/dc/dcmitype/Service",
+                    "dct:abstract": "Proin sit amet justo. In justo. Aenean adipiscing nulla id tellus.",
+                    "ows:BoundingBox": {
+                        "@crs": "urn:x-ogc:def:crs:EPSG:6.11:4326",
+                        "ows:LowerCorner": "60.042 13.754",
+                        "ows:UpperCorner": "68.410 17.920"
+                    }
+                },
                 {
-                    "tag": "csw:Record", 
-                    "children": [
-                        {
-                            "text": "urn:uuid:66ae76b7-54ba-489b-a582-0f0633d96493", 
-                            "tag": "dc:identifier"
-                        }, 
-                        {
-                            "text": "Maecenas enim", 
-                            "tag": "dc:title"
-                        }, 
-                        {
-                            "text": "http://purl.org/dc/dcmitype/Text", 
-                            "tag": "dc:type"
-                        }, 
-                        {
-                            "text": "application/xhtml+xml", 
-                            "tag": "dc:format"
-                        }, 
-                        {
-                            "text": "Marine sediments", 
-                            "tag": "dc:subject"
-                        }, 
-                        {
-                            "text": "Pellentesque tempus magna non sapien fringilla blandit.", 
-                            "tag": "dct:abstract"
-                        }
-                    ]
-                }, 
+                    "dc:identifier": "urn:uuid:66ae76b7-54ba-489b-a582-0f0633d96493",
+                    "dc:title": "Maecenas enim",
+                    "dc:type": "http://purl.org/dc/dcmitype/Text",
+                    "dc:format": "application/xhtml+xml",
+                    "dc:subject": "Marine sediments",
+                    "dct:abstract": "Pellentesque tempus magna non sapien fringilla blandit."
+                },
                 {
-                    "tag": "csw:Record", 
-                    "children": [
-                        {
-                            "text": "urn:uuid:6a3de50b-fa66-4b58-a0e6-ca146fdd18d4", 
-                            "tag": "dc:identifier"
-                        }, 
-                        {
-                            "text": "http://purl.org/dc/dcmitype/Service", 
-                            "tag": "dc:type"
-                        }, 
-                        {
-                            "text": "Ut facilisis justo ut lacus", 
-                            "tag": "dc:title"
-                        }, 
-                        {
-                            "text": "Vegetation", 
-                            "tag": "dc:subject", 
-                            "attributes": {
-                                "scheme": "http://www.digest.org/2.1"
-                            }
-                        }, 
-                        {
-                            "text": "urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63", 
-                            "tag": "dc:relation"
-                        }
-                    ]
-                }, 
+                    "dc:identifier": "urn:uuid:6a3de50b-fa66-4b58-a0e6-ca146fdd18d4",
+                    "dc:type": "http://purl.org/dc/dcmitype/Service",
+                    "dc:title": "Ut facilisis justo ut lacus",
+                    "dc:subject": {
+                        "@scheme": "http://www.digest.org/2.1",
+                        "#text": "Vegetation"
+                    },
+                    "dc:relation": "urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63"
+                },
                 {
-                    "tag": "csw:Record", 
-                    "children": [
-                        {
-                            "text": "urn:uuid:784e2afd-a9fd-44a6-9a92-a3848371c8ec", 
-                            "tag": "dc:identifier"
-                        }, 
-                        {
-                            "text": "Aliquam fermentum purus quis arcu", 
-                            "tag": "dc:title"
-                        }, 
-                        {
-                            "text": "http://purl.org/dc/dcmitype/Text", 
-                            "tag": "dc:type"
-                        }, 
-                        {
-                            "text": "Hydrography--Dictionaries", 
-                            "tag": "dc:subject"
-                        }, 
-                        {
-                            "text": "application/pdf", 
-                            "tag": "dc:format"
-                        }, 
-                        {
-                            "text": "2006-05-12", 
-                            "tag": "dc:date"
-                        }, 
-                        {
-                            "text": "Vestibulum quis ipsum sit amet metus imperdiet vehicula. Nulla scelerisque cursus mi.", 
-                            "tag": "dct:abstract"
-                        }
-                    ]
+                    "dc:identifier": "urn:uuid:784e2afd-a9fd-44a6-9a92-a3848371c8ec",
+                    "dc:title": "Aliquam fermentum purus quis arcu",
+                    "dc:type": "http://purl.org/dc/dcmitype/Text",
+                    "dc:subject": "Hydrography--Dictionaries",
+                    "dc:format": "application/pdf",
+                    "dc:date": "2006-05-12",
+                    "dct:abstract": "Vestibulum quis ipsum sit amet metus imperdiet vehicula. Nulla scelerisque cursus mi."
                 }
             ]
         }
-    ]
+    }
 }
\ No newline at end of file
diff --git a/tests/expected/suites_default_post_GetRecords-all-resulttype-hits.xml b/tests/expected/suites_default_post_GetRecords-all-resulttype-hits.xml
index f0533f6..b93efb2 100644
--- a/tests/expected/suites_default_post_GetRecords-all-resulttype-hits.xml
+++ b/tests/expected/suites_default_post_GetRecords-all-resulttype-hits.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<csw:GetRecordsResponse xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ows="http://www.opengis.net/ows" xmlns:fgdc="http://www.opengis.net/cat/csw/csdg [...]
+<csw:GetRecordsResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.0.2" xsi:schemaLocation="http://www.opengis.net/cat/csw/2.0.2 http://schemas.opengis.net/csw/2.0.2/CSW-di [...]
   <csw:SearchStatus timestamp="PYCSW_TIMESTAMP"/>
   <csw:SearchResults nextRecord="6" numberOfRecordsMatched="12" numberOfRecordsReturned="5" recordSchema="http://www.opengis.net/cat/csw/2.0.2" elementSet="full"/>
 </csw:GetRecordsResponse>
diff --git a/tests/expected/suites_default_post_GetRecords-all-resulttype-validate.xml b/tests/expected/suites_default_post_GetRecords-all-resulttype-validate.xml
index 4cb7cc8..40bc344 100644
--- a/tests/expected/suites_default_post_GetRecords-all-resulttype-validate.xml
+++ b/tests/expected/suites_default_post_GetRecords-all-resulttype-validate.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<csw:Acknowledgement xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ows="http://www.opengis.net/ows" xmlns:fgdc="http://www.opengis.net/cat/csw/csdgm"  [...]
+<csw:Acknowledgement xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" timeStamp="PYCSW_TIMESTAMP">
   <csw:EchoedRequest>
     <csw:GetRecords service="CSW" version="2.0.2" resultType="validate" startPosition="1" maxRecords="5" outputFormat="application/xml" outputSchema="http://www.opengis.net/cat/csw/2.0.2" xsi:schemaLocation="http://www.opengis.net/cat/csw/2.0.2 http://schemas.opengis.net/csw/2.0.2/CSW-discovery.xsd">
 	<csw:Query typeNames="csw:Record">
diff --git a/tests/expected/suites_default_post_GetRecords-all-sortby-bbox.xml b/tests/expected/suites_default_post_GetRecords-all-sortby-bbox.xml
index 31e38d7..e6bb272 100644
--- a/tests/expected/suites_default_post_GetRecords-all-sortby-bbox.xml
+++ b/tests/expected/suites_default_post_GetRecords-all-sortby-bbox.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<csw:GetRecordsResponse xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ows="http://www.opengis.net/ows" xmlns:fgdc="http://www.opengis.net/cat/csw/csdg [...]
+<csw:GetRecordsResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.0.2" xsi:schemaLocation="http://www.opengis.net/cat/csw/2.0.2 http://schemas.opengis.net/csw/2.0.2/CSW-di [...]
   <csw:SearchStatus timestamp="PYCSW_TIMESTAMP"/>
   <csw:SearchResults nextRecord="6" numberOfRecordsMatched="12" numberOfRecordsReturned="5" recordSchema="http://www.opengis.net/cat/csw/2.0.2" elementSet="full">
     <csw:Record>
diff --git a/tests/expected/suites_default_post_GetRecords-all.xml b/tests/expected/suites_default_post_GetRecords-all.xml
index f2037f4..97ead2e 100644
--- a/tests/expected/suites_default_post_GetRecords-all.xml
+++ b/tests/expected/suites_default_post_GetRecords-all.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<csw:GetRecordsResponse xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ows="http://www.opengis.net/ows" xmlns:fgdc="http://www.opengis.net/cat/csw/csdg [...]
+<csw:GetRecordsResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.0.2" xsi:schemaLocation="http://www.opengis.net/cat/csw/2.0.2 http://schemas.opengis.net/csw/2.0.2/CSW-di [...]
   <csw:SearchStatus timestamp="PYCSW_TIMESTAMP"/>
   <csw:SearchResults nextRecord="6" numberOfRecordsMatched="12" numberOfRecordsReturned="5" recordSchema="http://www.opengis.net/cat/csw/2.0.2" elementSet="full">
     <csw:Record>
diff --git a/tests/expected/suites_default_post_GetRecords-bbox-filter-crs84.xml b/tests/expected/suites_default_post_GetRecords-bbox-filter-crs84.xml
index e23dfc3..97de18a 100644
--- a/tests/expected/suites_default_post_GetRecords-bbox-filter-crs84.xml
+++ b/tests/expected/suites_default_post_GetRecords-bbox-filter-crs84.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<csw:GetRecordsResponse xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ows="http://www.opengis.net/ows" xmlns:fgdc="http://www.opengis.net/cat/csw/csdg [...]
+<csw:GetRecordsResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.0.2" xsi:schemaLocation="http://www.opengis.net/cat/csw/2.0.2 http://schemas.opengis.net/csw/2.0.2/CSW-di [...]
   <csw:SearchStatus timestamp="PYCSW_TIMESTAMP"/>
   <csw:SearchResults nextRecord="0" numberOfRecordsMatched="3" numberOfRecordsReturned="3" recordSchema="http://www.opengis.net/cat/csw/2.0.2" elementSet="brief">
     <csw:BriefRecord>
diff --git a/tests/expected/suites_default_post_GetRecords-cql-title.xml b/tests/expected/suites_default_post_GetRecords-cql-title.xml
index a9585ef..47493bb 100644
--- a/tests/expected/suites_default_post_GetRecords-cql-title.xml
+++ b/tests/expected/suites_default_post_GetRecords-cql-title.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<csw:GetRecordsResponse xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ows="http://www.opengis.net/ows" xmlns:fgdc="http://www.opengis.net/cat/csw/csdg [...]
+<csw:GetRecordsResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.0.2" xsi:schemaLocation="http://www.opengis.net/cat/csw/2.0.2 http://schemas.opengis.net/csw/2.0.2/CSW-di [...]
   <csw:SearchStatus timestamp="PYCSW_TIMESTAMP"/>
   <csw:SearchResults nextRecord="0" numberOfRecordsMatched="2" numberOfRecordsReturned="2" recordSchema="http://www.opengis.net/cat/csw/2.0.2" elementSet="brief">
     <csw:BriefRecord>
diff --git a/tests/expected/suites_default_post_GetRecords-distributedsearch.xml b/tests/expected/suites_default_post_GetRecords-distributedsearch.xml
index 5214e3f..d8f0c0f 100644
--- a/tests/expected/suites_default_post_GetRecords-distributedsearch.xml
+++ b/tests/expected/suites_default_post_GetRecords-distributedsearch.xml
@@ -1,10 +1,10 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<csw:GetRecordsResponse xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ows="http://www.opengis.net/ows" xmlns:fgdc="http://www.opengis.net/cat/csw/csdg [...]
+<csw:GetRecordsResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.0.2" xsi:schemaLocation="http://www.opengis.net/cat/csw/2.0.2 http://schemas.opengis.net/csw/2.0.2/CSW-di [...]
   <csw:SearchStatus timestamp="PYCSW_TIMESTAMP"/>
   <csw:SearchResults nextRecord="0" numberOfRecordsMatched="1" numberOfRecordsReturned="1" recordSchema="http://www.opengis.net/cat/csw/2.0.2" elementSet="brief">
     <!-- 1 result from http://demo.pycsw.org/gisdata/csw -->
-    <csw:BriefRecord xmlns:fes20="http://www.opengis.net/fes/2.0" xmlns:inspire_common="http://inspire.ec.europa.eu/schemas/common/1.0" xmlns:rim="urn:oasis:names:tc:ebxml-regrep:xsd:rim:3.0" xmlns:ows20="http://www.opengis.net/ows/2.0" xmlns:ebrim="http://www.opengis.net/cat/wrs/1.0" xmlns:gco="http://www.isotc211.org/2005/gco" xmlns:inspire_ds="http://inspire.ec.europa.eu/schemas/inspire_ds/1.0" xmlns:wrs="http://www.opengis.net/cat/wrs/1.0" xmlns:ows11="http://www.opengis.net/ows/1.1" [...]
+    <csw:BriefRecord>
       <dc:identifier>urn:uuid:dd87919a-e399-11e5-8327-aa0000ae6bfc</dc:identifier>
       <dc:title>Aquifers</dc:title>
       <dc:type>vector digital data</dc:type>
diff --git a/tests/expected/suites_default_post_GetRecords-elementname.xml b/tests/expected/suites_default_post_GetRecords-elementname.xml
index 4c52475..29fbf63 100644
--- a/tests/expected/suites_default_post_GetRecords-elementname.xml
+++ b/tests/expected/suites_default_post_GetRecords-elementname.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<csw:GetRecordsResponse xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ows="http://www.opengis.net/ows" xmlns:fgdc="http://www.opengis.net/cat/csw/csdg [...]
+<csw:GetRecordsResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.0.2" xsi:schemaLocation="http://www.opengis.net/cat/csw/2.0.2 http://schemas.opengis.net/csw/2.0.2/CSW-di [...]
   <csw:SearchStatus timestamp="PYCSW_TIMESTAMP"/>
   <csw:SearchResults nextRecord="6" numberOfRecordsMatched="12" numberOfRecordsReturned="5" recordSchema="http://www.opengis.net/cat/csw/2.0.2">
     <csw:Record>
diff --git a/tests/expected/suites_default_post_GetRecords-end.xml b/tests/expected/suites_default_post_GetRecords-end.xml
index c5f0e68..814be1f 100644
--- a/tests/expected/suites_default_post_GetRecords-end.xml
+++ b/tests/expected/suites_default_post_GetRecords-end.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<csw:GetRecordsResponse xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ows="http://www.opengis.net/ows" xmlns:fgdc="http://www.opengis.net/cat/csw/csdg [...]
+<csw:GetRecordsResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.0.2" xsi:schemaLocation="http://www.opengis.net/cat/csw/2.0.2 http://schemas.opengis.net/csw/2.0.2/CSW-di [...]
   <csw:SearchStatus timestamp="PYCSW_TIMESTAMP"/>
   <csw:SearchResults nextRecord="0" numberOfRecordsMatched="12" numberOfRecordsReturned="5" recordSchema="http://www.opengis.net/cat/csw/2.0.2" elementSet="full">
     <csw:Record>
diff --git a/tests/expected/suites_default_post_GetRecords-filter-and-bbox-freetext.xml b/tests/expected/suites_default_post_GetRecords-filter-and-bbox-freetext.xml
index a21b883..e45a6a2 100644
--- a/tests/expected/suites_default_post_GetRecords-filter-and-bbox-freetext.xml
+++ b/tests/expected/suites_default_post_GetRecords-filter-and-bbox-freetext.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<csw:GetRecordsResponse xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ows="http://www.opengis.net/ows" xmlns:fgdc="http://www.opengis.net/cat/csw/csdg [...]
+<csw:GetRecordsResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.0.2" xsi:schemaLocation="http://www.opengis.net/cat/csw/2.0.2 http://schemas.opengis.net/csw/2.0.2/CSW-di [...]
   <csw:SearchStatus timestamp="PYCSW_TIMESTAMP"/>
   <csw:SearchResults nextRecord="0" numberOfRecordsMatched="1" numberOfRecordsReturned="1" recordSchema="http://www.opengis.net/cat/csw/2.0.2" elementSet="brief">
     <csw:BriefRecord>
diff --git a/tests/expected/suites_default_post_GetRecords-filter-and-nested-or.xml b/tests/expected/suites_default_post_GetRecords-filter-and-nested-or.xml
index d78674f..a05b856 100644
--- a/tests/expected/suites_default_post_GetRecords-filter-and-nested-or.xml
+++ b/tests/expected/suites_default_post_GetRecords-filter-and-nested-or.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<csw:GetRecordsResponse xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ows="http://www.opengis.net/ows" xmlns:fgdc="http://www.opengis.net/cat/csw/csdg [...]
+<csw:GetRecordsResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.0.2" xsi:schemaLocation="http://www.opengis.net/cat/csw/2.0.2 http://schemas.opengis.net/csw/2.0.2/CSW-di [...]
   <csw:SearchStatus timestamp="PYCSW_TIMESTAMP"/>
   <csw:SearchResults nextRecord="0" numberOfRecordsMatched="1" numberOfRecordsReturned="1" recordSchema="http://www.opengis.net/cat/csw/2.0.2" elementSet="full">
     <csw:Record>
diff --git a/tests/expected/suites_default_post_GetRecords-filter-and-nested-or2.xml b/tests/expected/suites_default_post_GetRecords-filter-and-nested-or2.xml
index 30f9498..2b1accd 100644
--- a/tests/expected/suites_default_post_GetRecords-filter-and-nested-or2.xml
+++ b/tests/expected/suites_default_post_GetRecords-filter-and-nested-or2.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<csw:GetRecordsResponse xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ows="http://www.opengis.net/ows" xmlns:fgdc="http://www.opengis.net/cat/csw/csdg [...]
+<csw:GetRecordsResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.0.2" xsi:schemaLocation="http://www.opengis.net/cat/csw/2.0.2 http://schemas.opengis.net/csw/2.0.2/CSW-di [...]
   <csw:SearchStatus timestamp="PYCSW_TIMESTAMP"/>
   <csw:SearchResults nextRecord="0" numberOfRecordsMatched="2" numberOfRecordsReturned="2" recordSchema="http://www.opengis.net/cat/csw/2.0.2" elementSet="full">
     <csw:Record>
diff --git a/tests/expected/suites_default_post_GetRecords-filter-anytext-and-not.xml b/tests/expected/suites_default_post_GetRecords-filter-anytext-and-not.xml
index e73b39f..d758ab9 100644
--- a/tests/expected/suites_default_post_GetRecords-filter-anytext-and-not.xml
+++ b/tests/expected/suites_default_post_GetRecords-filter-anytext-and-not.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<csw:GetRecordsResponse xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ows="http://www.opengis.net/ows" xmlns:fgdc="http://www.opengis.net/cat/csw/csdg [...]
+<csw:GetRecordsResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.0.2" xsi:schemaLocation="http://www.opengis.net/cat/csw/2.0.2 http://schemas.opengis.net/csw/2.0.2/CSW-di [...]
   <csw:SearchStatus timestamp="PYCSW_TIMESTAMP"/>
   <csw:SearchResults nextRecord="0" numberOfRecordsMatched="1" numberOfRecordsReturned="1" recordSchema="http://www.opengis.net/cat/csw/2.0.2" elementSet="summary">
     <csw:SummaryRecord>
diff --git a/tests/expected/suites_default_post_GetRecords-filter-anytext-equal.xml b/tests/expected/suites_default_post_GetRecords-filter-anytext-equal.xml
index 5054dae..3b34891 100644
--- a/tests/expected/suites_default_post_GetRecords-filter-anytext-equal.xml
+++ b/tests/expected/suites_default_post_GetRecords-filter-anytext-equal.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<csw:GetRecordsResponse xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ows="http://www.opengis.net/ows" xmlns:fgdc="http://www.opengis.net/cat/csw/csdg [...]
+<csw:GetRecordsResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.0.2" xsi:schemaLocation="http://www.opengis.net/cat/csw/2.0.2 http://schemas.opengis.net/csw/2.0.2/CSW-di [...]
   <csw:SearchStatus timestamp="PYCSW_TIMESTAMP"/>
   <csw:SearchResults nextRecord="0" numberOfRecordsMatched="5" numberOfRecordsReturned="5" recordSchema="http://www.opengis.net/cat/csw/2.0.2" elementSet="brief">
     <csw:BriefRecord>
diff --git a/tests/expected/suites_default_post_GetRecords-filter-anytext.xml b/tests/expected/suites_default_post_GetRecords-filter-anytext.xml
index 5054dae..3b34891 100644
--- a/tests/expected/suites_default_post_GetRecords-filter-anytext.xml
+++ b/tests/expected/suites_default_post_GetRecords-filter-anytext.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<csw:GetRecordsResponse xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ows="http://www.opengis.net/ows" xmlns:fgdc="http://www.opengis.net/cat/csw/csdg [...]
+<csw:GetRecordsResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.0.2" xsi:schemaLocation="http://www.opengis.net/cat/csw/2.0.2 http://schemas.opengis.net/csw/2.0.2/CSW-di [...]
   <csw:SearchStatus timestamp="PYCSW_TIMESTAMP"/>
   <csw:SearchResults nextRecord="0" numberOfRecordsMatched="5" numberOfRecordsReturned="5" recordSchema="http://www.opengis.net/cat/csw/2.0.2" elementSet="brief">
     <csw:BriefRecord>
diff --git a/tests/expected/suites_default_post_GetRecords-filter-bbox-reproject.xml b/tests/expected/suites_default_post_GetRecords-filter-bbox-reproject.xml
index e650f15..8f98b1d 100644
--- a/tests/expected/suites_default_post_GetRecords-filter-bbox-reproject.xml
+++ b/tests/expected/suites_default_post_GetRecords-filter-bbox-reproject.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<csw:GetRecordsResponse xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ows="http://www.opengis.net/ows" xmlns:fgdc="http://www.opengis.net/cat/csw/csdg [...]
+<csw:GetRecordsResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.0.2" xsi:schemaLocation="http://www.opengis.net/cat/csw/2.0.2 http://schemas.opengis.net/csw/2.0.2/CSW-di [...]
   <csw:SearchStatus timestamp="PYCSW_TIMESTAMP"/>
   <csw:SearchResults nextRecord="0" numberOfRecordsMatched="2" numberOfRecordsReturned="2" recordSchema="http://www.opengis.net/cat/csw/2.0.2" elementSet="brief">
     <csw:BriefRecord>
diff --git a/tests/expected/suites_default_post_GetRecords-filter-bbox-sortby.xml b/tests/expected/suites_default_post_GetRecords-filter-bbox-sortby.xml
index 4b7f8a6..bb2e920 100644
--- a/tests/expected/suites_default_post_GetRecords-filter-bbox-sortby.xml
+++ b/tests/expected/suites_default_post_GetRecords-filter-bbox-sortby.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<csw:GetRecordsResponse xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ows="http://www.opengis.net/ows" xmlns:fgdc="http://www.opengis.net/cat/csw/csdg [...]
+<csw:GetRecordsResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.0.2" xsi:schemaLocation="http://www.opengis.net/cat/csw/2.0.2 http://schemas.opengis.net/csw/2.0.2/CSW-di [...]
   <csw:SearchStatus timestamp="PYCSW_TIMESTAMP"/>
   <csw:SearchResults nextRecord="0" numberOfRecordsMatched="2" numberOfRecordsReturned="2" recordSchema="http://www.opengis.net/cat/csw/2.0.2" elementSet="brief">
     <csw:BriefRecord>
diff --git a/tests/expected/suites_default_post_GetRecords-filter-bbox.xml b/tests/expected/suites_default_post_GetRecords-filter-bbox.xml
index e650f15..8f98b1d 100644
--- a/tests/expected/suites_default_post_GetRecords-filter-bbox.xml
+++ b/tests/expected/suites_default_post_GetRecords-filter-bbox.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<csw:GetRecordsResponse xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ows="http://www.opengis.net/ows" xmlns:fgdc="http://www.opengis.net/cat/csw/csdg [...]
+<csw:GetRecordsResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.0.2" xsi:schemaLocation="http://www.opengis.net/cat/csw/2.0.2 http://schemas.opengis.net/csw/2.0.2/CSW-di [...]
   <csw:SearchStatus timestamp="PYCSW_TIMESTAMP"/>
   <csw:SearchResults nextRecord="0" numberOfRecordsMatched="2" numberOfRecordsReturned="2" recordSchema="http://www.opengis.net/cat/csw/2.0.2" elementSet="brief">
     <csw:BriefRecord>
diff --git a/tests/expected/suites_default_post_GetRecords-filter-between.xml b/tests/expected/suites_default_post_GetRecords-filter-between.xml
index 714098f..37d7586 100644
--- a/tests/expected/suites_default_post_GetRecords-filter-between.xml
+++ b/tests/expected/suites_default_post_GetRecords-filter-between.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<csw:GetRecordsResponse xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ows="http://www.opengis.net/ows" xmlns:fgdc="http://www.opengis.net/cat/csw/csdg [...]
+<csw:GetRecordsResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.0.2" xsi:schemaLocation="http://www.opengis.net/cat/csw/2.0.2 http://schemas.opengis.net/csw/2.0.2/CSW-di [...]
   <csw:SearchStatus timestamp="PYCSW_TIMESTAMP"/>
   <csw:SearchResults nextRecord="0" numberOfRecordsMatched="5" numberOfRecordsReturned="5" recordSchema="http://www.opengis.net/cat/csw/2.0.2" elementSet="full">
     <csw:Record>
diff --git a/tests/expected/suites_default_post_GetRecords-filter-function-bad.xml b/tests/expected/suites_default_post_GetRecords-filter-function-bad.xml
index f16dab9..bc63e84 100644
--- a/tests/expected/suites_default_post_GetRecords-filter-function-bad.xml
+++ b/tests/expected/suites_default_post_GetRecords-filter-function-bad.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<ows:ExceptionReport xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ows="http://www.opengis.net/ows" xmlns:fgdc="http://www.opengis.net/cat/csw/csdgm"  [...]
+<ows:ExceptionReport xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" language="en-US" version="1.2.0" xsi:schemaLocation="http://www.opengis.net/ows http://schemas.opengis.net/ows/1.0.0/ow [...]
   <ows:Exception exceptionCode="InvalidParameterValue" locator="service">
     <ows:ExceptionText>Invalid Constraint: Invalid Filter request: Invalid ogc:Function: foo</ows:ExceptionText>
   </ows:Exception>
diff --git a/tests/expected/suites_default_post_GetRecords-filter-function.xml b/tests/expected/suites_default_post_GetRecords-filter-function.xml
index 6a9d175..4ed61a2 100644
--- a/tests/expected/suites_default_post_GetRecords-filter-function.xml
+++ b/tests/expected/suites_default_post_GetRecords-filter-function.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<csw:GetRecordsResponse xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ows="http://www.opengis.net/ows" xmlns:fgdc="http://www.opengis.net/cat/csw/csdg [...]
+<csw:GetRecordsResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.0.2" xsi:schemaLocation="http://www.opengis.net/cat/csw/2.0.2 http://schemas.opengis.net/csw/2.0.2/CSW-di [...]
   <csw:SearchStatus timestamp="PYCSW_TIMESTAMP"/>
   <csw:SearchResults nextRecord="0" numberOfRecordsMatched="1" numberOfRecordsReturned="1" recordSchema="http://www.opengis.net/cat/csw/2.0.2" elementSet="brief">
     <csw:BriefRecord>
diff --git a/tests/expected/suites_default_post_GetRecords-filter-not-bbox.xml b/tests/expected/suites_default_post_GetRecords-filter-not-bbox.xml
index 63df9c1..03686d4 100644
--- a/tests/expected/suites_default_post_GetRecords-filter-not-bbox.xml
+++ b/tests/expected/suites_default_post_GetRecords-filter-not-bbox.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<csw:GetRecordsResponse xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ows="http://www.opengis.net/ows" xmlns:fgdc="http://www.opengis.net/cat/csw/csdg [...]
+<csw:GetRecordsResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.0.2" xsi:schemaLocation="http://www.opengis.net/cat/csw/2.0.2 http://schemas.opengis.net/csw/2.0.2/CSW-di [...]
   <csw:SearchStatus timestamp="PYCSW_TIMESTAMP"/>
   <csw:SearchResults nextRecord="6" numberOfRecordsMatched="10" numberOfRecordsReturned="5" recordSchema="http://www.opengis.net/cat/csw/2.0.2" elementSet="brief">
     <csw:BriefRecord>
diff --git a/tests/expected/suites_default_post_GetRecords-filter-or-bbox-freetext.xml b/tests/expected/suites_default_post_GetRecords-filter-or-bbox-freetext.xml
index e650f15..8f98b1d 100644
--- a/tests/expected/suites_default_post_GetRecords-filter-or-bbox-freetext.xml
+++ b/tests/expected/suites_default_post_GetRecords-filter-or-bbox-freetext.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<csw:GetRecordsResponse xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ows="http://www.opengis.net/ows" xmlns:fgdc="http://www.opengis.net/cat/csw/csdg [...]
+<csw:GetRecordsResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.0.2" xsi:schemaLocation="http://www.opengis.net/cat/csw/2.0.2 http://schemas.opengis.net/csw/2.0.2/CSW-di [...]
   <csw:SearchStatus timestamp="PYCSW_TIMESTAMP"/>
   <csw:SearchResults nextRecord="0" numberOfRecordsMatched="2" numberOfRecordsReturned="2" recordSchema="http://www.opengis.net/cat/csw/2.0.2" elementSet="brief">
     <csw:BriefRecord>
diff --git a/tests/expected/suites_default_post_GetRecords-filter-or-nested-and.xml b/tests/expected/suites_default_post_GetRecords-filter-or-nested-and.xml
index 9097cea..077ef2f 100644
--- a/tests/expected/suites_default_post_GetRecords-filter-or-nested-and.xml
+++ b/tests/expected/suites_default_post_GetRecords-filter-or-nested-and.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<csw:GetRecordsResponse xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ows="http://www.opengis.net/ows" xmlns:fgdc="http://www.opengis.net/cat/csw/csdg [...]
+<csw:GetRecordsResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.0.2" xsi:schemaLocation="http://www.opengis.net/cat/csw/2.0.2 http://schemas.opengis.net/csw/2.0.2/CSW-di [...]
   <csw:SearchStatus timestamp="PYCSW_TIMESTAMP"/>
   <csw:SearchResults nextRecord="0" numberOfRecordsMatched="6" numberOfRecordsReturned="6" recordSchema="http://www.opengis.net/cat/csw/2.0.2" elementSet="full">
     <csw:Record>
diff --git a/tests/expected/suites_default_post_GetRecords-filter-or-title-abstract.xml b/tests/expected/suites_default_post_GetRecords-filter-or-title-abstract.xml
index f9c551d..0f34eb3 100644
--- a/tests/expected/suites_default_post_GetRecords-filter-or-title-abstract.xml
+++ b/tests/expected/suites_default_post_GetRecords-filter-or-title-abstract.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<csw:GetRecordsResponse xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ows="http://www.opengis.net/ows" xmlns:fgdc="http://www.opengis.net/cat/csw/csdg [...]
+<csw:GetRecordsResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.0.2" xsi:schemaLocation="http://www.opengis.net/cat/csw/2.0.2 http://schemas.opengis.net/csw/2.0.2/CSW-di [...]
   <csw:SearchStatus timestamp="PYCSW_TIMESTAMP"/>
   <csw:SearchResults nextRecord="0" numberOfRecordsMatched="1" numberOfRecordsReturned="1" recordSchema="http://www.opengis.net/cat/csw/2.0.2" elementSet="full">
     <csw:Record>
diff --git a/tests/expected/suites_default_post_GetRecords-maxrecords.xml b/tests/expected/suites_default_post_GetRecords-maxrecords.xml
index be156e1..bd4275d 100644
--- a/tests/expected/suites_default_post_GetRecords-maxrecords.xml
+++ b/tests/expected/suites_default_post_GetRecords-maxrecords.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<csw:GetRecordsResponse xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ows="http://www.opengis.net/ows" xmlns:fgdc="http://www.opengis.net/cat/csw/csdg [...]
+<csw:GetRecordsResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.0.2" xsi:schemaLocation="http://www.opengis.net/cat/csw/2.0.2 http://schemas.opengis.net/csw/2.0.2/CSW-di [...]
   <csw:SearchStatus timestamp="PYCSW_TIMESTAMP"/>
   <csw:SearchResults nextRecord="2" numberOfRecordsMatched="12" numberOfRecordsReturned="1" recordSchema="http://www.opengis.net/cat/csw/2.0.2" elementSet="full">
     <csw:Record>
diff --git a/tests/expected/suites_default_post_GetRecords-requestid.xml b/tests/expected/suites_default_post_GetRecords-requestid.xml
index 751cef1..31d2019 100644
--- a/tests/expected/suites_default_post_GetRecords-requestid.xml
+++ b/tests/expected/suites_default_post_GetRecords-requestid.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<csw:GetRecordsResponse xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ows="http://www.opengis.net/ows" xmlns:fgdc="http://www.opengis.net/cat/csw/csdg [...]
+<csw:GetRecordsResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.0.2" xsi:schemaLocation="http://www.opengis.net/cat/csw/2.0.2 http://schemas.opengis.net/csw/2.0.2/CSW-di [...]
   <csw:RequestId>ce74a6c8-677a-42b3-a07c-ce44df8ce7ab</csw:RequestId>
   <csw:SearchStatus timestamp="PYCSW_TIMESTAMP"/>
   <csw:SearchResults nextRecord="6" numberOfRecordsMatched="12" numberOfRecordsReturned="5" recordSchema="http://www.opengis.net/cat/csw/2.0.2" elementSet="full">
diff --git a/tests/expected/suites_default_post_Harvest-default.xml b/tests/expected/suites_default_post_Harvest-default.xml
index f9fe731..169151f 100644
--- a/tests/expected/suites_default_post_Harvest-default.xml
+++ b/tests/expected/suites_default_post_Harvest-default.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<ows:ExceptionReport xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ows="http://www.opengis.net/ows" xmlns:fgdc="http://www.opengis.net/cat/csw/csdgm"  [...]
+<ows:ExceptionReport xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" language="en-US" version="1.2.0" xsi:schemaLocation="http://www.opengis.net/ows http://schemas.opengis.net/ows/1.0.0/ow [...]
   <ows:Exception exceptionCode="OperationNotSupported" locator="request">
     <ows:ExceptionText>Harvest operations are not supported</ows:ExceptionText>
   </ows:Exception>
diff --git a/tests/expected/suites_default_post_Harvest-response-handler.xml b/tests/expected/suites_default_post_Harvest-response-handler.xml
index f9fe731..169151f 100644
--- a/tests/expected/suites_default_post_Harvest-response-handler.xml
+++ b/tests/expected/suites_default_post_Harvest-response-handler.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<ows:ExceptionReport xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ows="http://www.opengis.net/ows" xmlns:fgdc="http://www.opengis.net/cat/csw/csdgm"  [...]
+<ows:ExceptionReport xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" language="en-US" version="1.2.0" xsi:schemaLocation="http://www.opengis.net/ows http://schemas.opengis.net/ows/1.0.0/ow [...]
   <ows:Exception exceptionCode="OperationNotSupported" locator="request">
     <ows:ExceptionText>Harvest operations are not supported</ows:ExceptionText>
   </ows:Exception>
diff --git a/tests/expected/suites_default_post_Transaction-delete.xml b/tests/expected/suites_default_post_Transaction-delete.xml
index 131e251..2b4a6e3 100644
--- a/tests/expected/suites_default_post_Transaction-delete.xml
+++ b/tests/expected/suites_default_post_Transaction-delete.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<ows:ExceptionReport xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ows="http://www.opengis.net/ows" xmlns:fgdc="http://www.opengis.net/cat/csw/csdgm"  [...]
+<ows:ExceptionReport xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" language="en-US" version="1.2.0" xsi:schemaLocation="http://www.opengis.net/ows http://schemas.opengis.net/ows/1.0.0/ow [...]
   <ows:Exception exceptionCode="InvalidParameterValue" locator="service">
     <ows:ExceptionText>Invalid Constraint: Invalid Filter request: Invalid PropertyName: apiso:Identifier.  'apiso:Identifier'</ows:ExceptionText>
   </ows:Exception>
diff --git a/tests/expected/suites_default_post_Transaction-insert.xml b/tests/expected/suites_default_post_Transaction-insert.xml
index c2449ce..f5df4c6 100644
--- a/tests/expected/suites_default_post_Transaction-insert.xml
+++ b/tests/expected/suites_default_post_Transaction-insert.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<ows:ExceptionReport xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ows="http://www.opengis.net/ows" xmlns:fgdc="http://www.opengis.net/cat/csw/csdgm"  [...]
+<ows:ExceptionReport xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" language="en-US" version="1.2.0" xsi:schemaLocation="http://www.opengis.net/ows http://schemas.opengis.net/ows/1.0.0/ow [...]
   <ows:Exception exceptionCode="OperationNotSupported" locator="request">
     <ows:ExceptionText>Transaction operations are not supported</ows:ExceptionText>
   </ows:Exception>
diff --git a/tests/expected/suites_default_post_Transaction-update-full.xml b/tests/expected/suites_default_post_Transaction-update-full.xml
index c2449ce..f5df4c6 100644
--- a/tests/expected/suites_default_post_Transaction-update-full.xml
+++ b/tests/expected/suites_default_post_Transaction-update-full.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<ows:ExceptionReport xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ows="http://www.opengis.net/ows" xmlns:fgdc="http://www.opengis.net/cat/csw/csdgm"  [...]
+<ows:ExceptionReport xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" language="en-US" version="1.2.0" xsi:schemaLocation="http://www.opengis.net/ows http://schemas.opengis.net/ows/1.0.0/ow [...]
   <ows:Exception exceptionCode="OperationNotSupported" locator="request">
     <ows:ExceptionText>Transaction operations are not supported</ows:ExceptionText>
   </ows:Exception>
diff --git a/tests/expected/suites_default_post_Transaction-update-recordproperty.xml b/tests/expected/suites_default_post_Transaction-update-recordproperty.xml
index c2449ce..f5df4c6 100644
--- a/tests/expected/suites_default_post_Transaction-update-recordproperty.xml
+++ b/tests/expected/suites_default_post_Transaction-update-recordproperty.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<ows:ExceptionReport xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ows="http://www.opengis.net/ows" xmlns:fgdc="http://www.opengis.net/cat/csw/csdgm"  [...]
+<ows:ExceptionReport xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" language="en-US" version="1.2.0" xsi:schemaLocation="http://www.opengis.net/ows http://schemas.opengis.net/ows/1.0.0/ow [...]
   <ows:Exception exceptionCode="OperationNotSupported" locator="request">
     <ows:ExceptionText>Transaction operations are not supported</ows:ExceptionText>
   </ows:Exception>
diff --git a/tests/expected/suites_dif_post_DescribeRecord.xml b/tests/expected/suites_dif_post_DescribeRecord.xml
index 04284a4..5f82a7d 100644
--- a/tests/expected/suites_dif_post_DescribeRecord.xml
+++ b/tests/expected/suites_dif_post_DescribeRecord.xml
@@ -1,3 +1,3 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<csw:DescribeRecordResponse xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ows="http://www.opengis.net/ows" xmlns:fgdc="http://www.opengis.net/cat/csw/ [...]
+<csw:DescribeRecordResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/cat/csw/2.0.2 http://schemas.opengis.net/csw/2.0.2/CSW-discovery.xsd"/>
diff --git a/tests/expected/suites_dif_post_GetCapabilities.xml b/tests/expected/suites_dif_post_GetCapabilities.xml
index 2dacf0c..e062f22 100644
--- a/tests/expected/suites_dif_post_GetCapabilities.xml
+++ b/tests/expected/suites_dif_post_GetCapabilities.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<csw:Capabilities xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ows="http://www.opengis.net/ows" xmlns:fgdc="http://www.opengis.net/cat/csw/csdgm" xml [...]
+<csw:Capabilities xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ogc="http://www.opengis.net/ogc" xmlns:ows="http://www.opengis.net/ows" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" updateSequence="PYCSW_UPDATESEQUENCE" ve [...]
   <ows:ServiceIdentification>
     <ows:Title>pycsw Geospatial Catalogue</ows:Title>
     <ows:Abstract>pycsw is an OGC CSW server implementation written in Python</ows:Abstract>
@@ -11,6 +11,7 @@
     </ows:Keywords>
     <ows:ServiceType codeSpace="OGC">CSW</ows:ServiceType>
     <ows:ServiceTypeVersion>2.0.2</ows:ServiceTypeVersion>
+    <ows:ServiceTypeVersion>3.0.0</ows:ServiceTypeVersion>
     <ows:Fees>None</ows:Fees>
     <ows:AccessConstraints>None</ows:AccessConstraints>
   </ows:ServiceIdentification>
@@ -49,19 +50,12 @@
         </ows:HTTP>
       </ows:DCP>
       <ows:Parameter name="sections">
+        <ows:Value>Filter_Capabilities</ows:Value>
+        <ows:Value>OperationsMetadata</ows:Value>
         <ows:Value>ServiceIdentification</ows:Value>
         <ows:Value>ServiceProvider</ows:Value>
-        <ows:Value>OperationsMetadata</ows:Value>
-        <ows:Value>Filter_Capabilities</ows:Value>
       </ows:Parameter>
     </ows:Operation>
-    <ows:Operation name="GetRepositoryItem">
-      <ows:DCP>
-        <ows:HTTP>
-          <ows:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/dif/default.cfg"/>
-        </ows:HTTP>
-      </ows:DCP>
-    </ows:Operation>
     <ows:Operation name="DescribeRecord">
       <ows:DCP>
         <ows:HTTP>
@@ -69,14 +63,14 @@
           <ows:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/dif/default.cfg"/>
         </ows:HTTP>
       </ows:DCP>
-      <ows:Parameter name="schemaLanguage">
-        <ows:Value>http://www.w3.org/XML/Schema</ows:Value>
-        <ows:Value>http://www.w3.org/TR/xmlschema-1/</ows:Value>
-        <ows:Value>http://www.w3.org/2001/XMLSchema</ows:Value>
-      </ows:Parameter>
       <ows:Parameter name="outputFormat">
-        <ows:Value>application/xml</ows:Value>
         <ows:Value>application/json</ows:Value>
+        <ows:Value>application/xml</ows:Value>
+      </ows:Parameter>
+      <ows:Parameter name="schemaLanguage">
+        <ows:Value>http://www.w3.org/2001/XMLSchema</ows:Value>
+        <ows:Value>http://www.w3.org/TR/xmlschema-1/</ows:Value>
+        <ows:Value>http://www.w3.org/XML/Schema</ows:Value>
       </ows:Parameter>
       <ows:Parameter name="typeName">
         <ows:Value>csw:Record</ows:Value>
@@ -90,64 +84,47 @@
         </ows:HTTP>
       </ows:DCP>
       <ows:Parameter name="ParameterName">
+        <ows:Value>DescribeRecord.outputFormat</ows:Value>
+        <ows:Value>DescribeRecord.schemaLanguage</ows:Value>
+        <ows:Value>DescribeRecord.typeName</ows:Value>
+        <ows:Value>GetCapabilities.sections</ows:Value>
+        <ows:Value>GetRecordById.ElementSetName</ows:Value>
+        <ows:Value>GetRecordById.outputFormat</ows:Value>
+        <ows:Value>GetRecordById.outputSchema</ows:Value>
+        <ows:Value>GetRecords.CONSTRAINTLANGUAGE</ows:Value>
+        <ows:Value>GetRecords.ElementSetName</ows:Value>
         <ows:Value>GetRecords.outputFormat</ows:Value>
         <ows:Value>GetRecords.outputSchema</ows:Value>
-        <ows:Value>GetRecords.CONSTRAINTLANGUAGE</ows:Value>
         <ows:Value>GetRecords.resultType</ows:Value>
         <ows:Value>GetRecords.typeNames</ows:Value>
-        <ows:Value>GetRecords.ElementSetName</ows:Value>
-        <ows:Value>GetCapabilities.sections</ows:Value>
-        <ows:Value>GetRecordById.outputFormat</ows:Value>
-        <ows:Value>GetRecordById.outputSchema</ows:Value>
-        <ows:Value>GetRecordById.ElementSetName</ows:Value>
-        <ows:Value>DescribeRecord.schemaLanguage</ows:Value>
-        <ows:Value>DescribeRecord.outputFormat</ows:Value>
-        <ows:Value>DescribeRecord.typeName</ows:Value>
       </ows:Parameter>
     </ows:Operation>
-    <ows:Operation name="GetRecordById">
+    <ows:Operation name="GetRecords">
       <ows:DCP>
         <ows:HTTP>
           <ows:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/dif/default.cfg"/>
           <ows:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/dif/default.cfg"/>
         </ows:HTTP>
       </ows:DCP>
-      <ows:Parameter name="outputFormat">
-        <ows:Value>application/xml</ows:Value>
-        <ows:Value>application/json</ows:Value>
-      </ows:Parameter>
-      <ows:Parameter name="outputSchema">
-        <ows:Value>http://www.opengis.net/cat/csw/2.0.2</ows:Value>
-        <ows:Value>http://www.w3.org/2005/Atom</ows:Value>
-        <ows:Value>http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/</ows:Value>
-        <ows:Value>http://www.opengis.net/cat/csw/csdgm</ows:Value>
+      <ows:Parameter name="CONSTRAINTLANGUAGE">
+        <ows:Value>CQL_TEXT</ows:Value>
+        <ows:Value>FILTER</ows:Value>
       </ows:Parameter>
       <ows:Parameter name="ElementSetName">
         <ows:Value>brief</ows:Value>
-        <ows:Value>summary</ows:Value>
         <ows:Value>full</ows:Value>
+        <ows:Value>summary</ows:Value>
       </ows:Parameter>
-    </ows:Operation>
-    <ows:Operation name="GetRecords">
-      <ows:DCP>
-        <ows:HTTP>
-          <ows:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/dif/default.cfg"/>
-          <ows:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/dif/default.cfg"/>
-        </ows:HTTP>
-      </ows:DCP>
       <ows:Parameter name="outputFormat">
-        <ows:Value>application/xml</ows:Value>
         <ows:Value>application/json</ows:Value>
+        <ows:Value>application/xml</ows:Value>
       </ows:Parameter>
       <ows:Parameter name="outputSchema">
-        <ows:Value>http://www.opengis.net/cat/csw/2.0.2</ows:Value>
-        <ows:Value>http://www.w3.org/2005/Atom</ows:Value>
         <ows:Value>http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/</ows:Value>
+        <ows:Value>http://www.interlis.ch/INTERLIS2.3</ows:Value>
+        <ows:Value>http://www.opengis.net/cat/csw/2.0.2</ows:Value>
         <ows:Value>http://www.opengis.net/cat/csw/csdgm</ows:Value>
-      </ows:Parameter>
-      <ows:Parameter name="CONSTRAINTLANGUAGE">
-        <ows:Value>FILTER</ows:Value>
-        <ows:Value>CQL_TEXT</ows:Value>
+        <ows:Value>http://www.w3.org/2005/Atom</ows:Value>
       </ows:Parameter>
       <ows:Parameter name="resultType">
         <ows:Value>hits</ows:Value>
@@ -157,39 +134,66 @@
       <ows:Parameter name="typeNames">
         <ows:Value>csw:Record</ows:Value>
       </ows:Parameter>
-      <ows:Parameter name="ElementSetName">
-        <ows:Value>brief</ows:Value>
-        <ows:Value>summary</ows:Value>
-        <ows:Value>full</ows:Value>
-      </ows:Parameter>
       <ows:Constraint name="SupportedDublinCoreQueryables">
+        <ows:Value>csw:AnyText</ows:Value>
         <ows:Value>dc:contributor</ows:Value>
-        <ows:Value>dc:source</ows:Value>
-        <ows:Value>dc:language</ows:Value>
-        <ows:Value>dc:title</ows:Value>
-        <ows:Value>dc:subject</ows:Value>
         <ows:Value>dc:creator</ows:Value>
-        <ows:Value>dc:type</ows:Value>
-        <ows:Value>ows:BoundingBox</ows:Value>
-        <ows:Value>dct:modified</ows:Value>
-        <ows:Value>dct:abstract</ows:Value>
-        <ows:Value>dc:relation</ows:Value>
         <ows:Value>dc:date</ows:Value>
+        <ows:Value>dc:format</ows:Value>
         <ows:Value>dc:identifier</ows:Value>
+        <ows:Value>dc:language</ows:Value>
         <ows:Value>dc:publisher</ows:Value>
-        <ows:Value>dc:format</ows:Value>
-        <ows:Value>csw:AnyText</ows:Value>
+        <ows:Value>dc:relation</ows:Value>
         <ows:Value>dc:rights</ows:Value>
+        <ows:Value>dc:source</ows:Value>
+        <ows:Value>dc:subject</ows:Value>
+        <ows:Value>dc:title</ows:Value>
+        <ows:Value>dc:type</ows:Value>
+        <ows:Value>dct:abstract</ows:Value>
+        <ows:Value>dct:modified</ows:Value>
+        <ows:Value>ows:BoundingBox</ows:Value>
       </ows:Constraint>
     </ows:Operation>
-    <ows:Parameter name="version">
-      <ows:Value>2.0.2</ows:Value>
-    </ows:Parameter>
+    <ows:Operation name="GetRecordById">
+      <ows:DCP>
+        <ows:HTTP>
+          <ows:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/dif/default.cfg"/>
+          <ows:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/dif/default.cfg"/>
+        </ows:HTTP>
+      </ows:DCP>
+      <ows:Parameter name="ElementSetName">
+        <ows:Value>brief</ows:Value>
+        <ows:Value>full</ows:Value>
+        <ows:Value>summary</ows:Value>
+      </ows:Parameter>
+      <ows:Parameter name="outputFormat">
+        <ows:Value>application/json</ows:Value>
+        <ows:Value>application/xml</ows:Value>
+      </ows:Parameter>
+      <ows:Parameter name="outputSchema">
+        <ows:Value>http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/</ows:Value>
+        <ows:Value>http://www.interlis.ch/INTERLIS2.3</ows:Value>
+        <ows:Value>http://www.opengis.net/cat/csw/2.0.2</ows:Value>
+        <ows:Value>http://www.opengis.net/cat/csw/csdgm</ows:Value>
+        <ows:Value>http://www.w3.org/2005/Atom</ows:Value>
+      </ows:Parameter>
+    </ows:Operation>
+    <ows:Operation name="GetRepositoryItem">
+      <ows:DCP>
+        <ows:HTTP>
+          <ows:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/dif/default.cfg"/>
+        </ows:HTTP>
+      </ows:DCP>
+    </ows:Operation>
     <ows:Parameter name="service">
       <ows:Value>CSW</ows:Value>
     </ows:Parameter>
-    <ows:Constraint name="XPathQueryables">
-      <ows:Value>allowed</ows:Value>
+    <ows:Parameter name="version">
+      <ows:Value>2.0.2</ows:Value>
+      <ows:Value>3.0.0</ows:Value>
+    </ows:Parameter>
+    <ows:Constraint name="FederatedCatalogues">
+      <ows:Value>http://geo.data.gov/geoportal/csw/discovery</ows:Value>
     </ows:Constraint>
     <ows:Constraint name="MaxRecordDefault">
       <ows:Value>10</ows:Value>
@@ -198,8 +202,8 @@
       <ows:Value>XML</ows:Value>
       <ows:Value>SOAP</ows:Value>
     </ows:Constraint>
-    <ows:Constraint name="FederatedCatalogues">
-      <ows:Value>http://geo.data.gov/geoportal/csw/discovery</ows:Value>
+    <ows:Constraint name="XPathQueryables">
+      <ows:Value>allowed</ows:Value>
     </ows:Constraint>
   </ows:OperationsMetadata>
   <ogc:Filter_Capabilities>
@@ -229,11 +233,11 @@
       <ogc:ComparisonOperators>
         <ogc:ComparisonOperator>Between</ogc:ComparisonOperator>
         <ogc:ComparisonOperator>EqualTo</ogc:ComparisonOperator>
-        <ogc:ComparisonOperator>LessThanEqualTo</ogc:ComparisonOperator>
         <ogc:ComparisonOperator>GreaterThan</ogc:ComparisonOperator>
-        <ogc:ComparisonOperator>Like</ogc:ComparisonOperator>
-        <ogc:ComparisonOperator>LessThan</ogc:ComparisonOperator>
         <ogc:ComparisonOperator>GreaterThanEqualTo</ogc:ComparisonOperator>
+        <ogc:ComparisonOperator>LessThan</ogc:ComparisonOperator>
+        <ogc:ComparisonOperator>LessThanEqualTo</ogc:ComparisonOperator>
+        <ogc:ComparisonOperator>Like</ogc:ComparisonOperator>
         <ogc:ComparisonOperator>NotEqualTo</ogc:ComparisonOperator>
         <ogc:ComparisonOperator>NullCheck</ogc:ComparisonOperator>
       </ogc:ComparisonOperators>
diff --git a/tests/expected/suites_dif_post_GetRecords-filter-bbox.xml b/tests/expected/suites_dif_post_GetRecords-filter-bbox.xml
index ad3621e..d6a763d 100644
--- a/tests/expected/suites_dif_post_GetRecords-filter-bbox.xml
+++ b/tests/expected/suites_dif_post_GetRecords-filter-bbox.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<csw:GetRecordsResponse xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ows="http://www.opengis.net/ows" xmlns:fgdc="http://www.opengis.net/cat/csw/csdg [...]
+<csw:GetRecordsResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.0.2" xsi:schemaLocation="http://www.opengis.net/ca [...]
   <csw:SearchStatus timestamp="PYCSW_TIMESTAMP"/>
   <csw:SearchResults nextRecord="0" numberOfRecordsMatched="2" numberOfRecordsReturned="2" recordSchema="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" elementSet="brief">
     <dif:DIF xsi:schemaLocation="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/ http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/dif.xsd">
diff --git a/tests/expected/suites_ebrim_post_DescribeRecord.xml b/tests/expected/suites_ebrim_post_DescribeRecord.xml
index 21f4d9b..87e4d86 100644
--- a/tests/expected/suites_ebrim_post_DescribeRecord.xml
+++ b/tests/expected/suites_ebrim_post_DescribeRecord.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<csw:DescribeRecordResponse xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:rim="urn:oasis:names:tc:ebxml-regrep:xsd:rim:3.0" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ows="http://www.open [...]
+<csw:DescribeRecordResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/cat/csw/2.0.2 http://schemas.opengis.net/csw/2.0.2/CSW-discovery.xsd">
   <csw:SchemaComponent schemaLanguage="XMLSCHEMA" targetNamespace="urn:oasis:names:tc:ebxml-regrep:xsd:rim:3.0">
     <xs:schema xmlns:xmime="http://www.w3.org/2005/05/xmlmime" id="wrs" targetNamespace="http://www.opengis.net/cat/wrs/1.0" elementFormDefault="qualified" version="1.0.1">
 
@@ -18,9 +18,9 @@
   </xs:annotation>
     
   <xs:import namespace="urn:oasis:names:tc:ebxml-regrep:xsd:rim:3.0" schemaLocation="http://docs.oasis-open.org/regrep/v3.0/schema/rim.xsd"/>
-  <xs:import namespace="http://www.opengis.net/cat/csw/2.0.2" schemaLocation="../../../../../../../../../../../../pycsw/schemas/ogc/csw/2.0.2/CSW-publication.xsd"/>
-  <xs:import namespace="http://www.w3.org/1999/xlink" schemaLocation="../../../../../../../../../../../../pycsw/schemas/w3c/1999/xlink.xsd"/>
-  <xs:import namespace="http://www.opengis.net/ogc" schemaLocation="../../../../../../../../../../../../pycsw/schemas/ogc/filter/1.1.0/filter.xsd"/>
+  <xs:import namespace="http://www.opengis.net/cat/csw/2.0.2" schemaLocation="http://schemas.opengis.net/csw/2.0.2/CSW-publication.xsd"/>
+  <xs:import namespace="http://www.w3.org/1999/xlink" schemaLocation="http://www.w3.org/1999/xlink.xsd"/>
+  <xs:import namespace="http://www.opengis.net/ogc" schemaLocation="http://schemas.opengis.net/filter/1.1.0/filter.xsd"/>
     
   <xs:element name="Capabilities" type="csw:CapabilitiesType"/>
   <xs:element name="RecordId" type="wrs:RecordIdType" substitutionGroup="ogc:_Id" id="RecordId">
diff --git a/tests/expected/suites_ebrim_post_GetCapabilities.xml b/tests/expected/suites_ebrim_post_GetCapabilities.xml
index 2c9c930..41b60a2 100644
--- a/tests/expected/suites_ebrim_post_GetCapabilities.xml
+++ b/tests/expected/suites_ebrim_post_GetCapabilities.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<csw:Capabilities xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:rim="urn:oasis:names:tc:ebxml-regrep:xsd:rim:3.0" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ows="http://www.opengis.net/ow [...]
+<csw:Capabilities xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ogc="http://www.opengis.net/ogc" xmlns:ows="http://www.opengis.net/ows" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" updateSequence="PYCSW_UPDATESEQUENCE" ve [...]
   <ows:ServiceIdentification>
     <ows:Title>pycsw Geospatial Catalogue</ows:Title>
     <ows:Abstract>pycsw is an OGC CSW server implementation written in Python</ows:Abstract>
@@ -11,6 +11,7 @@
     </ows:Keywords>
     <ows:ServiceType codeSpace="OGC">CSW</ows:ServiceType>
     <ows:ServiceTypeVersion>2.0.2</ows:ServiceTypeVersion>
+    <ows:ServiceTypeVersion>3.0.0</ows:ServiceTypeVersion>
     <ows:Fees>None</ows:Fees>
     <ows:AccessConstraints>None</ows:AccessConstraints>
   </ows:ServiceIdentification>
@@ -49,19 +50,12 @@
         </ows:HTTP>
       </ows:DCP>
       <ows:Parameter name="sections">
+        <ows:Value>Filter_Capabilities</ows:Value>
+        <ows:Value>OperationsMetadata</ows:Value>
         <ows:Value>ServiceIdentification</ows:Value>
         <ows:Value>ServiceProvider</ows:Value>
-        <ows:Value>OperationsMetadata</ows:Value>
-        <ows:Value>Filter_Capabilities</ows:Value>
       </ows:Parameter>
     </ows:Operation>
-    <ows:Operation name="GetRepositoryItem">
-      <ows:DCP>
-        <ows:HTTP>
-          <ows:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/fgdc/default.cfg"/>
-        </ows:HTTP>
-      </ows:DCP>
-    </ows:Operation>
     <ows:Operation name="DescribeRecord">
       <ows:DCP>
         <ows:HTTP>
@@ -69,14 +63,14 @@
           <ows:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/fgdc/default.cfg"/>
         </ows:HTTP>
       </ows:DCP>
-      <ows:Parameter name="schemaLanguage">
-        <ows:Value>http://www.w3.org/XML/Schema</ows:Value>
-        <ows:Value>http://www.w3.org/TR/xmlschema-1/</ows:Value>
-        <ows:Value>http://www.w3.org/2001/XMLSchema</ows:Value>
-      </ows:Parameter>
       <ows:Parameter name="outputFormat">
-        <ows:Value>application/xml</ows:Value>
         <ows:Value>application/json</ows:Value>
+        <ows:Value>application/xml</ows:Value>
+      </ows:Parameter>
+      <ows:Parameter name="schemaLanguage">
+        <ows:Value>http://www.w3.org/2001/XMLSchema</ows:Value>
+        <ows:Value>http://www.w3.org/TR/xmlschema-1/</ows:Value>
+        <ows:Value>http://www.w3.org/XML/Schema</ows:Value>
       </ows:Parameter>
       <ows:Parameter name="typeName">
         <ows:Value>csw:Record</ows:Value>
@@ -91,66 +85,48 @@
         </ows:HTTP>
       </ows:DCP>
       <ows:Parameter name="ParameterName">
+        <ows:Value>DescribeRecord.outputFormat</ows:Value>
+        <ows:Value>DescribeRecord.schemaLanguage</ows:Value>
+        <ows:Value>DescribeRecord.typeName</ows:Value>
+        <ows:Value>GetCapabilities.sections</ows:Value>
+        <ows:Value>GetRecordById.ElementSetName</ows:Value>
+        <ows:Value>GetRecordById.outputFormat</ows:Value>
+        <ows:Value>GetRecordById.outputSchema</ows:Value>
+        <ows:Value>GetRecords.CONSTRAINTLANGUAGE</ows:Value>
+        <ows:Value>GetRecords.ElementSetName</ows:Value>
         <ows:Value>GetRecords.outputFormat</ows:Value>
         <ows:Value>GetRecords.outputSchema</ows:Value>
-        <ows:Value>GetRecords.CONSTRAINTLANGUAGE</ows:Value>
         <ows:Value>GetRecords.resultType</ows:Value>
         <ows:Value>GetRecords.typeNames</ows:Value>
-        <ows:Value>GetRecords.ElementSetName</ows:Value>
-        <ows:Value>GetCapabilities.sections</ows:Value>
-        <ows:Value>GetRecordById.outputFormat</ows:Value>
-        <ows:Value>GetRecordById.outputSchema</ows:Value>
-        <ows:Value>GetRecordById.ElementSetName</ows:Value>
-        <ows:Value>DescribeRecord.schemaLanguage</ows:Value>
-        <ows:Value>DescribeRecord.outputFormat</ows:Value>
-        <ows:Value>DescribeRecord.typeName</ows:Value>
       </ows:Parameter>
     </ows:Operation>
-    <ows:Operation name="GetRecordById">
+    <ows:Operation name="GetRecords">
       <ows:DCP>
         <ows:HTTP>
           <ows:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/fgdc/default.cfg"/>
           <ows:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/fgdc/default.cfg"/>
         </ows:HTTP>
       </ows:DCP>
-      <ows:Parameter name="outputFormat">
-        <ows:Value>application/xml</ows:Value>
-        <ows:Value>application/json</ows:Value>
-      </ows:Parameter>
-      <ows:Parameter name="outputSchema">
-        <ows:Value>http://www.opengis.net/cat/csw/2.0.2</ows:Value>
-        <ows:Value>urn:oasis:names:tc:ebxml-regrep:xsd:rim:3.0</ows:Value>
-        <ows:Value>http://www.w3.org/2005/Atom</ows:Value>
-        <ows:Value>http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/</ows:Value>
-        <ows:Value>http://www.opengis.net/cat/csw/csdgm</ows:Value>
+      <ows:Parameter name="CONSTRAINTLANGUAGE">
+        <ows:Value>CQL_TEXT</ows:Value>
+        <ows:Value>FILTER</ows:Value>
       </ows:Parameter>
       <ows:Parameter name="ElementSetName">
         <ows:Value>brief</ows:Value>
-        <ows:Value>summary</ows:Value>
         <ows:Value>full</ows:Value>
+        <ows:Value>summary</ows:Value>
       </ows:Parameter>
-    </ows:Operation>
-    <ows:Operation name="GetRecords">
-      <ows:DCP>
-        <ows:HTTP>
-          <ows:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/fgdc/default.cfg"/>
-          <ows:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/fgdc/default.cfg"/>
-        </ows:HTTP>
-      </ows:DCP>
       <ows:Parameter name="outputFormat">
-        <ows:Value>application/xml</ows:Value>
         <ows:Value>application/json</ows:Value>
+        <ows:Value>application/xml</ows:Value>
       </ows:Parameter>
       <ows:Parameter name="outputSchema">
-        <ows:Value>http://www.opengis.net/cat/csw/2.0.2</ows:Value>
-        <ows:Value>urn:oasis:names:tc:ebxml-regrep:xsd:rim:3.0</ows:Value>
-        <ows:Value>http://www.w3.org/2005/Atom</ows:Value>
         <ows:Value>http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/</ows:Value>
+        <ows:Value>http://www.interlis.ch/INTERLIS2.3</ows:Value>
+        <ows:Value>http://www.opengis.net/cat/csw/2.0.2</ows:Value>
         <ows:Value>http://www.opengis.net/cat/csw/csdgm</ows:Value>
-      </ows:Parameter>
-      <ows:Parameter name="CONSTRAINTLANGUAGE">
-        <ows:Value>FILTER</ows:Value>
-        <ows:Value>CQL_TEXT</ows:Value>
+        <ows:Value>http://www.w3.org/2005/Atom</ows:Value>
+        <ows:Value>urn:oasis:names:tc:ebxml-regrep:xsd:rim:3.0</ows:Value>
       </ows:Parameter>
       <ows:Parameter name="resultType">
         <ows:Value>hits</ows:Value>
@@ -161,39 +137,67 @@
         <ows:Value>csw:Record</ows:Value>
         <ows:Value>rim:RegistryObject</ows:Value>
       </ows:Parameter>
-      <ows:Parameter name="ElementSetName">
-        <ows:Value>brief</ows:Value>
-        <ows:Value>summary</ows:Value>
-        <ows:Value>full</ows:Value>
-      </ows:Parameter>
       <ows:Constraint name="SupportedDublinCoreQueryables">
+        <ows:Value>csw:AnyText</ows:Value>
         <ows:Value>dc:contributor</ows:Value>
-        <ows:Value>dc:source</ows:Value>
-        <ows:Value>dc:language</ows:Value>
-        <ows:Value>dc:title</ows:Value>
-        <ows:Value>dc:subject</ows:Value>
         <ows:Value>dc:creator</ows:Value>
-        <ows:Value>dc:type</ows:Value>
-        <ows:Value>ows:BoundingBox</ows:Value>
-        <ows:Value>dct:modified</ows:Value>
-        <ows:Value>dct:abstract</ows:Value>
-        <ows:Value>dc:relation</ows:Value>
         <ows:Value>dc:date</ows:Value>
+        <ows:Value>dc:format</ows:Value>
         <ows:Value>dc:identifier</ows:Value>
+        <ows:Value>dc:language</ows:Value>
         <ows:Value>dc:publisher</ows:Value>
-        <ows:Value>dc:format</ows:Value>
-        <ows:Value>csw:AnyText</ows:Value>
+        <ows:Value>dc:relation</ows:Value>
         <ows:Value>dc:rights</ows:Value>
+        <ows:Value>dc:source</ows:Value>
+        <ows:Value>dc:subject</ows:Value>
+        <ows:Value>dc:title</ows:Value>
+        <ows:Value>dc:type</ows:Value>
+        <ows:Value>dct:abstract</ows:Value>
+        <ows:Value>dct:modified</ows:Value>
+        <ows:Value>ows:BoundingBox</ows:Value>
       </ows:Constraint>
     </ows:Operation>
-    <ows:Parameter name="version">
-      <ows:Value>2.0.2</ows:Value>
-    </ows:Parameter>
+    <ows:Operation name="GetRecordById">
+      <ows:DCP>
+        <ows:HTTP>
+          <ows:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/fgdc/default.cfg"/>
+          <ows:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/fgdc/default.cfg"/>
+        </ows:HTTP>
+      </ows:DCP>
+      <ows:Parameter name="ElementSetName">
+        <ows:Value>brief</ows:Value>
+        <ows:Value>full</ows:Value>
+        <ows:Value>summary</ows:Value>
+      </ows:Parameter>
+      <ows:Parameter name="outputFormat">
+        <ows:Value>application/json</ows:Value>
+        <ows:Value>application/xml</ows:Value>
+      </ows:Parameter>
+      <ows:Parameter name="outputSchema">
+        <ows:Value>http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/</ows:Value>
+        <ows:Value>http://www.interlis.ch/INTERLIS2.3</ows:Value>
+        <ows:Value>http://www.opengis.net/cat/csw/2.0.2</ows:Value>
+        <ows:Value>http://www.opengis.net/cat/csw/csdgm</ows:Value>
+        <ows:Value>http://www.w3.org/2005/Atom</ows:Value>
+        <ows:Value>urn:oasis:names:tc:ebxml-regrep:xsd:rim:3.0</ows:Value>
+      </ows:Parameter>
+    </ows:Operation>
+    <ows:Operation name="GetRepositoryItem">
+      <ows:DCP>
+        <ows:HTTP>
+          <ows:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/fgdc/default.cfg"/>
+        </ows:HTTP>
+      </ows:DCP>
+    </ows:Operation>
     <ows:Parameter name="service">
       <ows:Value>CSW</ows:Value>
     </ows:Parameter>
-    <ows:Constraint name="XPathQueryables">
-      <ows:Value>allowed</ows:Value>
+    <ows:Parameter name="version">
+      <ows:Value>2.0.2</ows:Value>
+      <ows:Value>3.0.0</ows:Value>
+    </ows:Parameter>
+    <ows:Constraint name="FederatedCatalogues">
+      <ows:Value>http://geo.data.gov/geoportal/csw/discovery</ows:Value>
     </ows:Constraint>
     <ows:Constraint name="MaxRecordDefault">
       <ows:Value>10</ows:Value>
@@ -202,8 +206,8 @@
       <ows:Value>XML</ows:Value>
       <ows:Value>SOAP</ows:Value>
     </ows:Constraint>
-    <ows:Constraint name="FederatedCatalogues">
-      <ows:Value>http://geo.data.gov/geoportal/csw/discovery</ows:Value>
+    <ows:Constraint name="XPathQueryables">
+      <ows:Value>allowed</ows:Value>
     </ows:Constraint>
   </ows:OperationsMetadata>
   <ogc:Filter_Capabilities>
@@ -233,11 +237,11 @@
       <ogc:ComparisonOperators>
         <ogc:ComparisonOperator>Between</ogc:ComparisonOperator>
         <ogc:ComparisonOperator>EqualTo</ogc:ComparisonOperator>
-        <ogc:ComparisonOperator>LessThanEqualTo</ogc:ComparisonOperator>
         <ogc:ComparisonOperator>GreaterThan</ogc:ComparisonOperator>
-        <ogc:ComparisonOperator>Like</ogc:ComparisonOperator>
-        <ogc:ComparisonOperator>LessThan</ogc:ComparisonOperator>
         <ogc:ComparisonOperator>GreaterThanEqualTo</ogc:ComparisonOperator>
+        <ogc:ComparisonOperator>LessThan</ogc:ComparisonOperator>
+        <ogc:ComparisonOperator>LessThanEqualTo</ogc:ComparisonOperator>
+        <ogc:ComparisonOperator>Like</ogc:ComparisonOperator>
         <ogc:ComparisonOperator>NotEqualTo</ogc:ComparisonOperator>
         <ogc:ComparisonOperator>NullCheck</ogc:ComparisonOperator>
       </ogc:ComparisonOperators>
diff --git a/tests/expected/suites_ebrim_post_GetRecords-filter-bbox-full.xml b/tests/expected/suites_ebrim_post_GetRecords-filter-bbox-full.xml
index 04665a2..5b2074c 100644
--- a/tests/expected/suites_ebrim_post_GetRecords-filter-bbox-full.xml
+++ b/tests/expected/suites_ebrim_post_GetRecords-filter-bbox-full.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<csw:GetRecordsResponse xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:rim="urn:oasis:names:tc:ebxml-regrep:xsd:rim:3.0" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ows="http://www.opengis. [...]
+<csw:GetRecordsResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:rim="urn:oasis:names:tc:ebxml-regrep:xsd:rim:3.0" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.0.2" xsi:schemaLocation="http://www.opengis.net/c [...]
   <csw:SearchStatus timestamp="PYCSW_TIMESTAMP"/>
   <csw:SearchResults nextRecord="0" numberOfRecordsMatched="2" numberOfRecordsReturned="2" recordSchema="urn:oasis:names:tc:ebxml-regrep:xsd:rim:3.0" elementSet="full">
     <rim:ExtrinsicObject xsi:schemaLocation="http://www.opengis.net/cat/wrs/1.0 http://schemas.opengis.net/csw/2.0.2/profiles/ebrim/1.0/csw-ebrim.xsd" id="urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63" lid="urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63" objectType="http://purl.org/dc/dcmitype/Dataset" status="urn:oasis:names:tc:ebxml-regrep:StatusType:Submitted">
diff --git a/tests/expected/suites_ebrim_post_GetRecords-filter-bbox.xml b/tests/expected/suites_ebrim_post_GetRecords-filter-bbox.xml
index b59cecc..fdc31f2 100644
--- a/tests/expected/suites_ebrim_post_GetRecords-filter-bbox.xml
+++ b/tests/expected/suites_ebrim_post_GetRecords-filter-bbox.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<csw:GetRecordsResponse xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:rim="urn:oasis:names:tc:ebxml-regrep:xsd:rim:3.0" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ows="http://www.opengis. [...]
+<csw:GetRecordsResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:rim="urn:oasis:names:tc:ebxml-regrep:xsd:rim:3.0" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.0.2" xsi:schemaLocation="http://www.opengis.net/c [...]
   <csw:SearchStatus timestamp="PYCSW_TIMESTAMP"/>
   <csw:SearchResults nextRecord="0" numberOfRecordsMatched="2" numberOfRecordsReturned="2" recordSchema="urn:oasis:names:tc:ebxml-regrep:xsd:rim:3.0" elementSet="brief">
     <rim:ExtrinsicObject xsi:schemaLocation="http://www.opengis.net/cat/wrs/1.0 http://schemas.opengis.net/csw/2.0.2/profiles/ebrim/1.0/csw-ebrim.xsd" id="urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63" lid="urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63" objectType="http://purl.org/dc/dcmitype/Dataset" status="urn:oasis:names:tc:ebxml-regrep:StatusType:Submitted">
diff --git a/tests/expected/suites_fgdc_post_DescribeRecord.xml b/tests/expected/suites_fgdc_post_DescribeRecord.xml
index 04284a4..5f82a7d 100644
--- a/tests/expected/suites_fgdc_post_DescribeRecord.xml
+++ b/tests/expected/suites_fgdc_post_DescribeRecord.xml
@@ -1,3 +1,3 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<csw:DescribeRecordResponse xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ows="http://www.opengis.net/ows" xmlns:fgdc="http://www.opengis.net/cat/csw/ [...]
+<csw:DescribeRecordResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/cat/csw/2.0.2 http://schemas.opengis.net/csw/2.0.2/CSW-discovery.xsd"/>
diff --git a/tests/expected/suites_fgdc_post_GetCapabilities.xml b/tests/expected/suites_fgdc_post_GetCapabilities.xml
index bc39c3c..e4ea071 100644
--- a/tests/expected/suites_fgdc_post_GetCapabilities.xml
+++ b/tests/expected/suites_fgdc_post_GetCapabilities.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<csw:Capabilities xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ows="http://www.opengis.net/ows" xmlns:fgdc="http://www.opengis.net/cat/csw/csdgm" xml [...]
+<csw:Capabilities xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ogc="http://www.opengis.net/ogc" xmlns:ows="http://www.opengis.net/ows" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" updateSequence="PYCSW_UPDATESEQUENCE" ve [...]
   <ows:ServiceIdentification>
     <ows:Title>pycsw Geospatial Catalogue</ows:Title>
     <ows:Abstract>pycsw is an OGC CSW server implementation written in Python</ows:Abstract>
@@ -11,6 +11,7 @@
     </ows:Keywords>
     <ows:ServiceType codeSpace="OGC">CSW</ows:ServiceType>
     <ows:ServiceTypeVersion>2.0.2</ows:ServiceTypeVersion>
+    <ows:ServiceTypeVersion>3.0.0</ows:ServiceTypeVersion>
     <ows:Fees>None</ows:Fees>
     <ows:AccessConstraints>None</ows:AccessConstraints>
   </ows:ServiceIdentification>
@@ -49,19 +50,12 @@
         </ows:HTTP>
       </ows:DCP>
       <ows:Parameter name="sections">
+        <ows:Value>Filter_Capabilities</ows:Value>
+        <ows:Value>OperationsMetadata</ows:Value>
         <ows:Value>ServiceIdentification</ows:Value>
         <ows:Value>ServiceProvider</ows:Value>
-        <ows:Value>OperationsMetadata</ows:Value>
-        <ows:Value>Filter_Capabilities</ows:Value>
       </ows:Parameter>
     </ows:Operation>
-    <ows:Operation name="GetRepositoryItem">
-      <ows:DCP>
-        <ows:HTTP>
-          <ows:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/fgdc/default.cfg"/>
-        </ows:HTTP>
-      </ows:DCP>
-    </ows:Operation>
     <ows:Operation name="DescribeRecord">
       <ows:DCP>
         <ows:HTTP>
@@ -69,14 +63,14 @@
           <ows:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/fgdc/default.cfg"/>
         </ows:HTTP>
       </ows:DCP>
-      <ows:Parameter name="schemaLanguage">
-        <ows:Value>http://www.w3.org/XML/Schema</ows:Value>
-        <ows:Value>http://www.w3.org/TR/xmlschema-1/</ows:Value>
-        <ows:Value>http://www.w3.org/2001/XMLSchema</ows:Value>
-      </ows:Parameter>
       <ows:Parameter name="outputFormat">
-        <ows:Value>application/xml</ows:Value>
         <ows:Value>application/json</ows:Value>
+        <ows:Value>application/xml</ows:Value>
+      </ows:Parameter>
+      <ows:Parameter name="schemaLanguage">
+        <ows:Value>http://www.w3.org/2001/XMLSchema</ows:Value>
+        <ows:Value>http://www.w3.org/TR/xmlschema-1/</ows:Value>
+        <ows:Value>http://www.w3.org/XML/Schema</ows:Value>
       </ows:Parameter>
       <ows:Parameter name="typeName">
         <ows:Value>csw:Record</ows:Value>
@@ -90,64 +84,47 @@
         </ows:HTTP>
       </ows:DCP>
       <ows:Parameter name="ParameterName">
+        <ows:Value>DescribeRecord.outputFormat</ows:Value>
+        <ows:Value>DescribeRecord.schemaLanguage</ows:Value>
+        <ows:Value>DescribeRecord.typeName</ows:Value>
+        <ows:Value>GetCapabilities.sections</ows:Value>
+        <ows:Value>GetRecordById.ElementSetName</ows:Value>
+        <ows:Value>GetRecordById.outputFormat</ows:Value>
+        <ows:Value>GetRecordById.outputSchema</ows:Value>
+        <ows:Value>GetRecords.CONSTRAINTLANGUAGE</ows:Value>
+        <ows:Value>GetRecords.ElementSetName</ows:Value>
         <ows:Value>GetRecords.outputFormat</ows:Value>
         <ows:Value>GetRecords.outputSchema</ows:Value>
-        <ows:Value>GetRecords.CONSTRAINTLANGUAGE</ows:Value>
         <ows:Value>GetRecords.resultType</ows:Value>
         <ows:Value>GetRecords.typeNames</ows:Value>
-        <ows:Value>GetRecords.ElementSetName</ows:Value>
-        <ows:Value>GetCapabilities.sections</ows:Value>
-        <ows:Value>GetRecordById.outputFormat</ows:Value>
-        <ows:Value>GetRecordById.outputSchema</ows:Value>
-        <ows:Value>GetRecordById.ElementSetName</ows:Value>
-        <ows:Value>DescribeRecord.schemaLanguage</ows:Value>
-        <ows:Value>DescribeRecord.outputFormat</ows:Value>
-        <ows:Value>DescribeRecord.typeName</ows:Value>
       </ows:Parameter>
     </ows:Operation>
-    <ows:Operation name="GetRecordById">
+    <ows:Operation name="GetRecords">
       <ows:DCP>
         <ows:HTTP>
           <ows:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/fgdc/default.cfg"/>
           <ows:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/fgdc/default.cfg"/>
         </ows:HTTP>
       </ows:DCP>
-      <ows:Parameter name="outputFormat">
-        <ows:Value>application/xml</ows:Value>
-        <ows:Value>application/json</ows:Value>
-      </ows:Parameter>
-      <ows:Parameter name="outputSchema">
-        <ows:Value>http://www.opengis.net/cat/csw/2.0.2</ows:Value>
-        <ows:Value>http://www.w3.org/2005/Atom</ows:Value>
-        <ows:Value>http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/</ows:Value>
-        <ows:Value>http://www.opengis.net/cat/csw/csdgm</ows:Value>
+      <ows:Parameter name="CONSTRAINTLANGUAGE">
+        <ows:Value>CQL_TEXT</ows:Value>
+        <ows:Value>FILTER</ows:Value>
       </ows:Parameter>
       <ows:Parameter name="ElementSetName">
         <ows:Value>brief</ows:Value>
-        <ows:Value>summary</ows:Value>
         <ows:Value>full</ows:Value>
+        <ows:Value>summary</ows:Value>
       </ows:Parameter>
-    </ows:Operation>
-    <ows:Operation name="GetRecords">
-      <ows:DCP>
-        <ows:HTTP>
-          <ows:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/fgdc/default.cfg"/>
-          <ows:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/fgdc/default.cfg"/>
-        </ows:HTTP>
-      </ows:DCP>
       <ows:Parameter name="outputFormat">
-        <ows:Value>application/xml</ows:Value>
         <ows:Value>application/json</ows:Value>
+        <ows:Value>application/xml</ows:Value>
       </ows:Parameter>
       <ows:Parameter name="outputSchema">
-        <ows:Value>http://www.opengis.net/cat/csw/2.0.2</ows:Value>
-        <ows:Value>http://www.w3.org/2005/Atom</ows:Value>
         <ows:Value>http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/</ows:Value>
+        <ows:Value>http://www.interlis.ch/INTERLIS2.3</ows:Value>
+        <ows:Value>http://www.opengis.net/cat/csw/2.0.2</ows:Value>
         <ows:Value>http://www.opengis.net/cat/csw/csdgm</ows:Value>
-      </ows:Parameter>
-      <ows:Parameter name="CONSTRAINTLANGUAGE">
-        <ows:Value>FILTER</ows:Value>
-        <ows:Value>CQL_TEXT</ows:Value>
+        <ows:Value>http://www.w3.org/2005/Atom</ows:Value>
       </ows:Parameter>
       <ows:Parameter name="resultType">
         <ows:Value>hits</ows:Value>
@@ -157,39 +134,66 @@
       <ows:Parameter name="typeNames">
         <ows:Value>csw:Record</ows:Value>
       </ows:Parameter>
-      <ows:Parameter name="ElementSetName">
-        <ows:Value>brief</ows:Value>
-        <ows:Value>summary</ows:Value>
-        <ows:Value>full</ows:Value>
-      </ows:Parameter>
       <ows:Constraint name="SupportedDublinCoreQueryables">
+        <ows:Value>csw:AnyText</ows:Value>
         <ows:Value>dc:contributor</ows:Value>
-        <ows:Value>dc:source</ows:Value>
-        <ows:Value>dc:language</ows:Value>
-        <ows:Value>dc:title</ows:Value>
-        <ows:Value>dc:subject</ows:Value>
         <ows:Value>dc:creator</ows:Value>
-        <ows:Value>dc:type</ows:Value>
-        <ows:Value>ows:BoundingBox</ows:Value>
-        <ows:Value>dct:modified</ows:Value>
-        <ows:Value>dct:abstract</ows:Value>
-        <ows:Value>dc:relation</ows:Value>
         <ows:Value>dc:date</ows:Value>
+        <ows:Value>dc:format</ows:Value>
         <ows:Value>dc:identifier</ows:Value>
+        <ows:Value>dc:language</ows:Value>
         <ows:Value>dc:publisher</ows:Value>
-        <ows:Value>dc:format</ows:Value>
-        <ows:Value>csw:AnyText</ows:Value>
+        <ows:Value>dc:relation</ows:Value>
         <ows:Value>dc:rights</ows:Value>
+        <ows:Value>dc:source</ows:Value>
+        <ows:Value>dc:subject</ows:Value>
+        <ows:Value>dc:title</ows:Value>
+        <ows:Value>dc:type</ows:Value>
+        <ows:Value>dct:abstract</ows:Value>
+        <ows:Value>dct:modified</ows:Value>
+        <ows:Value>ows:BoundingBox</ows:Value>
       </ows:Constraint>
     </ows:Operation>
-    <ows:Parameter name="version">
-      <ows:Value>2.0.2</ows:Value>
-    </ows:Parameter>
+    <ows:Operation name="GetRecordById">
+      <ows:DCP>
+        <ows:HTTP>
+          <ows:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/fgdc/default.cfg"/>
+          <ows:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/fgdc/default.cfg"/>
+        </ows:HTTP>
+      </ows:DCP>
+      <ows:Parameter name="ElementSetName">
+        <ows:Value>brief</ows:Value>
+        <ows:Value>full</ows:Value>
+        <ows:Value>summary</ows:Value>
+      </ows:Parameter>
+      <ows:Parameter name="outputFormat">
+        <ows:Value>application/json</ows:Value>
+        <ows:Value>application/xml</ows:Value>
+      </ows:Parameter>
+      <ows:Parameter name="outputSchema">
+        <ows:Value>http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/</ows:Value>
+        <ows:Value>http://www.interlis.ch/INTERLIS2.3</ows:Value>
+        <ows:Value>http://www.opengis.net/cat/csw/2.0.2</ows:Value>
+        <ows:Value>http://www.opengis.net/cat/csw/csdgm</ows:Value>
+        <ows:Value>http://www.w3.org/2005/Atom</ows:Value>
+      </ows:Parameter>
+    </ows:Operation>
+    <ows:Operation name="GetRepositoryItem">
+      <ows:DCP>
+        <ows:HTTP>
+          <ows:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/fgdc/default.cfg"/>
+        </ows:HTTP>
+      </ows:DCP>
+    </ows:Operation>
     <ows:Parameter name="service">
       <ows:Value>CSW</ows:Value>
     </ows:Parameter>
-    <ows:Constraint name="XPathQueryables">
-      <ows:Value>allowed</ows:Value>
+    <ows:Parameter name="version">
+      <ows:Value>2.0.2</ows:Value>
+      <ows:Value>3.0.0</ows:Value>
+    </ows:Parameter>
+    <ows:Constraint name="FederatedCatalogues">
+      <ows:Value>http://geo.data.gov/geoportal/csw/discovery</ows:Value>
     </ows:Constraint>
     <ows:Constraint name="MaxRecordDefault">
       <ows:Value>10</ows:Value>
@@ -198,8 +202,8 @@
       <ows:Value>XML</ows:Value>
       <ows:Value>SOAP</ows:Value>
     </ows:Constraint>
-    <ows:Constraint name="FederatedCatalogues">
-      <ows:Value>http://geo.data.gov/geoportal/csw/discovery</ows:Value>
+    <ows:Constraint name="XPathQueryables">
+      <ows:Value>allowed</ows:Value>
     </ows:Constraint>
   </ows:OperationsMetadata>
   <ogc:Filter_Capabilities>
@@ -229,11 +233,11 @@
       <ogc:ComparisonOperators>
         <ogc:ComparisonOperator>Between</ogc:ComparisonOperator>
         <ogc:ComparisonOperator>EqualTo</ogc:ComparisonOperator>
-        <ogc:ComparisonOperator>LessThanEqualTo</ogc:ComparisonOperator>
         <ogc:ComparisonOperator>GreaterThan</ogc:ComparisonOperator>
-        <ogc:ComparisonOperator>Like</ogc:ComparisonOperator>
-        <ogc:ComparisonOperator>LessThan</ogc:ComparisonOperator>
         <ogc:ComparisonOperator>GreaterThanEqualTo</ogc:ComparisonOperator>
+        <ogc:ComparisonOperator>LessThan</ogc:ComparisonOperator>
+        <ogc:ComparisonOperator>LessThanEqualTo</ogc:ComparisonOperator>
+        <ogc:ComparisonOperator>Like</ogc:ComparisonOperator>
         <ogc:ComparisonOperator>NotEqualTo</ogc:ComparisonOperator>
         <ogc:ComparisonOperator>NullCheck</ogc:ComparisonOperator>
       </ogc:ComparisonOperators>
diff --git a/tests/expected/suites_fgdc_post_GetRecords-filter-bbox.xml b/tests/expected/suites_fgdc_post_GetRecords-filter-bbox.xml
index d55e72b..5f8c20d 100644
--- a/tests/expected/suites_fgdc_post_GetRecords-filter-bbox.xml
+++ b/tests/expected/suites_fgdc_post_GetRecords-filter-bbox.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<csw:GetRecordsResponse xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ows="http://www.opengis.net/ows" xmlns:fgdc="http://www.opengis.net/cat/csw/csdg [...]
+<csw:GetRecordsResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.0.2" xsi:schemaLocation="http://www.opengis.net/cat/csw/2.0.2 http://schemas.opengis.net/csw/2.0.2/CSW-di [...]
   <csw:SearchStatus timestamp="PYCSW_TIMESTAMP"/>
   <csw:SearchResults nextRecord="0" numberOfRecordsMatched="2" numberOfRecordsReturned="2" recordSchema="http://www.opengis.net/cat/csw/csdgm" elementSet="brief">
     <metadata xsi:noNamespaceSchemaLocation="http://www.fgdc.gov/metadata/fgdc-std-001-1998.xsd">
diff --git a/tests/expected/suites_dif_post_GetCapabilities.xml b/tests/expected/suites_gm03_post_GetCapabilities.xml
similarity index 87%
copy from tests/expected/suites_dif_post_GetCapabilities.xml
copy to tests/expected/suites_gm03_post_GetCapabilities.xml
index 2dacf0c..46b77ba 100644
--- a/tests/expected/suites_dif_post_GetCapabilities.xml
+++ b/tests/expected/suites_gm03_post_GetCapabilities.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<csw:Capabilities xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ows="http://www.opengis.net/ows" xmlns:fgdc="http://www.opengis.net/cat/csw/csdgm" xml [...]
+<csw:Capabilities xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ogc="http://www.opengis.net/ogc" xmlns:ows="http://www.opengis.net/ows" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" updateSequence="PYCSW_UPDATESEQUENCE" ve [...]
   <ows:ServiceIdentification>
     <ows:Title>pycsw Geospatial Catalogue</ows:Title>
     <ows:Abstract>pycsw is an OGC CSW server implementation written in Python</ows:Abstract>
@@ -11,6 +11,7 @@
     </ows:Keywords>
     <ows:ServiceType codeSpace="OGC">CSW</ows:ServiceType>
     <ows:ServiceTypeVersion>2.0.2</ows:ServiceTypeVersion>
+    <ows:ServiceTypeVersion>3.0.0</ows:ServiceTypeVersion>
     <ows:Fees>None</ows:Fees>
     <ows:AccessConstraints>None</ows:AccessConstraints>
   </ows:ServiceIdentification>
@@ -44,39 +45,32 @@
     <ows:Operation name="GetCapabilities">
       <ows:DCP>
         <ows:HTTP>
-          <ows:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/dif/default.cfg"/>
-          <ows:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/dif/default.cfg"/>
+          <ows:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/gm03/default.cfg"/>
+          <ows:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/gm03/default.cfg"/>
         </ows:HTTP>
       </ows:DCP>
       <ows:Parameter name="sections">
+        <ows:Value>Filter_Capabilities</ows:Value>
+        <ows:Value>OperationsMetadata</ows:Value>
         <ows:Value>ServiceIdentification</ows:Value>
         <ows:Value>ServiceProvider</ows:Value>
-        <ows:Value>OperationsMetadata</ows:Value>
-        <ows:Value>Filter_Capabilities</ows:Value>
       </ows:Parameter>
     </ows:Operation>
-    <ows:Operation name="GetRepositoryItem">
-      <ows:DCP>
-        <ows:HTTP>
-          <ows:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/dif/default.cfg"/>
-        </ows:HTTP>
-      </ows:DCP>
-    </ows:Operation>
     <ows:Operation name="DescribeRecord">
       <ows:DCP>
         <ows:HTTP>
-          <ows:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/dif/default.cfg"/>
-          <ows:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/dif/default.cfg"/>
+          <ows:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/gm03/default.cfg"/>
+          <ows:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/gm03/default.cfg"/>
         </ows:HTTP>
       </ows:DCP>
-      <ows:Parameter name="schemaLanguage">
-        <ows:Value>http://www.w3.org/XML/Schema</ows:Value>
-        <ows:Value>http://www.w3.org/TR/xmlschema-1/</ows:Value>
-        <ows:Value>http://www.w3.org/2001/XMLSchema</ows:Value>
-      </ows:Parameter>
       <ows:Parameter name="outputFormat">
-        <ows:Value>application/xml</ows:Value>
         <ows:Value>application/json</ows:Value>
+        <ows:Value>application/xml</ows:Value>
+      </ows:Parameter>
+      <ows:Parameter name="schemaLanguage">
+        <ows:Value>http://www.w3.org/2001/XMLSchema</ows:Value>
+        <ows:Value>http://www.w3.org/TR/xmlschema-1/</ows:Value>
+        <ows:Value>http://www.w3.org/XML/Schema</ows:Value>
       </ows:Parameter>
       <ows:Parameter name="typeName">
         <ows:Value>csw:Record</ows:Value>
@@ -85,69 +79,52 @@
     <ows:Operation name="GetDomain">
       <ows:DCP>
         <ows:HTTP>
-          <ows:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/dif/default.cfg"/>
-          <ows:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/dif/default.cfg"/>
+          <ows:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/gm03/default.cfg"/>
+          <ows:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/gm03/default.cfg"/>
         </ows:HTTP>
       </ows:DCP>
       <ows:Parameter name="ParameterName">
+        <ows:Value>DescribeRecord.outputFormat</ows:Value>
+        <ows:Value>DescribeRecord.schemaLanguage</ows:Value>
+        <ows:Value>DescribeRecord.typeName</ows:Value>
+        <ows:Value>GetCapabilities.sections</ows:Value>
+        <ows:Value>GetRecordById.ElementSetName</ows:Value>
+        <ows:Value>GetRecordById.outputFormat</ows:Value>
+        <ows:Value>GetRecordById.outputSchema</ows:Value>
+        <ows:Value>GetRecords.CONSTRAINTLANGUAGE</ows:Value>
+        <ows:Value>GetRecords.ElementSetName</ows:Value>
         <ows:Value>GetRecords.outputFormat</ows:Value>
         <ows:Value>GetRecords.outputSchema</ows:Value>
-        <ows:Value>GetRecords.CONSTRAINTLANGUAGE</ows:Value>
         <ows:Value>GetRecords.resultType</ows:Value>
         <ows:Value>GetRecords.typeNames</ows:Value>
-        <ows:Value>GetRecords.ElementSetName</ows:Value>
-        <ows:Value>GetCapabilities.sections</ows:Value>
-        <ows:Value>GetRecordById.outputFormat</ows:Value>
-        <ows:Value>GetRecordById.outputSchema</ows:Value>
-        <ows:Value>GetRecordById.ElementSetName</ows:Value>
-        <ows:Value>DescribeRecord.schemaLanguage</ows:Value>
-        <ows:Value>DescribeRecord.outputFormat</ows:Value>
-        <ows:Value>DescribeRecord.typeName</ows:Value>
       </ows:Parameter>
     </ows:Operation>
-    <ows:Operation name="GetRecordById">
+    <ows:Operation name="GetRecords">
       <ows:DCP>
         <ows:HTTP>
-          <ows:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/dif/default.cfg"/>
-          <ows:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/dif/default.cfg"/>
+          <ows:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/gm03/default.cfg"/>
+          <ows:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/gm03/default.cfg"/>
         </ows:HTTP>
       </ows:DCP>
-      <ows:Parameter name="outputFormat">
-        <ows:Value>application/xml</ows:Value>
-        <ows:Value>application/json</ows:Value>
-      </ows:Parameter>
-      <ows:Parameter name="outputSchema">
-        <ows:Value>http://www.opengis.net/cat/csw/2.0.2</ows:Value>
-        <ows:Value>http://www.w3.org/2005/Atom</ows:Value>
-        <ows:Value>http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/</ows:Value>
-        <ows:Value>http://www.opengis.net/cat/csw/csdgm</ows:Value>
+      <ows:Parameter name="CONSTRAINTLANGUAGE">
+        <ows:Value>CQL_TEXT</ows:Value>
+        <ows:Value>FILTER</ows:Value>
       </ows:Parameter>
       <ows:Parameter name="ElementSetName">
         <ows:Value>brief</ows:Value>
-        <ows:Value>summary</ows:Value>
         <ows:Value>full</ows:Value>
+        <ows:Value>summary</ows:Value>
       </ows:Parameter>
-    </ows:Operation>
-    <ows:Operation name="GetRecords">
-      <ows:DCP>
-        <ows:HTTP>
-          <ows:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/dif/default.cfg"/>
-          <ows:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/dif/default.cfg"/>
-        </ows:HTTP>
-      </ows:DCP>
       <ows:Parameter name="outputFormat">
-        <ows:Value>application/xml</ows:Value>
         <ows:Value>application/json</ows:Value>
+        <ows:Value>application/xml</ows:Value>
       </ows:Parameter>
       <ows:Parameter name="outputSchema">
-        <ows:Value>http://www.opengis.net/cat/csw/2.0.2</ows:Value>
-        <ows:Value>http://www.w3.org/2005/Atom</ows:Value>
         <ows:Value>http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/</ows:Value>
+        <ows:Value>http://www.interlis.ch/INTERLIS2.3</ows:Value>
+        <ows:Value>http://www.opengis.net/cat/csw/2.0.2</ows:Value>
         <ows:Value>http://www.opengis.net/cat/csw/csdgm</ows:Value>
-      </ows:Parameter>
-      <ows:Parameter name="CONSTRAINTLANGUAGE">
-        <ows:Value>FILTER</ows:Value>
-        <ows:Value>CQL_TEXT</ows:Value>
+        <ows:Value>http://www.w3.org/2005/Atom</ows:Value>
       </ows:Parameter>
       <ows:Parameter name="resultType">
         <ows:Value>hits</ows:Value>
@@ -157,39 +134,66 @@
       <ows:Parameter name="typeNames">
         <ows:Value>csw:Record</ows:Value>
       </ows:Parameter>
-      <ows:Parameter name="ElementSetName">
-        <ows:Value>brief</ows:Value>
-        <ows:Value>summary</ows:Value>
-        <ows:Value>full</ows:Value>
-      </ows:Parameter>
       <ows:Constraint name="SupportedDublinCoreQueryables">
+        <ows:Value>csw:AnyText</ows:Value>
         <ows:Value>dc:contributor</ows:Value>
-        <ows:Value>dc:source</ows:Value>
-        <ows:Value>dc:language</ows:Value>
-        <ows:Value>dc:title</ows:Value>
-        <ows:Value>dc:subject</ows:Value>
         <ows:Value>dc:creator</ows:Value>
-        <ows:Value>dc:type</ows:Value>
-        <ows:Value>ows:BoundingBox</ows:Value>
-        <ows:Value>dct:modified</ows:Value>
-        <ows:Value>dct:abstract</ows:Value>
-        <ows:Value>dc:relation</ows:Value>
         <ows:Value>dc:date</ows:Value>
+        <ows:Value>dc:format</ows:Value>
         <ows:Value>dc:identifier</ows:Value>
+        <ows:Value>dc:language</ows:Value>
         <ows:Value>dc:publisher</ows:Value>
-        <ows:Value>dc:format</ows:Value>
-        <ows:Value>csw:AnyText</ows:Value>
+        <ows:Value>dc:relation</ows:Value>
         <ows:Value>dc:rights</ows:Value>
+        <ows:Value>dc:source</ows:Value>
+        <ows:Value>dc:subject</ows:Value>
+        <ows:Value>dc:title</ows:Value>
+        <ows:Value>dc:type</ows:Value>
+        <ows:Value>dct:abstract</ows:Value>
+        <ows:Value>dct:modified</ows:Value>
+        <ows:Value>ows:BoundingBox</ows:Value>
       </ows:Constraint>
     </ows:Operation>
-    <ows:Parameter name="version">
-      <ows:Value>2.0.2</ows:Value>
-    </ows:Parameter>
+    <ows:Operation name="GetRecordById">
+      <ows:DCP>
+        <ows:HTTP>
+          <ows:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/gm03/default.cfg"/>
+          <ows:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/gm03/default.cfg"/>
+        </ows:HTTP>
+      </ows:DCP>
+      <ows:Parameter name="ElementSetName">
+        <ows:Value>brief</ows:Value>
+        <ows:Value>full</ows:Value>
+        <ows:Value>summary</ows:Value>
+      </ows:Parameter>
+      <ows:Parameter name="outputFormat">
+        <ows:Value>application/json</ows:Value>
+        <ows:Value>application/xml</ows:Value>
+      </ows:Parameter>
+      <ows:Parameter name="outputSchema">
+        <ows:Value>http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/</ows:Value>
+        <ows:Value>http://www.interlis.ch/INTERLIS2.3</ows:Value>
+        <ows:Value>http://www.opengis.net/cat/csw/2.0.2</ows:Value>
+        <ows:Value>http://www.opengis.net/cat/csw/csdgm</ows:Value>
+        <ows:Value>http://www.w3.org/2005/Atom</ows:Value>
+      </ows:Parameter>
+    </ows:Operation>
+    <ows:Operation name="GetRepositoryItem">
+      <ows:DCP>
+        <ows:HTTP>
+          <ows:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/gm03/default.cfg"/>
+        </ows:HTTP>
+      </ows:DCP>
+    </ows:Operation>
     <ows:Parameter name="service">
       <ows:Value>CSW</ows:Value>
     </ows:Parameter>
-    <ows:Constraint name="XPathQueryables">
-      <ows:Value>allowed</ows:Value>
+    <ows:Parameter name="version">
+      <ows:Value>2.0.2</ows:Value>
+      <ows:Value>3.0.0</ows:Value>
+    </ows:Parameter>
+    <ows:Constraint name="FederatedCatalogues">
+      <ows:Value>http://geo.data.gov/geoportal/csw/discovery</ows:Value>
     </ows:Constraint>
     <ows:Constraint name="MaxRecordDefault">
       <ows:Value>10</ows:Value>
@@ -198,8 +202,8 @@
       <ows:Value>XML</ows:Value>
       <ows:Value>SOAP</ows:Value>
     </ows:Constraint>
-    <ows:Constraint name="FederatedCatalogues">
-      <ows:Value>http://geo.data.gov/geoportal/csw/discovery</ows:Value>
+    <ows:Constraint name="XPathQueryables">
+      <ows:Value>allowed</ows:Value>
     </ows:Constraint>
   </ows:OperationsMetadata>
   <ogc:Filter_Capabilities>
@@ -229,11 +233,11 @@
       <ogc:ComparisonOperators>
         <ogc:ComparisonOperator>Between</ogc:ComparisonOperator>
         <ogc:ComparisonOperator>EqualTo</ogc:ComparisonOperator>
-        <ogc:ComparisonOperator>LessThanEqualTo</ogc:ComparisonOperator>
         <ogc:ComparisonOperator>GreaterThan</ogc:ComparisonOperator>
-        <ogc:ComparisonOperator>Like</ogc:ComparisonOperator>
-        <ogc:ComparisonOperator>LessThan</ogc:ComparisonOperator>
         <ogc:ComparisonOperator>GreaterThanEqualTo</ogc:ComparisonOperator>
+        <ogc:ComparisonOperator>LessThan</ogc:ComparisonOperator>
+        <ogc:ComparisonOperator>LessThanEqualTo</ogc:ComparisonOperator>
+        <ogc:ComparisonOperator>Like</ogc:ComparisonOperator>
         <ogc:ComparisonOperator>NotEqualTo</ogc:ComparisonOperator>
         <ogc:ComparisonOperator>NullCheck</ogc:ComparisonOperator>
       </ogc:ComparisonOperators>
diff --git a/tests/expected/suites_gm03_post_GetRecords-filter-bbox.xml b/tests/expected/suites_gm03_post_GetRecords-filter-bbox.xml
new file mode 100644
index 0000000..55213c6
--- /dev/null
+++ b/tests/expected/suites_gm03_post_GetRecords-filter-bbox.xml
@@ -0,0 +1,137 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- PYCSW_VERSION -->
+<csw:GetRecordsResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gm03="http://www.interlis.ch/INTERLIS2.3" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.0.2" xsi:schemaLocation="http://www.opengis.net/cat/csw/2 [...]
+  <csw:SearchStatus timestamp="PYCSW_TIMESTAMP"/>
+  <csw:SearchResults nextRecord="0" numberOfRecordsMatched="2" numberOfRecordsReturned="2" recordSchema="http://www.interlis.ch/INTERLIS2.3" elementSet="brief">
+    <gm03:TRANSFER>
+      <gm03:HEADERSECTION version="2.3" sender="pycsw">
+        <gm03:MODELS/>
+      </gm03:HEADERSECTION>
+      <gm03:DATASECTION>
+        <gm03:GM03_2_1Core.Core>
+          <gm03:GM03_2_1Core.Core.MD_Metadata>
+            <gm03:fileIdentifier>urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63</gm03:fileIdentifier>
+            <gm03:language/>
+            <gm03:dateStamp/>
+            <gm03:metadataStandardName>GM03</gm03:metadataStandardName>
+            <gm03:metadataStandardVersion>2.3</gm03:metadataStandardVersion>
+            <gm03:hierarchyLevel>
+              <gm03:GM03_2_1Core.Core.MD_ScopeCode_>
+                <gm03:value>http://purl.org/dc/dcmitype/Dataset</gm03:value>
+              </gm03:GM03_2_1Core.Core.MD_ScopeCode_>
+            </gm03:hierarchyLevel>
+            <gm03:parentIdentifier>
+              <gm03:GM03_2_1Core.Core.MD_ScopeCode_>
+                <gm03:value/>
+              </gm03:GM03_2_1Core.Core.MD_ScopeCode_>
+            </gm03:parentIdentifier>
+          </gm03:GM03_2_1Core.Core.MD_Metadata>
+          <gm03:GM03_2_1Core.Core.CI_Citation>
+            <gm03:title>
+              <gm03:GM03_2_1Core.Core.PT_FreeText>
+                <gm03:textGroup>
+                  <gm03:GM03_2_1Core.Core.PT_Group>
+                    <gm03:plainText>Mauris sed neque</gm03:plainText>
+                  </gm03:GM03_2_1Core.Core.PT_Group>
+                </gm03:textGroup>
+              </gm03:GM03_2_1Core.Core.PT_FreeText>
+            </gm03:title>
+          </gm03:GM03_2_1Core.Core.CI_Citation>
+          <gm03:GM03_2_1Core.Core.MD_DataIdentification>
+            <gm03:abstract>
+              <gm03:GM03_2_1Core.Core.PT_FreeText>
+                <gm03:textGroup>
+                  <gm03:GM03_2_1Core.Core.PT_Group>
+                    <gm03:plainText>Curabitur lacinia, ante non porta tempus, mi lorem feugiat odio, eget suscipit eros pede ac velit.</gm03:plainText>
+                  </gm03:GM03_2_1Core.Core.PT_Group>
+                </gm03:textGroup>
+              </gm03:GM03_2_1Core.Core.PT_FreeText>
+            </gm03:abstract>
+          </gm03:GM03_2_1Core.Core.MD_DataIdentification>
+          <gm03:GM03_2_1Core.Core.MD_Keywords>
+            <gm03:keyword>
+              <gm03:GM03_2_1Core.Core.PT_FreeText>
+                <gm03:textGroup>
+                  <gm03:GM03_2_1Core.Core.PT_Group>
+                    <gm03:plainText>Vegetation-Cropland</gm03:plainText>
+                  </gm03:GM03_2_1Core.Core.PT_Group>
+                </gm03:textGroup>
+              </gm03:GM03_2_1Core.Core.PT_FreeText>
+            </gm03:keyword>
+          </gm03:GM03_2_1Core.Core.MD_Keywords>
+          <gm03:GM03_2_1Core.Core.EX_GeographicBoundingBox>
+            <gm03:northBoundLatitude>51.22</gm03:northBoundLatitude>
+            <gm03:southBoundLatitude>47.59</gm03:southBoundLatitude>
+            <gm03:eastBoundLongitude>-4.1</gm03:eastBoundLongitude>
+            <gm03:westBoundLongitude>0.89</gm03:westBoundLongitude>
+          </gm03:GM03_2_1Core.Core.EX_GeographicBoundingBox>
+        </gm03:GM03_2_1Core.Core>
+      </gm03:DATASECTION>
+    </gm03:TRANSFER>
+    <gm03:TRANSFER>
+      <gm03:HEADERSECTION version="2.3" sender="pycsw">
+        <gm03:MODELS/>
+      </gm03:HEADERSECTION>
+      <gm03:DATASECTION>
+        <gm03:GM03_2_1Core.Core>
+          <gm03:GM03_2_1Core.Core.MD_Metadata>
+            <gm03:fileIdentifier>urn:uuid:9a669547-b69b-469f-a11f-2d875366bbdc</gm03:fileIdentifier>
+            <gm03:language/>
+            <gm03:dateStamp/>
+            <gm03:metadataStandardName>GM03</gm03:metadataStandardName>
+            <gm03:metadataStandardVersion>2.3</gm03:metadataStandardVersion>
+            <gm03:hierarchyLevel>
+              <gm03:GM03_2_1Core.Core.MD_ScopeCode_>
+                <gm03:value>http://purl.org/dc/dcmitype/Dataset</gm03:value>
+              </gm03:GM03_2_1Core.Core.MD_ScopeCode_>
+            </gm03:hierarchyLevel>
+            <gm03:parentIdentifier>
+              <gm03:GM03_2_1Core.Core.MD_ScopeCode_>
+                <gm03:value/>
+              </gm03:GM03_2_1Core.Core.MD_ScopeCode_>
+            </gm03:parentIdentifier>
+          </gm03:GM03_2_1Core.Core.MD_Metadata>
+          <gm03:GM03_2_1Core.Core.CI_Citation>
+            <gm03:title>
+              <gm03:GM03_2_1Core.Core.PT_FreeText>
+                <gm03:textGroup>
+                  <gm03:GM03_2_1Core.Core.PT_Group>
+                    <gm03:plainText>Ñunç elementum</gm03:plainText>
+                  </gm03:GM03_2_1Core.Core.PT_Group>
+                </gm03:textGroup>
+              </gm03:GM03_2_1Core.Core.PT_FreeText>
+            </gm03:title>
+          </gm03:GM03_2_1Core.Core.CI_Citation>
+          <gm03:GM03_2_1Core.Core.MD_DataIdentification>
+            <gm03:abstract>
+              <gm03:GM03_2_1Core.Core.PT_FreeText>
+                <gm03:textGroup>
+                  <gm03:GM03_2_1Core.Core.PT_Group>
+                    <gm03:plainText/>
+                  </gm03:GM03_2_1Core.Core.PT_Group>
+                </gm03:textGroup>
+              </gm03:GM03_2_1Core.Core.PT_FreeText>
+            </gm03:abstract>
+          </gm03:GM03_2_1Core.Core.MD_DataIdentification>
+          <gm03:GM03_2_1Core.Core.MD_Keywords>
+            <gm03:keyword>
+              <gm03:GM03_2_1Core.Core.PT_FreeText>
+                <gm03:textGroup>
+                  <gm03:GM03_2_1Core.Core.PT_Group>
+                    <gm03:plainText>Hydrography-Oceanographic</gm03:plainText>
+                  </gm03:GM03_2_1Core.Core.PT_Group>
+                </gm03:textGroup>
+              </gm03:GM03_2_1Core.Core.PT_FreeText>
+            </gm03:keyword>
+          </gm03:GM03_2_1Core.Core.MD_Keywords>
+          <gm03:GM03_2_1Core.Core.EX_GeographicBoundingBox>
+            <gm03:northBoundLatitude>51.13</gm03:northBoundLatitude>
+            <gm03:southBoundLatitude>44.79</gm03:southBoundLatitude>
+            <gm03:eastBoundLongitude>-6.17</gm03:eastBoundLongitude>
+            <gm03:westBoundLongitude>-2.23</gm03:westBoundLongitude>
+          </gm03:GM03_2_1Core.Core.EX_GeographicBoundingBox>
+        </gm03:GM03_2_1Core.Core>
+      </gm03:DATASECTION>
+    </gm03:TRANSFER>
+  </csw:SearchResults>
+</csw:GetRecordsResponse>
diff --git a/tests/expected/suites_harvesting_get_Exception-Harvest-invalid-resourcetype.xml b/tests/expected/suites_harvesting_get_Exception-Harvest-invalid-resourcetype.xml
index c3656bd..911ecc1 100644
--- a/tests/expected/suites_harvesting_get_Exception-Harvest-invalid-resourcetype.xml
+++ b/tests/expected/suites_harvesting_get_Exception-Harvest-invalid-resourcetype.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<ows:ExceptionReport xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:inspire_common="http://inspire.ec.europa.eu/schemas/common/1.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dct="http://purl.org/dc/terms/" xmlns:ows="http://www.opengis.net/ows" xmlns:apiso="http://www.opengis.net/cat/csw/apiso/1.0" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xlink="http://www.w3.org/1999/xlink" xml [...]
+<ows:ExceptionReport xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" language="en-US" version="1.2.0" xsi:schemaLocation="http://www.opengis.net/ows http://schemas.opengis.net/ows/1.0.0/ow [...]
   <ows:Exception exceptionCode="InvalidParameterValue" locator="resourcetype">
-    <ows:ExceptionText>Invalid resource type parameter: http://www.opengis.net/wms1234.            Allowable resourcetype values: http://www.opengis.net/cat/csw/2.0.2,http://www.opengis.net/wms,http://www.opengis.net/wfs,http://www.opengis.net/wcs,http://www.opengis.net/wps/1.0.0,http://www.opengis.net/sos/1.0,http://www.opengis.net/sos/2.0,http://www.isotc211.org/2005/gmi,urn:geoss:waf,http://www.isotc211.org/2005/gmd,http://www.isotc211.org/schemas/2005/gmd/,http://www.w3.org/2005/Atom [...]
+    <ows:ExceptionText>Invalid resource type parameter: http://www.opengis.net/wms1234.            Allowable resourcetype values: http://www.opengis.net/cat/csw/2.0.2,http://www.opengis.net/cat/csw/3.0,http://www.opengis.net/wms,http://www.opengis.net/wmts/1.0,http://www.opengis.net/wfs,http://www.opengis.net/wcs,http://www.opengis.net/wps/1.0.0,http://www.opengis.net/sos/1.0,http://www.opengis.net/sos/2.0,http://www.isotc211.org/2005/gmi,urn:geoss:waf,http://www.interlis.ch/INTERLIS2.3, [...]
   </ows:Exception>
 </ows:ExceptionReport>
diff --git a/tests/expected/suites_harvesting_get_Exception-Harvest-missing-resourcetype.xml b/tests/expected/suites_harvesting_get_Exception-Harvest-missing-resourcetype.xml
index f46e81b..36852c4 100644
--- a/tests/expected/suites_harvesting_get_Exception-Harvest-missing-resourcetype.xml
+++ b/tests/expected/suites_harvesting_get_Exception-Harvest-missing-resourcetype.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<ows:ExceptionReport xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:inspire_common="http://inspire.ec.europa.eu/schemas/common/1.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dct="http://purl.org/dc/terms/" xmlns:ows="http://www.opengis.net/ows" xmlns:apiso="http://www.opengis.net/cat/csw/apiso/1.0" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xlink="http://www.w3.org/1999/xlink" xml [...]
+<ows:ExceptionReport xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" language="en-US" version="1.2.0" xsi:schemaLocation="http://www.opengis.net/ows http://schemas.opengis.net/ows/1.0.0/ow [...]
   <ows:Exception exceptionCode="MissingParameterValue" locator="resourcetype">
     <ows:ExceptionText>Missing resourcetype parameter</ows:ExceptionText>
   </ows:Exception>
diff --git a/tests/expected/suites_harvesting_get_Exception-Harvest-missing-source.xml b/tests/expected/suites_harvesting_get_Exception-Harvest-missing-source.xml
index bbdf15c..250afe7 100644
--- a/tests/expected/suites_harvesting_get_Exception-Harvest-missing-source.xml
+++ b/tests/expected/suites_harvesting_get_Exception-Harvest-missing-source.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<ows:ExceptionReport xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:inspire_common="http://inspire.ec.europa.eu/schemas/common/1.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dct="http://purl.org/dc/terms/" xmlns:ows="http://www.opengis.net/ows" xmlns:apiso="http://www.opengis.net/cat/csw/apiso/1.0" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xlink="http://www.w3.org/1999/xlink" xml [...]
+<ows:ExceptionReport xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" language="en-US" version="1.2.0" xsi:schemaLocation="http://www.opengis.net/ows http://schemas.opengis.net/ows/1.0.0/ow [...]
   <ows:Exception exceptionCode="MissingParameterValue" locator="source">
     <ows:ExceptionText>Missing source parameter</ows:ExceptionText>
   </ows:Exception>
diff --git a/tests/expected/suites_harvesting_get_Exception-Harvest-waf-bad-value.xml b/tests/expected/suites_harvesting_get_Exception-Harvest-waf-bad-value.xml
index 5d7ad42..4739bff 100644
--- a/tests/expected/suites_harvesting_get_Exception-Harvest-waf-bad-value.xml
+++ b/tests/expected/suites_harvesting_get_Exception-Harvest-waf-bad-value.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<ows:ExceptionReport xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:inspire_common="http://inspire.ec.europa.eu/schemas/common/1.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dct="http://purl.org/dc/terms/" xmlns:ows="http://www.opengis.net/ows" xmlns:apiso="http://www.opengis.net/cat/csw/apiso/1.0" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xlink="http://www.w3.org/1999/xlink" xml [...]
+<ows:ExceptionReport xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" language="en-US" version="1.2.0" xsi:schemaLocation="http://www.opengis.net/ows http://schemas.opengis.net/ows/1.0.0/ow [...]
   <ows:Exception exceptionCode="NoApplicableCode" locator="source">
     <ows:ExceptionText>Harvest failed: record parsing failed: unknown url type: badvalue</ows:ExceptionText>
   </ows:Exception>
diff --git a/tests/expected/suites_harvesting_get_Exception-Harvest-waf-no-records-found.xml b/tests/expected/suites_harvesting_get_Exception-Harvest-waf-no-records-found.xml
index 5904e69..177601c 100644
--- a/tests/expected/suites_harvesting_get_Exception-Harvest-waf-no-records-found.xml
+++ b/tests/expected/suites_harvesting_get_Exception-Harvest-waf-no-records-found.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<csw:HarvestResponse xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:inspire_common="http://inspire.ec.europa.eu/schemas/common/1.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dct="http://purl.org/dc/terms/" xmlns:ows="http://www.opengis.net/ows" xmlns:apiso="http://www.opengis.net/cat/csw/apiso/1.0" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xlink="http://www.w3.org/1999/xlink" xml [...]
+<csw:HarvestResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/cat/csw/2.0.2 http://schemas.opengis.net/csw/2.0.2/CSW-publication.xsd">
   <csw:TransactionResponse version="2.0.2">
     <csw:TransactionSummary>
       <csw:totalInserted>0</csw:totalInserted>
diff --git a/tests/expected/suites_harvesting_post_Clear-000-delete-all.xml b/tests/expected/suites_harvesting_post_Clear-000-delete-all.xml
index 381db66..01ccdf6 100644
--- a/tests/expected/suites_harvesting_post_Clear-000-delete-all.xml
+++ b/tests/expected/suites_harvesting_post_Clear-000-delete-all.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<csw:TransactionResponse xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:inspire_common="http://inspire.ec.europa.eu/schemas/common/1.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dct="http://purl.org/dc/terms/" xmlns:ows="http://www.opengis.net/ows" xmlns:apiso="http://www.opengis.net/cat/csw/apiso/1.0" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xlink="http://www.w3.org/1999/xlink" [...]
+<csw:TransactionResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.0.2" xsi:schemaLocation="http://www.opengis.net/cat/csw/2.0.2 http://schemas.opengis.net/csw/2.0.2/CSW-p [...]
   <csw:TransactionSummary>
     <csw:totalInserted>0</csw:totalInserted>
     <csw:totalUpdated>0</csw:totalUpdated>
diff --git a/tests/expected/suites_harvesting_post_Exception-Havest-csw-404.xml b/tests/expected/suites_harvesting_post_Exception-Havest-csw-404.xml
index b981c03..371aae9 100644
--- a/tests/expected/suites_harvesting_post_Exception-Havest-csw-404.xml
+++ b/tests/expected/suites_harvesting_post_Exception-Havest-csw-404.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<ows:ExceptionReport xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:inspire_common="http://inspire.ec.europa.eu/schemas/common/1.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dct="http://purl.org/dc/terms/" xmlns:ows="http://www.opengis.net/ows" xmlns:apiso="http://www.opengis.net/cat/csw/apiso/1.0" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xlink="http://www.w3.org/1999/xlink" xml [...]
+<ows:ExceptionReport xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" language="en-US" version="1.2.0" xsi:schemaLocation="http://www.opengis.net/ows http://schemas.opengis.net/ows/1.0.0/ow [...]
   <ows:Exception exceptionCode="NoApplicableCode" locator="source">
     <ows:ExceptionText>Harvest failed: record parsing failed: HTTP error: HTTP Error 404: Not Found</ows:ExceptionText>
   </ows:Exception>
diff --git a/tests/expected/suites_harvesting_post_GetCapabilities.xml b/tests/expected/suites_harvesting_post_GetCapabilities.xml
index 474485d..aa92372 100644
--- a/tests/expected/suites_harvesting_post_GetCapabilities.xml
+++ b/tests/expected/suites_harvesting_post_GetCapabilities.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<csw:Capabilities xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:inspire_common="http://inspire.ec.europa.eu/schemas/common/1.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dct="http://purl.org/dc/terms/" xmlns:ows="http://www.opengis.net/ows" xmlns:apiso="http://www.opengis.net/cat/csw/apiso/1.0" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns: [...]
+<csw:Capabilities xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ogc="http://www.opengis.net/ogc" xmlns:ows="http://www.opengis.net/ows" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" updateSequence="PYCSW_UPDATESEQUENCE" ve [...]
   <ows:ServiceIdentification>
     <ows:Title>pycsw Geospatial Catalogue</ows:Title>
     <ows:Abstract>pycsw is an OGC CSW server implementation written in Python</ows:Abstract>
@@ -11,6 +11,7 @@
     </ows:Keywords>
     <ows:ServiceType codeSpace="OGC">CSW</ows:ServiceType>
     <ows:ServiceTypeVersion>2.0.2</ows:ServiceTypeVersion>
+    <ows:ServiceTypeVersion>3.0.0</ows:ServiceTypeVersion>
     <ows:Fees>None</ows:Fees>
     <ows:AccessConstraints>None</ows:AccessConstraints>
   </ows:ServiceIdentification>
@@ -61,6 +62,19 @@
           <ows:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/harvesting/default.cfg"/>
         </ows:HTTP>
       </ows:DCP>
+      <ows:Parameter name="TransactionSchemas">
+        <ows:Value>http://www.isotc211.org/2005/gmi</ows:Value>
+        <ows:Value>http://www.opengis.net/cat/csw/2.0.2</ows:Value>
+        <ows:Value>http://www.opengis.net/cat/csw/3.0</ows:Value>
+        <ows:Value>http://www.opengis.net/sos/1.0</ows:Value>
+        <ows:Value>http://www.opengis.net/sos/2.0</ows:Value>
+        <ows:Value>http://www.opengis.net/wcs</ows:Value>
+        <ows:Value>http://www.opengis.net/wfs</ows:Value>
+        <ows:Value>http://www.opengis.net/wms</ows:Value>
+        <ows:Value>http://www.opengis.net/wmts/1.0</ows:Value>
+        <ows:Value>http://www.opengis.net/wps/1.0.0</ows:Value>
+        <ows:Value>urn:geoss:waf</ows:Value>
+      </ows:Parameter>
     </ows:Operation>
     <ows:Operation name="GetRepositoryItem">
       <ows:DCP>
@@ -99,6 +113,7 @@
       </ows:DCP>
       <ows:Parameter name="ParameterName">
         <ows:Value>GetCapabilities.sections</ows:Value>
+        <ows:Value>Transaction.TransactionSchemas</ows:Value>
         <ows:Value>DescribeRecord.schemaLanguage</ows:Value>
         <ows:Value>DescribeRecord.outputFormat</ows:Value>
         <ows:Value>DescribeRecord.typeName</ows:Value>
@@ -127,10 +142,11 @@
       </ows:Parameter>
       <ows:Parameter name="outputSchema">
         <ows:Value>http://www.opengis.net/cat/csw/2.0.2</ows:Value>
-        <ows:Value>http://www.isotc211.org/2005/gmd</ows:Value>
-        <ows:Value>http://www.w3.org/2005/Atom</ows:Value>
-        <ows:Value>http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/</ows:Value>
+        <ows:Value>http://www.interlis.ch/INTERLIS2.3</ows:Value>
         <ows:Value>http://www.opengis.net/cat/csw/csdgm</ows:Value>
+        <ows:Value>http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/</ows:Value>
+        <ows:Value>http://www.w3.org/2005/Atom</ows:Value>
+        <ows:Value>http://www.isotc211.org/2005/gmd</ows:Value>
       </ows:Parameter>
       <ows:Parameter name="ElementSetName">
         <ows:Value>brief</ows:Value>
@@ -151,10 +167,11 @@
       </ows:Parameter>
       <ows:Parameter name="outputSchema">
         <ows:Value>http://www.opengis.net/cat/csw/2.0.2</ows:Value>
-        <ows:Value>http://www.isotc211.org/2005/gmd</ows:Value>
-        <ows:Value>http://www.w3.org/2005/Atom</ows:Value>
-        <ows:Value>http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/</ows:Value>
+        <ows:Value>http://www.interlis.ch/INTERLIS2.3</ows:Value>
         <ows:Value>http://www.opengis.net/cat/csw/csdgm</ows:Value>
+        <ows:Value>http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/</ows:Value>
+        <ows:Value>http://www.w3.org/2005/Atom</ows:Value>
+        <ows:Value>http://www.isotc211.org/2005/gmd</ows:Value>
       </ows:Parameter>
       <ows:Parameter name="CONSTRAINTLANGUAGE">
         <ows:Value>FILTER</ows:Value>
@@ -254,7 +271,9 @@
       </ows:DCP>
       <ows:Parameter name="ResourceType">
         <ows:Value>http://www.opengis.net/cat/csw/2.0.2</ows:Value>
+        <ows:Value>http://www.opengis.net/cat/csw/3.0</ows:Value>
         <ows:Value>http://www.opengis.net/wms</ows:Value>
+        <ows:Value>http://www.opengis.net/wmts/1.0</ows:Value>
         <ows:Value>http://www.opengis.net/wfs</ows:Value>
         <ows:Value>http://www.opengis.net/wcs</ows:Value>
         <ows:Value>http://www.opengis.net/wps/1.0.0</ows:Value>
@@ -262,15 +281,17 @@
         <ows:Value>http://www.opengis.net/sos/2.0</ows:Value>
         <ows:Value>http://www.isotc211.org/2005/gmi</ows:Value>
         <ows:Value>urn:geoss:waf</ows:Value>
+        <ows:Value>http://www.interlis.ch/INTERLIS2.3</ows:Value>
+        <ows:Value>http://www.opengis.net/cat/csw/csdgm</ows:Value>
+        <ows:Value>http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/</ows:Value>
+        <ows:Value>http://www.w3.org/2005/Atom</ows:Value>
         <ows:Value>http://www.isotc211.org/2005/gmd</ows:Value>
         <ows:Value>http://www.isotc211.org/schemas/2005/gmd/</ows:Value>
-        <ows:Value>http://www.w3.org/2005/Atom</ows:Value>
-        <ows:Value>http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/</ows:Value>
-        <ows:Value>http://www.opengis.net/cat/csw/csdgm</ows:Value>
       </ows:Parameter>
     </ows:Operation>
     <ows:Parameter name="version">
       <ows:Value>2.0.2</ows:Value>
+      <ows:Value>3.0.0</ows:Value>
     </ows:Parameter>
     <ows:Parameter name="service">
       <ows:Value>CSW</ows:Value>
diff --git a/tests/expected/suites_harvesting_post_GetDomain-parameter.xml b/tests/expected/suites_harvesting_post_GetDomain-parameter.xml
index 01db252..336bfe2 100644
--- a/tests/expected/suites_harvesting_post_GetDomain-parameter.xml
+++ b/tests/expected/suites_harvesting_post_GetDomain-parameter.xml
@@ -1,11 +1,13 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<csw:GetDomainResponse xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:inspire_common="http://inspire.ec.europa.eu/schemas/common/1.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dct="http://purl.org/dc/terms/" xmlns:ows="http://www.opengis.net/ows" xmlns:apiso="http://www.opengis.net/cat/csw/apiso/1.0" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xlink="http://www.w3.org/1999/xlink" x [...]
+<csw:GetDomainResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/cat/csw/2.0.2 http://schemas.opengis.net/csw/2.0.2/CSW-discovery.xsd">
   <csw:DomainValues type="csw:Record">
     <csw:ParameterName>Harvest.ResourceType</csw:ParameterName>
     <csw:ListOfValues>
       <csw:Value>http://www.opengis.net/cat/csw/2.0.2</csw:Value>
+      <csw:Value>http://www.opengis.net/cat/csw/3.0</csw:Value>
       <csw:Value>http://www.opengis.net/wms</csw:Value>
+      <csw:Value>http://www.opengis.net/wmts/1.0</csw:Value>
       <csw:Value>http://www.opengis.net/wfs</csw:Value>
       <csw:Value>http://www.opengis.net/wcs</csw:Value>
       <csw:Value>http://www.opengis.net/wps/1.0.0</csw:Value>
@@ -13,11 +15,12 @@
       <csw:Value>http://www.opengis.net/sos/2.0</csw:Value>
       <csw:Value>http://www.isotc211.org/2005/gmi</csw:Value>
       <csw:Value>urn:geoss:waf</csw:Value>
+      <csw:Value>http://www.interlis.ch/INTERLIS2.3</csw:Value>
+      <csw:Value>http://www.opengis.net/cat/csw/csdgm</csw:Value>
+      <csw:Value>http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/</csw:Value>
+      <csw:Value>http://www.w3.org/2005/Atom</csw:Value>
       <csw:Value>http://www.isotc211.org/2005/gmd</csw:Value>
       <csw:Value>http://www.isotc211.org/schemas/2005/gmd/</csw:Value>
-      <csw:Value>http://www.w3.org/2005/Atom</csw:Value>
-      <csw:Value>http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/</csw:Value>
-      <csw:Value>http://www.opengis.net/cat/csw/csdgm</csw:Value>
     </csw:ListOfValues>
   </csw:DomainValues>
 </csw:GetDomainResponse>
diff --git a/tests/expected/suites_harvesting_post_Harvest-csw-iso.xml b/tests/expected/suites_harvesting_post_Harvest-csw-iso.xml
index 2e34654..1aa0f2b 100644
--- a/tests/expected/suites_harvesting_post_Harvest-csw-iso.xml
+++ b/tests/expected/suites_harvesting_post_Harvest-csw-iso.xml
@@ -1,176 +1,148 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<csw:HarvestResponse xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:inspire_common="http://inspire.ec.europa.eu/schemas/common/1.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dct="http://purl.org/dc/terms/" xmlns:ows="http://www.opengis.net/ows" xmlns:apiso="http://www.opengis.net/cat/csw/apiso/1.0" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xlink="http://www.w3.org/1999/xlink" xml [...]
+<csw:HarvestResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/cat/csw/2.0.2 http://schemas.opengis.net/csw/2.0.2/CSW-publication.xsd">
   <csw:TransactionResponse version="2.0.2">
     <csw:TransactionSummary>
-      <csw:totalInserted>41</csw:totalInserted>
+      <csw:totalInserted>34</csw:totalInserted>
       <csw:totalUpdated>0</csw:totalUpdated>
       <csw:totalDeleted>0</csw:totalDeleted>
     </csw:TransactionSummary>
     <csw:InsertResult>
       <csw:BriefRecord>
         <dc:identifier>PYCSW_IDENTIFIER</dc:identifier>
-        <dc:title/>
+        <dc:title>pycsw Geospatial Catalogue OGC services demo</dc:title>
       </csw:BriefRecord>
       <csw:BriefRecord>
         <dc:identifier>PYCSW_IDENTIFIER</dc:identifier>
-        <dc:title/>
+        <dc:title>1 Million Scale WMS Layers from the National Atlas of the United States</dc:title>
       </csw:BriefRecord>
       <csw:BriefRecord>
-        <dc:identifier>PYCSW_IDENTIFIER</dc:identifier>
-        <dc:title/>
+        <dc:identifier>PYCSW_IDENTIFIER-ports1m</dc:identifier>
+        <dc:title>1 Million Scale - Ports</dc:title>
       </csw:BriefRecord>
       <csw:BriefRecord>
-        <dc:identifier>PYCSW_IDENTIFIER</dc:identifier>
-        <dc:title/>
+        <dc:identifier>PYCSW_IDENTIFIER-national1m</dc:identifier>
+        <dc:title>1 Million Scale - National Boundary</dc:title>
       </csw:BriefRecord>
       <csw:BriefRecord>
-        <dc:identifier>PYCSW_IDENTIFIER</dc:identifier>
-        <dc:title/>
+        <dc:identifier>PYCSW_IDENTIFIER-elevation</dc:identifier>
+        <dc:title>1 Million Scale - Elevation 100 Meter Resolution</dc:title>
       </csw:BriefRecord>
       <csw:BriefRecord>
-        <dc:identifier>PYCSW_IDENTIFIER</dc:identifier>
-        <dc:title/>
+        <dc:identifier>PYCSW_IDENTIFIER-impervious</dc:identifier>
+        <dc:title>1 Million Scale - Impervious Surface 100 Meter Resolution</dc:title>
       </csw:BriefRecord>
       <csw:BriefRecord>
-        <dc:identifier>PYCSW_IDENTIFIER</dc:identifier>
-        <dc:title/>
+        <dc:identifier>PYCSW_IDENTIFIER-coast1m</dc:identifier>
+        <dc:title>1 Million Scale - Coastlines</dc:title>
       </csw:BriefRecord>
       <csw:BriefRecord>
-        <dc:identifier>PYCSW_IDENTIFIER</dc:identifier>
-        <dc:title/>
+        <dc:identifier>PYCSW_IDENTIFIER-cdl</dc:identifier>
+        <dc:title>1 Million Scale - 113th Congressional Districts</dc:title>
       </csw:BriefRecord>
       <csw:BriefRecord>
-        <dc:identifier>PYCSW_IDENTIFIER</dc:identifier>
-        <dc:title/>
+        <dc:identifier>PYCSW_IDENTIFIER-states1m</dc:identifier>
+        <dc:title>1 Million Scale - States</dc:title>
       </csw:BriefRecord>
       <csw:BriefRecord>
-        <dc:identifier>PYCSW_IDENTIFIER</dc:identifier>
-        <dc:title/>
+        <dc:identifier>PYCSW_IDENTIFIER-elsli0100g</dc:identifier>
+        <dc:title>1 Million Scale - Color-Sliced Elevation 100 Meter Resolution</dc:title>
       </csw:BriefRecord>
       <csw:BriefRecord>
-        <dc:identifier>PYCSW_IDENTIFIER</dc:identifier>
-        <dc:title/>
+        <dc:identifier>PYCSW_IDENTIFIER-landcov100m</dc:identifier>
+        <dc:title>1 Million Scale - Land Cover 100 Meter Resolution</dc:title>
       </csw:BriefRecord>
       <csw:BriefRecord>
-        <dc:identifier>PYCSW_IDENTIFIER</dc:identifier>
-        <dc:title/>
+        <dc:identifier>PYCSW_IDENTIFIER-cdp</dc:identifier>
+        <dc:title>1 Million Scale - 113th Congressional Districts by Party</dc:title>
       </csw:BriefRecord>
       <csw:BriefRecord>
-        <dc:identifier>PYCSW_IDENTIFIER</dc:identifier>
-        <dc:title/>
+        <dc:identifier>PYCSW_IDENTIFIER-amtrak1m</dc:identifier>
+        <dc:title>1 Million Scale - Railroad and Bus Passenger Stations</dc:title>
       </csw:BriefRecord>
       <csw:BriefRecord>
-        <dc:identifier>PYCSW_IDENTIFIER</dc:identifier>
-        <dc:title/>
+        <dc:identifier>PYCSW_IDENTIFIER-airports1m</dc:identifier>
+        <dc:title>1 Million Scale - Airports</dc:title>
       </csw:BriefRecord>
       <csw:BriefRecord>
-        <dc:identifier>PYCSW_IDENTIFIER</dc:identifier>
-        <dc:title/>
+        <dc:identifier>PYCSW_IDENTIFIER-one_million</dc:identifier>
+        <dc:title>1 Million Scale WMS Layers from the National Atlas of the United States</dc:title>
       </csw:BriefRecord>
       <csw:BriefRecord>
-        <dc:identifier>PYCSW_IDENTIFIER</dc:identifier>
-        <dc:title/>
+        <dc:identifier>PYCSW_IDENTIFIER-satvi0100g</dc:identifier>
+        <dc:title>1 Million Scale - Satellite View 100 Meter Resolution</dc:title>
       </csw:BriefRecord>
       <csw:BriefRecord>
-        <dc:identifier>PYCSW_IDENTIFIER</dc:identifier>
-        <dc:title/>
+        <dc:identifier>PYCSW_IDENTIFIER-srcoi0100g</dc:identifier>
+        <dc:title>1 Million Scale - Color Shaded Relief 100 Meter Resolution</dc:title>
       </csw:BriefRecord>
       <csw:BriefRecord>
-        <dc:identifier>PYCSW_IDENTIFIER</dc:identifier>
-        <dc:title/>
+        <dc:identifier>PYCSW_IDENTIFIER-srgri0100g</dc:identifier>
+        <dc:title>1 Million Scale - Gray Shaded Relief 100 Meter Resolution</dc:title>
       </csw:BriefRecord>
       <csw:BriefRecord>
-        <dc:identifier>PYCSW_IDENTIFIER</dc:identifier>
-        <dc:title/>
+        <dc:identifier>PYCSW_IDENTIFIER-treecanopy</dc:identifier>
+        <dc:title>1 Million Scale - Tree Canopy 100 Meter Resolution</dc:title>
       </csw:BriefRecord>
       <csw:BriefRecord>
-        <dc:identifier>PYCSW_IDENTIFIER</dc:identifier>
-        <dc:title/>
+        <dc:identifier>PYCSW_IDENTIFIER-svsri0100g</dc:identifier>
+        <dc:title>1 Million Scale - Satellite View with Shaded Relief 100 Meter Resolution</dc:title>
       </csw:BriefRecord>
       <csw:BriefRecord>
         <dc:identifier>PYCSW_IDENTIFIER</dc:identifier>
-        <dc:title/>
+        <dc:title>Wisconsin Lake Clarity</dc:title>
       </csw:BriefRecord>
       <csw:BriefRecord>
-        <dc:identifier>PYCSW_IDENTIFIER</dc:identifier>
-        <dc:title/>
+        <dc:identifier>PYCSW_IDENTIFIER-Highways</dc:identifier>
+        <dc:title>Highways</dc:title>
       </csw:BriefRecord>
       <csw:BriefRecord>
-        <dc:identifier>PYCSW_IDENTIFIER</dc:identifier>
-        <dc:title/>
+        <dc:identifier>PYCSW_IDENTIFIER-LakesTSI</dc:identifier>
+        <dc:title>LakesTSI</dc:title>
       </csw:BriefRecord>
       <csw:BriefRecord>
-        <dc:identifier>PYCSW_IDENTIFIER</dc:identifier>
-        <dc:title/>
+        <dc:identifier>PYCSW_IDENTIFIER-LakeClarity</dc:identifier>
+        <dc:title>Wisconsin Lake Clarity</dc:title>
       </csw:BriefRecord>
       <csw:BriefRecord>
-        <dc:identifier>PYCSW_IDENTIFIER</dc:identifier>
-        <dc:title/>
+        <dc:identifier>PYCSW_IDENTIFIER-LakesTSI_0305</dc:identifier>
+        <dc:title>LakesTSI_0305</dc:title>
       </csw:BriefRecord>
       <csw:BriefRecord>
-        <dc:identifier>PYCSW_IDENTIFIER</dc:identifier>
-        <dc:title/>
+        <dc:identifier>PYCSW_IDENTIFIER-Relief</dc:identifier>
+        <dc:title>Relief</dc:title>
       </csw:BriefRecord>
       <csw:BriefRecord>
-        <dc:identifier>PYCSW_IDENTIFIER_gen0</dc:identifier>
-        <dc:title/>
+        <dc:identifier>PYCSW_IDENTIFIER-LakeNames_0305</dc:identifier>
+        <dc:title>LakeNames_0305</dc:title>
       </csw:BriefRecord>
       <csw:BriefRecord>
-        <dc:identifier>PYCSW_IDENTIFIER</dc:identifier>
-        <dc:title/>
+        <dc:identifier>PYCSW_IDENTIFIER-Roads</dc:identifier>
+        <dc:title>Roads</dc:title>
       </csw:BriefRecord>
       <csw:BriefRecord>
-        <dc:identifier>PYCSW_IDENTIFIER</dc:identifier>
-        <dc:title/>
-      </csw:BriefRecord>
-      <csw:BriefRecord>
-        <dc:identifier>PYCSW_IDENTIFIER</dc:identifier>
-        <dc:title/>
-      </csw:BriefRecord>
-      <csw:BriefRecord>
-        <dc:identifier>PYCSW_IDENTIFIER</dc:identifier>
-        <dc:title/>
-      </csw:BriefRecord>
-      <csw:BriefRecord>
-        <dc:identifier>PYCSW_IDENTIFIER_gen1</dc:identifier>
-        <dc:title/>
+        <dc:identifier>PYCSW_IDENTIFIER-LakeNames</dc:identifier>
+        <dc:title>LakeNames</dc:title>
       </csw:BriefRecord>
       <csw:BriefRecord>
-        <dc:identifier>PYCSW_IDENTIFIER_gen0</dc:identifier>
-        <dc:title/>
+        <dc:identifier>PYCSW_IDENTIFIER-Counties</dc:identifier>
+        <dc:title>Counties</dc:title>
       </csw:BriefRecord>
       <csw:BriefRecord>
         <dc:identifier>PYCSW_IDENTIFIER</dc:identifier>
-        <dc:title/>
+        <dc:title>View & download service for EU-DEM data provided by EOX</dc:title>
       </csw:BriefRecord>
       <csw:BriefRecord>
-        <dc:identifier>PYCSW_IDENTIFIER_gen1</dc:identifier>
-        <dc:title/>
+        <dc:identifier>PYCSW_IDENTIFIER-EU-DEM</dc:identifier>
+        <dc:title>EU-DEM</dc:title>
       </csw:BriefRecord>
       <csw:BriefRecord>
-        <dc:identifier>PYCSW_IDENTIFIER</dc:identifier>
-        <dc:title/>
+        <dc:identifier>PYCSW_IDENTIFIER-MS</dc:identifier>
+        <dc:title>View & download service for EU-DEM data provided by EOX</dc:title>
       </csw:BriefRecord>
       <csw:BriefRecord>
-        <dc:identifier>PYCSW_IDENTIFIER</dc:identifier>
-        <dc:title/>
-      </csw:BriefRecord>
-      <csw:BriefRecord>
-        <dc:identifier>PYCSW_IDENTIFIER</dc:identifier>
-        <dc:title/>
-      </csw:BriefRecord>
-      <csw:BriefRecord>
-        <dc:identifier>PYCSW_IDENTIFIER</dc:identifier>
-        <dc:title/>
-      </csw:BriefRecord>
-      <csw:BriefRecord>
-        <dc:identifier>PYCSW_IDENTIFIER</dc:identifier>
-        <dc:title/>
-      </csw:BriefRecord>
-      <csw:BriefRecord>
-        <dc:identifier>PYCSW_IDENTIFIER</dc:identifier>
-        <dc:title/>
+        <dc:identifier>PYCSW_IDENTIFIER-eudem_color</dc:identifier>
+        <dc:title>EU-DEM color shaded</dc:title>
       </csw:BriefRecord>
     </csw:InsertResult>
   </csw:TransactionResponse>
diff --git a/tests/expected/suites_harvesting_post_Harvest-csw-run1.xml b/tests/expected/suites_harvesting_post_Harvest-csw-run1.xml
index 96d5d63..5786b54 100644
--- a/tests/expected/suites_harvesting_post_Harvest-csw-run1.xml
+++ b/tests/expected/suites_harvesting_post_Harvest-csw-run1.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<csw:HarvestResponse xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:inspire_common="http://inspire.ec.europa.eu/schemas/common/1.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dct="http://purl.org/dc/terms/" xmlns:ows="http://www.opengis.net/ows" xmlns:apiso="http://www.opengis.net/cat/csw/apiso/1.0" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xlink="http://www.w3.org/1999/xlink" xml [...]
+<csw:HarvestResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/cat/csw/2.0.2 http://schemas.opengis.net/csw/2.0.2/CSW-publication.xsd">
   <csw:TransactionResponse version="2.0.2">
     <csw:TransactionSummary>
       <csw:totalInserted>13</csw:totalInserted>
@@ -10,7 +10,7 @@
     <csw:InsertResult>
       <csw:BriefRecord>
         <dc:identifier>PYCSW_IDENTIFIER</dc:identifier>
-        <dc:title>pycsw Geospatial Catalogue OGC CITE demo and Reference Implementation</dc:title>
+        <dc:title>pycsw OGC CITE demo and Reference Implementation</dc:title>
       </csw:BriefRecord>
       <csw:BriefRecord>
         <dc:identifier>PYCSW_IDENTIFIER</dc:identifier>
diff --git a/tests/expected/suites_harvesting_post_Harvest-csw-run2.xml b/tests/expected/suites_harvesting_post_Harvest-csw-run2.xml
index 2fb706d..c61dad4 100644
--- a/tests/expected/suites_harvesting_post_Harvest-csw-run2.xml
+++ b/tests/expected/suites_harvesting_post_Harvest-csw-run2.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<csw:HarvestResponse xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:inspire_common="http://inspire.ec.europa.eu/schemas/common/1.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dct="http://purl.org/dc/terms/" xmlns:ows="http://www.opengis.net/ows" xmlns:apiso="http://www.opengis.net/cat/csw/apiso/1.0" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xlink="http://www.w3.org/1999/xlink" xml [...]
+<csw:HarvestResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/cat/csw/2.0.2 http://schemas.opengis.net/csw/2.0.2/CSW-publication.xsd">
   <csw:TransactionResponse version="2.0.2">
     <csw:TransactionSummary>
       <csw:totalInserted>0</csw:totalInserted>
diff --git a/tests/expected/suites_harvesting_post_Harvest-dc.xml b/tests/expected/suites_harvesting_post_Harvest-dc.xml
index db4ed11..58d6d50 100644
--- a/tests/expected/suites_harvesting_post_Harvest-dc.xml
+++ b/tests/expected/suites_harvesting_post_Harvest-dc.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<csw:HarvestResponse xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:inspire_common="http://inspire.ec.europa.eu/schemas/common/1.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dct="http://purl.org/dc/terms/" xmlns:ows="http://www.opengis.net/ows" xmlns:apiso="http://www.opengis.net/cat/csw/apiso/1.0" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xlink="http://www.w3.org/1999/xlink" xml [...]
+<csw:HarvestResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/cat/csw/2.0.2 http://schemas.opengis.net/csw/2.0.2/CSW-publication.xsd">
   <csw:TransactionResponse version="2.0.2">
     <csw:TransactionSummary>
       <csw:totalInserted>1</csw:totalInserted>
diff --git a/tests/expected/suites_harvesting_post_Harvest-fgdc.xml b/tests/expected/suites_harvesting_post_Harvest-fgdc.xml
index c4671a3..c12247f 100644
--- a/tests/expected/suites_harvesting_post_Harvest-fgdc.xml
+++ b/tests/expected/suites_harvesting_post_Harvest-fgdc.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<csw:HarvestResponse xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:inspire_common="http://inspire.ec.europa.eu/schemas/common/1.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dct="http://purl.org/dc/terms/" xmlns:ows="http://www.opengis.net/ows" xmlns:apiso="http://www.opengis.net/cat/csw/apiso/1.0" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xlink="http://www.w3.org/1999/xlink" xml [...]
+<csw:HarvestResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/cat/csw/2.0.2 http://schemas.opengis.net/csw/2.0.2/CSW-publication.xsd">
   <csw:TransactionResponse version="2.0.2">
     <csw:TransactionSummary>
       <csw:totalInserted>1</csw:totalInserted>
diff --git a/tests/expected/suites_harvesting_post_Harvest-iso.xml b/tests/expected/suites_harvesting_post_Harvest-iso.xml
index e0669d0..98b9770 100644
--- a/tests/expected/suites_harvesting_post_Harvest-iso.xml
+++ b/tests/expected/suites_harvesting_post_Harvest-iso.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<csw:HarvestResponse xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:inspire_common="http://inspire.ec.europa.eu/schemas/common/1.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dct="http://purl.org/dc/terms/" xmlns:ows="http://www.opengis.net/ows" xmlns:apiso="http://www.opengis.net/cat/csw/apiso/1.0" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xlink="http://www.w3.org/1999/xlink" xml [...]
+<csw:HarvestResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/cat/csw/2.0.2 http://schemas.opengis.net/csw/2.0.2/CSW-publication.xsd">
   <csw:TransactionResponse version="2.0.2">
     <csw:TransactionSummary>
       <csw:totalInserted>1</csw:totalInserted>
diff --git a/tests/expected/suites_harvesting_post_Harvest-rdf.xml b/tests/expected/suites_harvesting_post_Harvest-rdf.xml
index 567c312..2e926c2 100644
--- a/tests/expected/suites_harvesting_post_Harvest-rdf.xml
+++ b/tests/expected/suites_harvesting_post_Harvest-rdf.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<csw:HarvestResponse xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:inspire_common="http://inspire.ec.europa.eu/schemas/common/1.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dct="http://purl.org/dc/terms/" xmlns:ows="http://www.opengis.net/ows" xmlns:apiso="http://www.opengis.net/cat/csw/apiso/1.0" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xlink="http://www.w3.org/1999/xlink" xml [...]
+<csw:HarvestResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/cat/csw/2.0.2 http://schemas.opengis.net/csw/2.0.2/CSW-publication.xsd">
   <csw:TransactionResponse version="2.0.2">
     <csw:TransactionSummary>
       <csw:totalInserted>1</csw:totalInserted>
diff --git a/tests/expected/suites_harvesting_post_Harvest-sos100.xml b/tests/expected/suites_harvesting_post_Harvest-sos100.xml
index d331bda..62e8fc1 100644
--- a/tests/expected/suites_harvesting_post_Harvest-sos100.xml
+++ b/tests/expected/suites_harvesting_post_Harvest-sos100.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<csw:HarvestResponse xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:inspire_common="http://inspire.ec.europa.eu/schemas/common/1.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dct="http://purl.org/dc/terms/" xmlns:ows="http://www.opengis.net/ows" xmlns:apiso="http://www.opengis.net/cat/csw/apiso/1.0" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xlink="http://www.w3.org/1999/xlink" xml [...]
+<csw:HarvestResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/cat/csw/2.0.2 http://schemas.opengis.net/csw/2.0.2/CSW-publication.xsd">
   <csw:TransactionResponse version="2.0.2">
     <csw:TransactionSummary>
       <csw:totalInserted>29</csw:totalInserted>
diff --git a/tests/expected/suites_harvesting_post_Harvest-sos200.xml b/tests/expected/suites_harvesting_post_Harvest-sos200.xml
index d5d99f9..b41170b 100644
--- a/tests/expected/suites_harvesting_post_Harvest-sos200.xml
+++ b/tests/expected/suites_harvesting_post_Harvest-sos200.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<csw:HarvestResponse xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:inspire_common="http://inspire.ec.europa.eu/schemas/common/1.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dct="http://purl.org/dc/terms/" xmlns:ows="http://www.opengis.net/ows" xmlns:apiso="http://www.opengis.net/cat/csw/apiso/1.0" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xlink="http://www.w3.org/1999/xlink" xml [...]
+<csw:HarvestResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/cat/csw/2.0.2 http://schemas.opengis.net/csw/2.0.2/CSW-publication.xsd">
   <csw:TransactionResponse version="2.0.2">
     <csw:TransactionSummary>
       <csw:totalInserted>2</csw:totalInserted>
diff --git a/tests/expected/suites_harvesting_post_Harvest-waf.xml b/tests/expected/suites_harvesting_post_Harvest-waf.xml
index dc67736..75b6027 100644
--- a/tests/expected/suites_harvesting_post_Harvest-waf.xml
+++ b/tests/expected/suites_harvesting_post_Harvest-waf.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<csw:HarvestResponse xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:inspire_common="http://inspire.ec.europa.eu/schemas/common/1.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dct="http://purl.org/dc/terms/" xmlns:ows="http://www.opengis.net/ows" xmlns:apiso="http://www.opengis.net/cat/csw/apiso/1.0" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xlink="http://www.w3.org/1999/xlink" xml [...]
+<csw:HarvestResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/cat/csw/2.0.2 http://schemas.opengis.net/csw/2.0.2/CSW-publication.xsd">
   <csw:TransactionResponse version="2.0.2">
     <csw:TransactionSummary>
       <csw:totalInserted>3</csw:totalInserted>
diff --git a/tests/expected/suites_harvesting_post_Harvest-wcs.xml b/tests/expected/suites_harvesting_post_Harvest-wcs.xml
index 789e1f2..a5dcbed 100644
--- a/tests/expected/suites_harvesting_post_Harvest-wcs.xml
+++ b/tests/expected/suites_harvesting_post_Harvest-wcs.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<csw:HarvestResponse xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:inspire_common="http://inspire.ec.europa.eu/schemas/common/1.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dct="http://purl.org/dc/terms/" xmlns:ows="http://www.opengis.net/ows" xmlns:apiso="http://www.opengis.net/cat/csw/apiso/1.0" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xlink="http://www.w3.org/1999/xlink" xml [...]
+<csw:HarvestResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/cat/csw/2.0.2 http://schemas.opengis.net/csw/2.0.2/CSW-publication.xsd">
   <csw:TransactionResponse version="2.0.2">
     <csw:TransactionSummary>
       <csw:totalInserted>5</csw:totalInserted>
diff --git a/tests/expected/suites_harvesting_post_Harvest-wfs.xml b/tests/expected/suites_harvesting_post_Harvest-wfs.xml
index a47baa3..96ec6fe 100644
--- a/tests/expected/suites_harvesting_post_Harvest-wfs.xml
+++ b/tests/expected/suites_harvesting_post_Harvest-wfs.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<csw:HarvestResponse xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:inspire_common="http://inspire.ec.europa.eu/schemas/common/1.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dct="http://purl.org/dc/terms/" xmlns:ows="http://www.opengis.net/ows" xmlns:apiso="http://www.opengis.net/cat/csw/apiso/1.0" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xlink="http://www.w3.org/1999/xlink" xml [...]
+<csw:HarvestResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/cat/csw/2.0.2 http://schemas.opengis.net/csw/2.0.2/CSW-publication.xsd">
   <csw:TransactionResponse version="2.0.2">
     <csw:TransactionSummary>
       <csw:totalInserted>6</csw:totalInserted>
diff --git a/tests/expected/suites_harvesting_post_Harvest-wms-run1.xml b/tests/expected/suites_harvesting_post_Harvest-wms-run1.xml
index 51c2b0e..d75519d 100644
--- a/tests/expected/suites_harvesting_post_Harvest-wms-run1.xml
+++ b/tests/expected/suites_harvesting_post_Harvest-wms-run1.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<csw:HarvestResponse xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:inspire_common="http://inspire.ec.europa.eu/schemas/common/1.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dct="http://purl.org/dc/terms/" xmlns:ows="http://www.opengis.net/ows" xmlns:apiso="http://www.opengis.net/cat/csw/apiso/1.0" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xlink="http://www.w3.org/1999/xlink" xml [...]
+<csw:HarvestResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/cat/csw/2.0.2 http://schemas.opengis.net/csw/2.0.2/CSW-publication.xsd">
   <csw:TransactionResponse version="2.0.2">
     <csw:TransactionSummary>
       <csw:totalInserted>4</csw:totalInserted>
@@ -13,6 +13,10 @@
         <dc:title>IEM WMS Service</dc:title>
       </csw:BriefRecord>
       <csw:BriefRecord>
+        <dc:identifier>PYCSW_IDENTIFIER-nexrad_base_reflect</dc:identifier>
+        <dc:title>IEM WMS Service</dc:title>
+      </csw:BriefRecord>
+      <csw:BriefRecord>
         <dc:identifier>PYCSW_IDENTIFIER-time_idx</dc:identifier>
         <dc:title>NEXRAD BASE REFLECT</dc:title>
       </csw:BriefRecord>
@@ -20,10 +24,6 @@
         <dc:identifier>PYCSW_IDENTIFIER-nexrad-n0r-wmst</dc:identifier>
         <dc:title>NEXRAD BASE REFLECT</dc:title>
       </csw:BriefRecord>
-      <csw:BriefRecord>
-        <dc:identifier>PYCSW_IDENTIFIER-nexrad_base_reflect</dc:identifier>
-        <dc:title>IEM WMS Service</dc:title>
-      </csw:BriefRecord>
     </csw:InsertResult>
   </csw:TransactionResponse>
 </csw:HarvestResponse>
diff --git a/tests/expected/suites_harvesting_post_Harvest-wms-run2.xml b/tests/expected/suites_harvesting_post_Harvest-wms-run2.xml
index d012260..38614f9 100644
--- a/tests/expected/suites_harvesting_post_Harvest-wms-run2.xml
+++ b/tests/expected/suites_harvesting_post_Harvest-wms-run2.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<csw:HarvestResponse xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:inspire_common="http://inspire.ec.europa.eu/schemas/common/1.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dct="http://purl.org/dc/terms/" xmlns:ows="http://www.opengis.net/ows" xmlns:apiso="http://www.opengis.net/cat/csw/apiso/1.0" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xlink="http://www.w3.org/1999/xlink" xml [...]
+<csw:HarvestResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/cat/csw/2.0.2 http://schemas.opengis.net/csw/2.0.2/CSW-publication.xsd">
   <csw:TransactionResponse version="2.0.2">
     <csw:TransactionSummary>
       <csw:totalInserted>0</csw:totalInserted>
diff --git a/tests/expected/suites_harvesting_post_Harvest-wmts.xml b/tests/expected/suites_harvesting_post_Harvest-wmts.xml
new file mode 100644
index 0000000..4742d0d
--- /dev/null
+++ b/tests/expected/suites_harvesting_post_Harvest-wmts.xml
@@ -0,0 +1,713 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- PYCSW_VERSION -->
+<csw:HarvestResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/cat/csw/2.0.2 http://schemas.opengis.net/csw/2.0.2/CSW-publication.xsd">
+  <csw:TransactionResponse version="2.0.2">
+    <csw:TransactionSummary>
+      <csw:totalInserted>175</csw:totalInserted>
+      <csw:totalUpdated>0</csw:totalUpdated>
+      <csw:totalDeleted>0</csw:totalDeleted>
+    </csw:TransactionSummary>
+    <csw:InsertResult>
+      <csw:BriefRecord>
+        <dc:identifier>PYCSW_IDENTIFIER</dc:identifier>
+        <dc:title>NASA Global Imagery Browse Services for EOSDIS</dc:title>
+      </csw:BriefRecord>
+      <csw:BriefRecord>
+        <dc:identifier>PYCSW_IDENTIFIER-MODIS_Aqua_Cloud_Top_Temp_Night</dc:identifier>
+        <dc:title>MODIS_Aqua_Cloud_Top_Temp_Night</dc:title>
+      </csw:BriefRecord>
+      <csw:BriefRecord>
+        <dc:identifier>PYCSW_IDENTIFIER-MODIS_Aqua_SurfaceReflectance_Bands721</dc:identifier>
+        <dc:title>MODIS_Aqua_SurfaceReflectance_Bands721</dc:title>
+      </csw:BriefRecord>
+      <csw:BriefRecord>
+        <dc:identifier>PYCSW_IDENTIFIER-VIIRS_SNPP_CorrectedReflectance_BandsM3-I3-M11</dc:identifier>
+        <dc:title>VIIRS_SNPP_CorrectedReflectance_BandsM3-I3-M11</dc:title>
+      </csw:BriefRecord>
+      <csw:BriefRecord>
+        <dc:identifier>PYCSW_IDENTIFIER-SMAP_L4_Uncertainty_Analyzed_Root_Zone_Soil_Moisture</dc:identifier>
+        <dc:title>SMAP_L4_Uncertainty_Analyzed_Root_Zone_Soil_Moisture</dc:title>
+      </csw:BriefRecord>
+      <csw:BriefRecord>
+        <dc:identifier>PYCSW_IDENTIFIER-MODIS_Combined_Value_Added_AOD</dc:identifier>
+        <dc:title>MODIS_Combined_Value_Added_AOD</dc:title>
+      </csw:BriefRecord>
+      <csw:BriefRecord>
+        <dc:identifier>PYCSW_IDENTIFIER-SMAP_L3_Active_Sigma0_VV</dc:identifier>
+        <dc:title>SMAP_L3_Active_Sigma0_VV</dc:title>
+      </csw:BriefRecord>
+      <csw:BriefRecord>
+        <dc:identifier>PYCSW_IDENTIFIER-AMSRE_Brightness_Temp_89H_Day</dc:identifier>
+        <dc:title>AMSRE_Brightness_Temp_89H_Day</dc:title>
+      </csw:BriefRecord>
+      <csw:BriefRecord>
+        <dc:identifier>PYCSW_IDENTIFIER-SMAP_L1_Passive_Faraday_Rotation_Aft</dc:identifier>
+        <dc:title>SMAP_L1_Passive_Faraday_Rotation_Aft</dc:title>
+      </csw:BriefRecord>
+      <csw:BriefRecord>
+        <dc:identifier>PYCSW_IDENTIFIER-SMAP_L3_Active_Sigma0_HH_RFI</dc:identifier>
+        <dc:title>SMAP_L3_Active_Sigma0_HH_RFI</dc:title>
+      </csw:BriefRecord>
+      <csw:BriefRecord>
+        <dc:identifier>PYCSW_IDENTIFIER-AMSR2_Cloud_Liquid_Water_Night</dc:identifier>
+        <dc:title>AMSR2_Cloud_Liquid_Water_Night</dc:title>
+      </csw:BriefRecord>
+      <csw:BriefRecord>
+        <dc:identifier>PYCSW_IDENTIFIER-MLS_HNO3_46hPa_Night</dc:identifier>
+        <dc:title>MLS_HNO3_46hPa_Night</dc:title>
+      </csw:BriefRecord>
+      <csw:BriefRecord>
+        <dc:identifier>PYCSW_IDENTIFIER-SMAP_L1_Passive_Brightness_Temp_Fore_V</dc:identifier>
+        <dc:title>SMAP_L1_Passive_Brightness_Temp_Fore_V</dc:title>
+      </csw:BriefRecord>
+      <csw:BriefRecord>
+        <dc:identifier>PYCSW_IDENTIFIER-SMAP_L1_Passive_Brightness_Temp_Fore_H</dc:identifier>
+        <dc:title>SMAP_L1_Passive_Brightness_Temp_Fore_H</dc:title>
+      </csw:BriefRecord>
+      <csw:BriefRecord>
+        <dc:identifier>PYCSW_IDENTIFIER-SMAP_L1_Passive_Brightness_Temp_Fore_H_QA</dc:identifier>
+        <dc:title>SMAP_L1_Passive_Brightness_Temp_Fore_H_QA</dc:title>
+      </csw:BriefRecord>
+      <csw:BriefRecord>
+        <dc:identifier>PYCSW_IDENTIFIER-SMAP_L1_Passive_Faraday_Rotation_Fore</dc:identifier>
+        <dc:title>SMAP_L1_Passive_Faraday_Rotation_Fore</dc:title>
+      </csw:BriefRecord>
+      <csw:BriefRecord>
+        <dc:identifier>PYCSW_IDENTIFIER-GMI_Brightness_Temp_Asc</dc:identifier>
+        <dc:title>GMI_Brightness_Temp_Asc</dc:title>
+      </csw:BriefRecord>
+      <csw:BriefRecord>
+        <dc:identifier>PYCSW_IDENTIFIER-GMI_Rain_Rate_Dsc</dc:identifier>
+        <dc:title>GMI_Rain_Rate_Dsc</dc:title>
+      </csw:BriefRecord>
+      <csw:BriefRecord>
+        <dc:identifier>PYCSW_IDENTIFIER-SMAP_L3_Active_Sigma0_XPOL_RFI</dc:identifier>
+        <dc:title>SMAP_L3_Active_Sigma0_XPOL_RFI</dc:title>
+      </csw:BriefRecord>
+      <csw:BriefRecord>
+        <dc:identifier>PYCSW_IDENTIFIER-MODIS_Terra_Brightness_Temp_Band31_Day</dc:identifier>
+        <dc:title>MODIS_Terra_Brightness_Temp_Band31_Day</dc:title>
+      </csw:BriefRecord>
+      <csw:BriefRecord>
+        <dc:identifier>PYCSW_IDENTIFIER-SMAP_L4_Mean_Gross_Primary_Productivity</dc:identifier>
+        <dc:title>SMAP_L4_Mean_Gross_Primary_Productivity</dc:title>
+      </csw:BriefRecord>
+      <csw:BriefRecord>
+        <dc:identifier>PYCSW_IDENTIFIER-MODIS_Terra_Cloud_Top_Pressure_Day</dc:identifier>
+        <dc:title>MODIS_Terra_Cloud_Top_Pressure_Day</dc:title>
+      </csw:BriefRecord>
+      <csw:BriefRecord>
+        <dc:identifier>PYCSW_IDENTIFIER-AMSR2_Snow_Water_Equivalent</dc:identifier>
+        <dc:title>AMSR2_Snow_Water_Equivalent</dc:title>
+      </csw:BriefRecord>
+      <csw:BriefRecord>
+        <dc:identifier>PYCSW_IDENTIFIER-MODIS_Terra_Land_Surface_Temp_Day</dc:identifier>
+        <dc:title>MODIS_Terra_Land_Surface_Temp_Day</dc:title>
+      </csw:BriefRecord>
+      <csw:BriefRecord>
+        <dc:identifier>PYCSW_IDENTIFIER-Coastlines</dc:identifier>
+        <dc:title>Coastlines</dc:title>
+      </csw:BriefRecord>
+      <csw:BriefRecord>
+        <dc:identifier>PYCSW_IDENTIFIER-MLS_HNO3_46hPa_Day</dc:identifier>
+        <dc:title>MLS_HNO3_46hPa_Day</dc:title>
+      </csw:BriefRecord>
+      <csw:BriefRecord>
+        <dc:identifier>PYCSW_IDENTIFIER-SMAP_L2_Passive_Soil_Moisture_Option1</dc:identifier>
+        <dc:title>SMAP_L2_Passive_Soil_Moisture_Option1</dc:title>
+      </csw:BriefRecord>
+      <csw:BriefRecord>
+        <dc:identifier>PYCSW_IDENTIFIER-OMI_SO2_Middle_Troposphere</dc:identifier>
+        <dc:title>OMI_SO2_Middle_Troposphere</dc:title>
+      </csw:BriefRecord>
+      <csw:BriefRecord>
+        <dc:identifier>PYCSW_IDENTIFIER-SMAP_L2_Passive_Soil_Moisture_Option3</dc:identifier>
+        <dc:title>SMAP_L2_Passive_Soil_Moisture_Option3</dc:title>
+      </csw:BriefRecord>
+      <csw:BriefRecord>
+        <dc:identifier>PYCSW_IDENTIFIER-MEaSUREs_Daily_Landscape_Freeze_Thaw_AMSRE</dc:identifier>
+        <dc:title>MEaSUREs_Daily_Landscape_Freeze_Thaw_AMSRE</dc:title>
+      </csw:BriefRecord>
+      <csw:BriefRecord>
+        <dc:identifier>PYCSW_IDENTIFIER-MODIS_Aqua_Cloud_Top_Temp_Day</dc:identifier>
+        <dc:title>MODIS_Aqua_Cloud_Top_Temp_Day</dc:title>
+      </csw:BriefRecord>
+      <csw:BriefRecord>
+        <dc:identifier>PYCSW_IDENTIFIER-GHRSST_L4_MUR_Sea_Surface_Temperature</dc:identifier>
+        <dc:title>GHRSST_L4_MUR_Sea_Surface_Temperature</dc:title>
+      </csw:BriefRecord>
+      <csw:BriefRecord>
+        <dc:identifier>PYCSW_IDENTIFIER-MODIS_Terra_Land_Surface_Temp_Night</dc:identifier>
+        <dc:title>MODIS_Terra_Land_Surface_Temp_Night</dc:title>
+      </csw:BriefRecord>
+      <csw:BriefRecord>
+        <dc:identifier>PYCSW_IDENTIFIER-AMSRE_Surface_Precipitation_Rate_Day</dc:identifier>
+        <dc:title>AMSRE_Surface_Precipitation_Rate_Day</dc:title>
+      </csw:BriefRecord>
+      <csw:BriefRecord>
+        <dc:identifier>PYCSW_IDENTIFIER-VIIRS_CityLights_2012</dc:identifier>
+        <dc:title>VIIRS_EarthAtNight_2012</dc:title>
+      </csw:BriefRecord>
+      <csw:BriefRecord>
+        <dc:identifier>PYCSW_IDENTIFIER-AMSRE_Surface_Rain_Rate_Day</dc:identifier>
+        <dc:title>AMSRE_Surface_Rain_Rate_Day</dc:title>
+      </csw:BriefRecord>
+      <csw:BriefRecord>
+        <dc:identifier>PYCSW_IDENTIFIER-SMAP_L3_Active_Sigma0_VV_RFI</dc:identifier>
+        <dc:title>SMAP_L3_Active_Sigma0_VV_RFI</dc:title>
+      </csw:BriefRecord>
+      <csw:BriefRecord>
+        <dc:identifier>PYCSW_IDENTIFIER-MODIS_Aqua_SurfaceReflectance_Bands143</dc:identifier>
+        <dc:title>MODIS_Aqua_SurfaceReflectance_Bands143</dc:title>
+      </csw:BriefRecord>
+      <csw:BriefRecord>
+        <dc:identifier>PYCSW_IDENTIFIER-SMAP_L4_Uncertainty_Analyzed_Surface_Soil_Moisture</dc:identifier>
+        <dc:title>SMAP_L4_Uncertainty_Analyzed_Surface_Soil_Moisture</dc:title>
+      </csw:BriefRecord>
+      <csw:BriefRecord>
+        <dc:identifier>PYCSW_IDENTIFIER-Reference_Labels</dc:identifier>
+        <dc:title>Reference_Labels</dc:title>
+      </csw:BriefRecord>
+      <csw:BriefRecord>
+        <dc:identifier>PYCSW_IDENTIFIER-MLS_O3_46hPa_Day</dc:identifier>
+        <dc:title>MLS_O3_46hPa_Day</dc:title>
+      </csw:BriefRecord>
+      <csw:BriefRecord>
+        <dc:identifier>PYCSW_IDENTIFIER-MLS_Temperature_46hPa_Day</dc:identifier>
+        <dc:title>MLS_Temperature_46hPa_Day</dc:title>
+      </csw:BriefRecord>
+      <csw:BriefRecord>
+        <dc:identifier>PYCSW_IDENTIFIER-SMAP_L1_Passive_Brightness_Temp_Aft_V</dc:identifier>
+        <dc:title>SMAP_L1_Passive_Brightness_Temp_Aft_V</dc:title>
+      </csw:BriefRecord>
+      <csw:BriefRecord>
+        <dc:identifier>PYCSW_IDENTIFIER-SMAP_L3_Active_Sigma0_XPOL</dc:identifier>
+        <dc:title>SMAP_L3_Active_Sigma0_XPOL</dc:title>
+      </csw:BriefRecord>
+      <csw:BriefRecord>
+        <dc:identifier>PYCSW_IDENTIFIER-MODIS_Terra_CorrectedReflectance_Bands721</dc:identifier>
+        <dc:title>MODIS_Terra_CorrectedReflectance_Bands721</dc:title>
+      </csw:BriefRecord>
+      <csw:BriefRecord>
+        <dc:identifier>PYCSW_IDENTIFIER-GMI_Brightness_Temp_Dsc</dc:identifier>
+        <dc:title>GMI_Brightness_Temp_Dsc</dc:title>
+      </csw:BriefRecord>
+      <csw:BriefRecord>
+        <dc:identifier>PYCSW_IDENTIFIER-AMSRE_Brightness_Temp_89V_Day</dc:identifier>
+        <dc:title>AMSRE_Brightness_Temp_89V_Day</dc:title>
+      </csw:BriefRecord>
+      <csw:BriefRecord>
+        <dc:identifier>PYCSW_IDENTIFIER-MODIS_Aqua_Cloud_Top_Pressure_Night</dc:identifier>
+        <dc:title>MODIS_Aqua_Cloud_Top_Pressure_Night</dc:title>
+      </csw:BriefRecord>
+      <csw:BriefRecord>
+        <dc:identifier>PYCSW_IDENTIFIER-MODIS_Terra_Chlorophyll_A</dc:identifier>
+        <dc:title>MODIS_Terra_Chlorophyll_A</dc:title>
+      </csw:BriefRecord>
+      <csw:BriefRecord>
+        <dc:identifier>PYCSW_IDENTIFIER-MODIS_Aqua_Brightness_Temp_Band31_Day</dc:identifier>
+        <dc:title>MODIS_Aqua_Brightness_Temp_Band31_Day</dc:title>
+      </csw:BriefRecord>
+      <csw:BriefRecord>
+        <dc:identifier>PYCSW_IDENTIFIER-SMAP_L1_Passive_Brightness_Temp_Aft_H</dc:identifier>
+        <dc:title>SMAP_L1_Passive_Brightness_Temp_Aft_H</dc:title>
+      </csw:BriefRecord>
+      <csw:BriefRecord>
+        <dc:identifier>PYCSW_IDENTIFIER-SMAP_L1_Passive_Brightness_Temp_Aft_V_RFI</dc:identifier>
+        <dc:title>SMAP_L1_Passive_Brightness_Temp_Aft_V_RFI</dc:title>
+      </csw:BriefRecord>
+      <csw:BriefRecord>
+        <dc:identifier>PYCSW_IDENTIFIER-MODIS_Aqua_Land_Surface_Temp_Day</dc:identifier>
+        <dc:title>MODIS_Aqua_Land_Surface_Temp_Day</dc:title>
+      </csw:BriefRecord>
+      <csw:BriefRecord>
+        <dc:identifier>PYCSW_IDENTIFIER-SMAP_L3_Passive_Brightness_Temp_H</dc:identifier>
+        <dc:title>SMAP_L3_Passive_Brightness_Temp_H</dc:title>
+      </csw:BriefRecord>
+      <csw:BriefRecord>
+        <dc:identifier>PYCSW_IDENTIFIER-MODIS_Aqua_Chlorophyll_A</dc:identifier>
+        <dc:title>MODIS_Aqua_Chlorophyll_A</dc:title>
+      </csw:BriefRecord>
+      <csw:BriefRecord>
+        <dc:identifier>PYCSW_IDENTIFIER-BlueMarble_ShadedRelief</dc:identifier>
+        <dc:title>BlueMarble_ShadedRelief</dc:title>
+      </csw:BriefRecord>
+      <csw:BriefRecord>
+        <dc:identifier>PYCSW_IDENTIFIER-AMSRE_Sea_Ice_Concentration_25km</dc:identifier>
+        <dc:title>AMSRE_Sea_Ice_Concentration_25km</dc:title>
+      </csw:BriefRecord>
+      <csw:BriefRecord>
+        <dc:identifier>PYCSW_IDENTIFIER-MODIS_Terra_Sea_Ice</dc:identifier>
+        <dc:title>MODIS_Terra_Sea_Ice</dc:title>
+      </csw:BriefRecord>
+      <csw:BriefRecord>
+        <dc:identifier>PYCSW_IDENTIFIER-AMSRE_Brightness_Temp_89V_Night</dc:identifier>
+        <dc:title>AMSRE_Brightness_Temp_89V_Night</dc:title>
+      </csw:BriefRecord>
+      <csw:BriefRecord>
+        <dc:identifier>PYCSW_IDENTIFIER-OMI_Aerosol_Index</dc:identifier>
+        <dc:title>OMI_Aerosol_Index</dc:title>
+      </csw:BriefRecord>
+      <csw:BriefRecord>
+        <dc:identifier>PYCSW_IDENTIFIER-SMAP_L4_Analyzed_Surface_Soil_Moisture</dc:identifier>
+        <dc:title>SMAP_L4_Analyzed_Surface_Soil_Moisture</dc:title>
+      </csw:BriefRecord>
+      <csw:BriefRecord>
+        <dc:identifier>PYCSW_IDENTIFIER-AMSR2_Columnar_Water_Vapor_Day</dc:identifier>
+        <dc:title>AMSR2_Columnar_Water_Vapor_Day</dc:title>
+      </csw:BriefRecord>
+      <csw:BriefRecord>
+        <dc:identifier>PYCSW_IDENTIFIER-MODIS_Aqua_Aerosol</dc:identifier>
+        <dc:title>MODIS_Aqua_Aerosol</dc:title>
+      </csw:BriefRecord>
+      <csw:BriefRecord>
+        <dc:identifier>PYCSW_IDENTIFIER-AIRS_CO_Total_Column_Night</dc:identifier>
+        <dc:title>AIRS_CO_Total_Column_Night</dc:title>
+      </csw:BriefRecord>
+      <csw:BriefRecord>
+        <dc:identifier>PYCSW_IDENTIFIER-SMAP_L3_Passive_Brightness_Temp_V</dc:identifier>
+        <dc:title>SMAP_L3_Passive_Brightness_Temp_V</dc:title>
+      </csw:BriefRecord>
+      <csw:BriefRecord>
+        <dc:identifier>PYCSW_IDENTIFIER-AIRS_Precipitation_Day</dc:identifier>
+        <dc:title>AIRS_Precipitation_Day</dc:title>
+      </csw:BriefRecord>
+      <csw:BriefRecord>
+        <dc:identifier>PYCSW_IDENTIFIER-SMAP_L2_Passive_Soil_Moisture_Option2</dc:identifier>
+        <dc:title>SMAP_L2_Passive_Soil_Moisture_Option2</dc:title>
+      </csw:BriefRecord>
+      <csw:BriefRecord>
+        <dc:identifier>PYCSW_IDENTIFIER-Sea_Surface_Temp_Microwave</dc:identifier>
+        <dc:title>Sea_Surface_Temp_Microwave</dc:title>
+      </csw:BriefRecord>
+      <csw:BriefRecord>
+        <dc:identifier>PYCSW_IDENTIFIER-SMAP_L3_Active_Sigma0_XPOL_QA</dc:identifier>
+        <dc:title>SMAP_L3_Active_Sigma0_XPOL_QA</dc:title>
+      </csw:BriefRecord>
+      <csw:BriefRecord>
+        <dc:identifier>PYCSW_IDENTIFIER-AMSRE_Surface_Precipitation_Rate_Night</dc:identifier>
+        <dc:title>AMSRE_Surface_Precipitation_Rate_Night</dc:title>
+      </csw:BriefRecord>
+      <csw:BriefRecord>
+        <dc:identifier>PYCSW_IDENTIFIER-AIRS_CO_Total_Column_Day</dc:identifier>
+        <dc:title>AIRS_CO_Total_Column_Day</dc:title>
+      </csw:BriefRecord>
+      <csw:BriefRecord>
+        <dc:identifier>PYCSW_IDENTIFIER-GMI_Snow_Rate_Dsc</dc:identifier>
+        <dc:title>GMI_Snow_Rate_Dsc</dc:title>
+      </csw:BriefRecord>
+      <csw:BriefRecord>
+        <dc:identifier>PYCSW_IDENTIFIER-SMAP_L3_Active_Passive_Soil_Moisture</dc:identifier>
+        <dc:title>SMAP_L3_Active_Passive_Soil_Moisture</dc:title>
+      </csw:BriefRecord>
+      <csw:BriefRecord>
+        <dc:identifier>PYCSW_IDENTIFIER-Sea_Surface_Temp_Blended</dc:identifier>
+        <dc:title>Sea_Surface_Temp_Blended</dc:title>
+      </csw:BriefRecord>
+      <csw:BriefRecord>
+        <dc:identifier>PYCSW_IDENTIFIER-OSM_Land_Water_Map</dc:identifier>
+        <dc:title>OSM_Land_Water_Map</dc:title>
+      </csw:BriefRecord>
+      <csw:BriefRecord>
+        <dc:identifier>PYCSW_IDENTIFIER-OSM_Land_Mask</dc:identifier>
+        <dc:title>OSM_Land_Mask</dc:title>
+      </csw:BriefRecord>
+      <csw:BriefRecord>
+        <dc:identifier>PYCSW_IDENTIFIER-ASTER_GDEM_Color_Index</dc:identifier>
+        <dc:title>ASTER_GDEM_Color_Index</dc:title>
+      </csw:BriefRecord>
+      <csw:BriefRecord>
+        <dc:identifier>PYCSW_IDENTIFIER-AIRS_Prata_SO2_Index_Night</dc:identifier>
+        <dc:title>AIRS_Prata_SO2_Index_Night</dc:title>
+      </csw:BriefRecord>
+      <csw:BriefRecord>
+        <dc:identifier>PYCSW_IDENTIFIER-AMSRE_Sea_Ice_Concentration_12km</dc:identifier>
+        <dc:title>AMSRE_Sea_Ice_Concentration_12km</dc:title>
+      </csw:BriefRecord>
+      <csw:BriefRecord>
+        <dc:identifier>PYCSW_IDENTIFIER-GMI_Rain_Rate_Asc</dc:identifier>
+        <dc:title>GMI_Rain_Rate_Asc</dc:title>
+      </csw:BriefRecord>
+      <csw:BriefRecord>
+        <dc:identifier>PYCSW_IDENTIFIER-MODIS_Aqua_CorrectedReflectance_Bands721</dc:identifier>
+        <dc:title>MODIS_Aqua_CorrectedReflectance_Bands721</dc:title>
+      </csw:BriefRecord>
+      <csw:BriefRecord>
+        <dc:identifier>PYCSW_IDENTIFIER-SMAP_L4_Mean_Net_Ecosystem_Exchange</dc:identifier>
+        <dc:title>SMAP_L4_Mean_Net_Ecosystem_Exchange</dc:title>
+      </csw:BriefRecord>
+      <csw:BriefRecord>
+        <dc:identifier>PYCSW_IDENTIFIER-MODIS_Terra_SurfaceReflectance_Bands721</dc:identifier>
+        <dc:title>MODIS_Terra_SurfaceReflectance_Bands721</dc:title>
+      </csw:BriefRecord>
+      <csw:BriefRecord>
+        <dc:identifier>PYCSW_IDENTIFIER-SMAP_L4_Frozen_Area</dc:identifier>
+        <dc:title>SMAP_L4_Frozen_Area</dc:title>
+      </csw:BriefRecord>
+      <csw:BriefRecord>
+        <dc:identifier>PYCSW_IDENTIFIER-Sea_Surface_Temp_Infrared</dc:identifier>
+        <dc:title>Sea_Surface_Temp_Infrared</dc:title>
+      </csw:BriefRecord>
+      <csw:BriefRecord>
+        <dc:identifier>PYCSW_IDENTIFIER-SMAP_L3_Active_Passive_Brightness_Temp_V</dc:identifier>
+        <dc:title>SMAP_L3_Active_Passive_Brightness_Temp_V</dc:title>
+      </csw:BriefRecord>
+      <csw:BriefRecord>
+        <dc:identifier>PYCSW_IDENTIFIER-MODIS_Aqua_Snow_Cover</dc:identifier>
+        <dc:title>MODIS_Aqua_Snow_Cover</dc:title>
+      </csw:BriefRecord>
+      <csw:BriefRecord>
+        <dc:identifier>PYCSW_IDENTIFIER-SMAP_L4_Snow_Mass</dc:identifier>
+        <dc:title>SMAP_L4_Snow_Mass</dc:title>
+      </csw:BriefRecord>
+      <csw:BriefRecord>
+        <dc:identifier>PYCSW_IDENTIFIER-VIIRS_SNPP_CorrectedReflectance_TrueColor</dc:identifier>
+        <dc:title>VIIRS_SNPP_CorrectedReflectance_TrueColor</dc:title>
+      </csw:BriefRecord>
+      <csw:BriefRecord>
+        <dc:identifier>PYCSW_IDENTIFIER-SMAP_L3_Active_Sigma0_HH_QA</dc:identifier>
+        <dc:title>SMAP_L3_Active_Sigma0_HH_QA</dc:title>
+      </csw:BriefRecord>
+      <csw:BriefRecord>
+        <dc:identifier>PYCSW_IDENTIFIER-MODIS_Terra_CorrectedReflectance_TrueColor</dc:identifier>
+        <dc:title>MODIS_Terra_CorrectedReflectance_TrueColor</dc:title>
+      </csw:BriefRecord>
+      <csw:BriefRecord>
+        <dc:identifier>PYCSW_IDENTIFIER-SMAP_L3_Active_Sigma0_HH</dc:identifier>
+        <dc:title>SMAP_L3_Active_Sigma0_HH</dc:title>
+      </csw:BriefRecord>
+      <csw:BriefRecord>
+        <dc:identifier>PYCSW_IDENTIFIER-SMAP_L3_Active_Passive_Brightness_Temp_H</dc:identifier>
+        <dc:title>SMAP_L3_Active_Passive_Brightness_Temp_H</dc:title>
+      </csw:BriefRecord>
+      <csw:BriefRecord>
+        <dc:identifier>PYCSW_IDENTIFIER-SMAP_L1_Passive_Brightness_Temp_Fore_V_RFI</dc:identifier>
+        <dc:title>SMAP_L1_Passive_Brightness_Temp_Fore_V_RFI</dc:title>
+      </csw:BriefRecord>
+      <csw:BriefRecord>
+        <dc:identifier>PYCSW_IDENTIFIER-AMSRE_Brightness_Temp_89H_Night</dc:identifier>
+        <dc:title>AMSRE_Brightness_Temp_89H_Night</dc:title>
+      </csw:BriefRecord>
+      <csw:BriefRecord>
+        <dc:identifier>PYCSW_IDENTIFIER-SMAP_L1_Passive_Brightness_Temp_Fore_V_QA</dc:identifier>
+        <dc:title>SMAP_L1_Passive_Brightness_Temp_Fore_V_QA</dc:title>
+      </csw:BriefRecord>
+      <csw:BriefRecord>
+        <dc:identifier>PYCSW_IDENTIFIER-AMSR2_Wind_Speed_Day</dc:identifier>
+        <dc:title>AMSR2_Wind_Speed_Day</dc:title>
+      </csw:BriefRecord>
+      <csw:BriefRecord>
+        <dc:identifier>PYCSW_IDENTIFIER-OMI_Cloud_Pressure</dc:identifier>
+        <dc:title>OMI_Cloud_Pressure</dc:title>
+      </csw:BriefRecord>
+      <csw:BriefRecord>
+        <dc:identifier>PYCSW_IDENTIFIER-MLS_H2O_46hPa_Day</dc:identifier>
+        <dc:title>MLS_H2O_46hPa_Day</dc:title>
+      </csw:BriefRecord>
+      <csw:BriefRecord>
+        <dc:identifier>PYCSW_IDENTIFIER-MODIS_Terra_Water_Vapor_5km_Day</dc:identifier>
+        <dc:title>MODIS_Terra_Water_Vapor_5km_Day</dc:title>
+      </csw:BriefRecord>
+      <csw:BriefRecord>
+        <dc:identifier>PYCSW_IDENTIFIER-SMAP_L1_Passive_Brightness_Temp_Aft_V_QA</dc:identifier>
+        <dc:title>SMAP_L1_Passive_Brightness_Temp_Aft_V_QA</dc:title>
+      </csw:BriefRecord>
+      <csw:BriefRecord>
+        <dc:identifier>PYCSW_IDENTIFIER-BlueMarble_NextGeneration</dc:identifier>
+        <dc:title>BlueMarble_NextGeneration</dc:title>
+      </csw:BriefRecord>
+      <csw:BriefRecord>
+        <dc:identifier>PYCSW_IDENTIFIER-MODIS_Terra_SurfaceReflectance_Bands121</dc:identifier>
+        <dc:title>MODIS_Terra_SurfaceReflectance_Bands121</dc:title>
+      </csw:BriefRecord>
+      <csw:BriefRecord>
+        <dc:identifier>PYCSW_IDENTIFIER-MLS_CO_215hPa_Day</dc:identifier>
+        <dc:title>MLS_CO_215hPa_Day</dc:title>
+      </csw:BriefRecord>
+      <csw:BriefRecord>
+        <dc:identifier>PYCSW_IDENTIFIER-MLS_CO_215hPa_Night</dc:identifier>
+        <dc:title>MLS_CO_215hPa_Night</dc:title>
+      </csw:BriefRecord>
+      <csw:BriefRecord>
+        <dc:identifier>PYCSW_IDENTIFIER-AIRS_Dust_Score</dc:identifier>
+        <dc:title>AIRS_Dust_Score</dc:title>
+      </csw:BriefRecord>
+      <csw:BriefRecord>
+        <dc:identifier>PYCSW_IDENTIFIER-OMI_Absorbing_Aerosol_Optical_Depth</dc:identifier>
+        <dc:title>OMI_Absorbing_Aerosol_Optical_Depth</dc:title>
+      </csw:BriefRecord>
+      <csw:BriefRecord>
+        <dc:identifier>PYCSW_IDENTIFIER-SMAP_L4_Emult_Average</dc:identifier>
+        <dc:title>SMAP_L4_Emult_Average</dc:title>
+      </csw:BriefRecord>
+      <csw:BriefRecord>
+        <dc:identifier>PYCSW_IDENTIFIER-AMSR2_Sea_Ice_Brightness_Temp_6km_89H</dc:identifier>
+        <dc:title>AMSR2_Sea_Ice_Brightness_Temp_6km_89H</dc:title>
+      </csw:BriefRecord>
+      <csw:BriefRecord>
+        <dc:identifier>PYCSW_IDENTIFIER-SMAP_L1_Passive_Brightness_Temp_Aft_H_RFI</dc:identifier>
+        <dc:title>SMAP_L1_Passive_Brightness_Temp_Aft_H_RFI</dc:title>
+      </csw:BriefRecord>
+      <csw:BriefRecord>
+        <dc:identifier>PYCSW_IDENTIFIER-AMSR2_Surface_Rain_Rate_Day</dc:identifier>
+        <dc:title>AMSR2_Surface_Rain_Rate_Day</dc:title>
+      </csw:BriefRecord>
+      <csw:BriefRecord>
+        <dc:identifier>PYCSW_IDENTIFIER-AMSRE_Sea_Ice_Brightness_Temp_89V</dc:identifier>
+        <dc:title>AMSRE_Sea_Ice_Brightness_Temp_89V</dc:title>
+      </csw:BriefRecord>
+      <csw:BriefRecord>
+        <dc:identifier>PYCSW_IDENTIFIER-MODIS_Terra_Aerosol</dc:identifier>
+        <dc:title>MODIS_Terra_Aerosol</dc:title>
+      </csw:BriefRecord>
+      <csw:BriefRecord>
+        <dc:identifier>PYCSW_IDENTIFIER-AMSR2_Surface_Precipitation_Rate_Night</dc:identifier>
+        <dc:title>AMSR2_Surface_Precipitation_Rate_Night</dc:title>
+      </csw:BriefRecord>
+      <csw:BriefRecord>
+        <dc:identifier>PYCSW_IDENTIFIER-AMSRE_Sea_Ice_Brightness_Temp_89H</dc:identifier>
+        <dc:title>AMSRE_Sea_Ice_Brightness_Temp_89H</dc:title>
+      </csw:BriefRecord>
+      <csw:BriefRecord>
+        <dc:identifier>PYCSW_IDENTIFIER-SMAP_L3_Active_Sigma0_VV_QA</dc:identifier>
+        <dc:title>SMAP_L3_Active_Sigma0_VV_QA</dc:title>
+      </csw:BriefRecord>
+      <csw:BriefRecord>
+        <dc:identifier>PYCSW_IDENTIFIER-MODIS_Terra_Cloud_Top_Temp_Day</dc:identifier>
+        <dc:title>MODIS_Terra_Cloud_Top_Temp_Day</dc:title>
+      </csw:BriefRecord>
+      <csw:BriefRecord>
+        <dc:identifier>PYCSW_IDENTIFIER-AMSR2_Sea_Ice_Brightness_Temp_6km_89V</dc:identifier>
+        <dc:title>AMSR2_Sea_Ice_Brightness_Temp_6km_89V</dc:title>
+      </csw:BriefRecord>
+      <csw:BriefRecord>
+        <dc:identifier>PYCSW_IDENTIFIER-MODIS_Water_Mask</dc:identifier>
+        <dc:title>MODIS_Water_Mask</dc:title>
+      </csw:BriefRecord>
+      <csw:BriefRecord>
+        <dc:identifier>PYCSW_IDENTIFIER-MLS_Temperature_46hPa_Night</dc:identifier>
+        <dc:title>MLS_Temperature_46hPa_Night</dc:title>
+      </csw:BriefRecord>
+      <csw:BriefRecord>
+        <dc:identifier>PYCSW_IDENTIFIER-VIIRS_SNPP_CorrectedReflectance_BandsM11-I2-I1</dc:identifier>
+        <dc:title>VIIRS_SNPP_CorrectedReflectance_BandsM11-I2-I1</dc:title>
+      </csw:BriefRecord>
+      <csw:BriefRecord>
+        <dc:identifier>PYCSW_IDENTIFIER-SMAP_L3_Passive_Soil_Moisture</dc:identifier>
+        <dc:title>SMAP_L3_Passive_Soil_Moisture</dc:title>
+      </csw:BriefRecord>
+      <csw:BriefRecord>
+        <dc:identifier>PYCSW_IDENTIFIER-AMSR2_Cloud_Liquid_Water_Day</dc:identifier>
+        <dc:title>AMSR2_Cloud_Liquid_Water_Day</dc:title>
+      </csw:BriefRecord>
+      <csw:BriefRecord>
+        <dc:identifier>PYCSW_IDENTIFIER-MODIS_Terra_Water_Vapor_5km_Night</dc:identifier>
+        <dc:title>MODIS_Terra_Water_Vapor_5km_Night</dc:title>
+      </csw:BriefRecord>
+      <csw:BriefRecord>
+        <dc:identifier>PYCSW_IDENTIFIER-OMI_SO2_Lower_Troposphere</dc:identifier>
+        <dc:title>OMI_SO2_Lower_Troposphere</dc:title>
+      </csw:BriefRecord>
+      <csw:BriefRecord>
+        <dc:identifier>PYCSW_IDENTIFIER-BlueMarble_ShadedRelief_Bathymetry</dc:identifier>
+        <dc:title>BlueMarble_ShadedRelief_Bathymetry</dc:title>
+      </csw:BriefRecord>
+      <csw:BriefRecord>
+        <dc:identifier>PYCSW_IDENTIFIER-GHRSST_L4_G1SST_Sea_Surface_Temperature</dc:identifier>
+        <dc:title>GHRSST_L4_G1SST_Sea_Surface_Temperature</dc:title>
+      </csw:BriefRecord>
+      <csw:BriefRecord>
+        <dc:identifier>PYCSW_IDENTIFIER-SMAP_L1_Passive_Brightness_Temp_Fore_H_RFI</dc:identifier>
+        <dc:title>SMAP_L1_Passive_Brightness_Temp_Fore_H_RFI</dc:title>
+      </csw:BriefRecord>
+      <csw:BriefRecord>
+        <dc:identifier>PYCSW_IDENTIFIER-MODIS_Terra_Snow_Cover</dc:identifier>
+        <dc:title>MODIS_Terra_Snow_Cover</dc:title>
+      </csw:BriefRecord>
+      <csw:BriefRecord>
+        <dc:identifier>PYCSW_IDENTIFIER-SMAP_L4_Analyzed_Root_Zone_Soil_Moisture</dc:identifier>
+        <dc:title>SMAP_L4_Analyzed_Root_Zone_Soil_Moisture</dc:title>
+      </csw:BriefRecord>
+      <csw:BriefRecord>
+        <dc:identifier>PYCSW_IDENTIFIER-SMAP_L4_Mean_Heterotrophic_Respiration</dc:identifier>
+        <dc:title>SMAP_L4_Mean_Heterotrophic_Respiration</dc:title>
+      </csw:BriefRecord>
+      <csw:BriefRecord>
+        <dc:identifier>PYCSW_IDENTIFIER-MLS_H2O_46hPa_Night</dc:identifier>
+        <dc:title>MLS_H2O_46hPa_Night</dc:title>
+      </csw:BriefRecord>
+      <csw:BriefRecord>
+        <dc:identifier>PYCSW_IDENTIFIER-MODIS_Terra_SurfaceReflectance_Bands143</dc:identifier>
+        <dc:title>MODIS_Terra_SurfaceReflectance_Bands143</dc:title>
+      </csw:BriefRecord>
+      <csw:BriefRecord>
+        <dc:identifier>PYCSW_IDENTIFIER-MODIS_Terra_Brightness_Temp_Band31_Night</dc:identifier>
+        <dc:title>MODIS_Terra_Brightness_Temp_Band31_Night</dc:title>
+      </csw:BriefRecord>
+      <csw:BriefRecord>
+        <dc:identifier>PYCSW_IDENTIFIER-AMSRE_Surface_Rain_Rate_Night</dc:identifier>
+        <dc:title>AMSRE_Surface_Rain_Rate_Night</dc:title>
+      </csw:BriefRecord>
+      <csw:BriefRecord>
+        <dc:identifier>PYCSW_IDENTIFIER-SMAP_L3_Active_Soil_Moisture</dc:identifier>
+        <dc:title>SMAP_L3_Active_Soil_Moisture</dc:title>
+      </csw:BriefRecord>
+      <csw:BriefRecord>
+        <dc:identifier>PYCSW_IDENTIFIER-Reference_Features</dc:identifier>
+        <dc:title>Reference_Features</dc:title>
+      </csw:BriefRecord>
+      <csw:BriefRecord>
+        <dc:identifier>PYCSW_IDENTIFIER-AMSR2_Sea_Ice_Concentration_25km</dc:identifier>
+        <dc:title>AMSR2_Sea_Ice_Concentration_25km</dc:title>
+      </csw:BriefRecord>
+      <csw:BriefRecord>
+        <dc:identifier>PYCSW_IDENTIFIER-AMSRE_Snow_Depth_Over_Ice</dc:identifier>
+        <dc:title>AMSRE_Snow_Depth_Over_Ice</dc:title>
+      </csw:BriefRecord>
+      <csw:BriefRecord>
+        <dc:identifier>PYCSW_IDENTIFIER-MODIS_Terra_Cloud_Top_Pressure_Night</dc:identifier>
+        <dc:title>MODIS_Terra_Cloud_Top_Pressure_Night</dc:title>
+      </csw:BriefRecord>
+      <csw:BriefRecord>
+        <dc:identifier>PYCSW_IDENTIFIER-AMSR2_Columnar_Water_Vapor_Night</dc:identifier>
+        <dc:title>AMSR2_Columnar_Water_Vapor_Night</dc:title>
+      </csw:BriefRecord>
+      <csw:BriefRecord>
+        <dc:identifier>PYCSW_IDENTIFIER-MLS_N2O_46hPa_Day</dc:identifier>
+        <dc:title>MLS_N2O_46hPa_Day</dc:title>
+      </csw:BriefRecord>
+      <csw:BriefRecord>
+        <dc:identifier>PYCSW_IDENTIFIER-MODIS_Aqua_CorrectedReflectance_TrueColor</dc:identifier>
+        <dc:title>MODIS_Aqua_CorrectedReflectance_TrueColor</dc:title>
+      </csw:BriefRecord>
+      <csw:BriefRecord>
+        <dc:identifier>PYCSW_IDENTIFIER-OMI_Aerosol_Optical_Depth</dc:identifier>
+        <dc:title>OMI_Aerosol_Optical_Depth</dc:title>
+      </csw:BriefRecord>
+      <csw:BriefRecord>
+        <dc:identifier>PYCSW_IDENTIFIER-MODIS_Aqua_Water_Vapor_5km_Day</dc:identifier>
+        <dc:title>MODIS_Aqua_Water_Vapor_5km_Day</dc:title>
+      </csw:BriefRecord>
+      <csw:BriefRecord>
+        <dc:identifier>PYCSW_IDENTIFIER-MODIS_Terra_CorrectedReflectance_Bands367</dc:identifier>
+        <dc:title>MODIS_Terra_CorrectedReflectance_Bands367</dc:title>
+      </csw:BriefRecord>
+      <csw:BriefRecord>
+        <dc:identifier>PYCSW_IDENTIFIER-GMI_Snow_Rate_Asc</dc:identifier>
+        <dc:title>GMI_Snow_Rate_Asc</dc:title>
+      </csw:BriefRecord>
+      <csw:BriefRecord>
+        <dc:identifier>PYCSW_IDENTIFIER-AIRS_Dust_Score_Ocean_Day</dc:identifier>
+        <dc:title>AIRS_Dust_Score_Ocean_Day</dc:title>
+      </csw:BriefRecord>
+      <csw:BriefRecord>
+        <dc:identifier>PYCSW_IDENTIFIER-MODIS_Aqua_Cloud_Top_Pressure_Day</dc:identifier>
+        <dc:title>MODIS_Aqua_Cloud_Top_Pressure_Day</dc:title>
+      </csw:BriefRecord>
+      <csw:BriefRecord>
+        <dc:identifier>PYCSW_IDENTIFIER-MODIS_Terra_Data_No_Data</dc:identifier>
+        <dc:title>MODIS_Terra_Data_No_Data</dc:title>
+      </csw:BriefRecord>
+      <csw:BriefRecord>
+        <dc:identifier>PYCSW_IDENTIFIER-AIRS_Precipitation_Night</dc:identifier>
+        <dc:title>AIRS_Precipitation_Night</dc:title>
+      </csw:BriefRecord>
+      <csw:BriefRecord>
+        <dc:identifier>PYCSW_IDENTIFIER-AMSR2_Sea_Ice_Concentration_12km</dc:identifier>
+        <dc:title>AMSR2_Sea_Ice_Concentration_12km</dc:title>
+      </csw:BriefRecord>
+      <csw:BriefRecord>
+        <dc:identifier>PYCSW_IDENTIFIER-MODIS_Terra_Cloud_Top_Temp_Night</dc:identifier>
+        <dc:title>MODIS_Terra_Cloud_Top_Temp_Night</dc:title>
+      </csw:BriefRecord>
+      <csw:BriefRecord>
+        <dc:identifier>PYCSW_IDENTIFIER-MEaSUREs_Daily_Landscape_Freeze_Thaw_SSMI</dc:identifier>
+        <dc:title>MEaSUREs_Daily_Landscape_Freeze_Thaw_SSMI</dc:title>
+      </csw:BriefRecord>
+      <csw:BriefRecord>
+        <dc:identifier>PYCSW_IDENTIFIER-AMSR2_Surface_Precipitation_Rate_Day</dc:identifier>
+        <dc:title>AMSR2_Surface_Precipitation_Rate_Day</dc:title>
+      </csw:BriefRecord>
+      <csw:BriefRecord>
+        <dc:identifier>PYCSW_IDENTIFIER-SMAP_L1_Passive_Brightness_Temp_Aft_H_QA</dc:identifier>
+        <dc:title>SMAP_L1_Passive_Brightness_Temp_Aft_H_QA</dc:title>
+      </csw:BriefRecord>
+      <csw:BriefRecord>
+        <dc:identifier>PYCSW_IDENTIFIER-MLS_N2O_46hPa_Night</dc:identifier>
+        <dc:title>MLS_N2O_46hPa_Night</dc:title>
+      </csw:BriefRecord>
+      <csw:BriefRecord>
+        <dc:identifier>PYCSW_IDENTIFIER-SRTM_Color_Index</dc:identifier>
+        <dc:title>SRTM_Color_Index</dc:title>
+      </csw:BriefRecord>
+      <csw:BriefRecord>
+        <dc:identifier>PYCSW_IDENTIFIER-MLS_O3_46hPa_Night</dc:identifier>
+        <dc:title>MLS_O3_46hPa_Night</dc:title>
+      </csw:BriefRecord>
+      <csw:BriefRecord>
+        <dc:identifier>PYCSW_IDENTIFIER-AIRS_Dust_Score_Ocean_Night</dc:identifier>
+        <dc:title>AIRS_Dust_Score_Ocean_Night</dc:title>
+      </csw:BriefRecord>
+      <csw:BriefRecord>
+        <dc:identifier>PYCSW_IDENTIFIER-MODIS_Aqua_SurfaceReflectance_Bands121</dc:identifier>
+        <dc:title>MODIS_Aqua_SurfaceReflectance_Bands121</dc:title>
+      </csw:BriefRecord>
+      <csw:BriefRecord>
+        <dc:identifier>PYCSW_IDENTIFIER-AMSR2_Wind_Speed_Night</dc:identifier>
+        <dc:title>AMSR2_Wind_Speed_Night</dc:title>
+      </csw:BriefRecord>
+      <csw:BriefRecord>
+        <dc:identifier>PYCSW_IDENTIFIER-SMAP_L4_Soil_Temperature_Layer_1</dc:identifier>
+        <dc:title>SMAP_L4_Soil_Temperature_Layer_1</dc:title>
+      </csw:BriefRecord>
+      <csw:BriefRecord>
+        <dc:identifier>PYCSW_IDENTIFIER-ASTER_GDEM_Greyscale_Shaded_Relief</dc:identifier>
+        <dc:title>ASTER_GDEM_Greyscale_Shaded_Relief</dc:title>
+      </csw:BriefRecord>
+      <csw:BriefRecord>
+        <dc:identifier>PYCSW_IDENTIFIER-AMSR2_Surface_Rain_Rate_Night</dc:identifier>
+        <dc:title>AMSR2_Surface_Rain_Rate_Night</dc:title>
+      </csw:BriefRecord>
+      <csw:BriefRecord>
+        <dc:identifier>PYCSW_IDENTIFIER-AIRS_Prata_SO2_Index_Day</dc:identifier>
+        <dc:title>AIRS_Prata_SO2_Index_Day</dc:title>
+      </csw:BriefRecord>
+      <csw:BriefRecord>
+        <dc:identifier>PYCSW_IDENTIFIER-MODIS_Aqua_Brightness_Temp_Band31_Night</dc:identifier>
+        <dc:title>MODIS_Aqua_Brightness_Temp_Band31_Night</dc:title>
+      </csw:BriefRecord>
+      <csw:BriefRecord>
+        <dc:identifier>PYCSW_IDENTIFIER-MLS_SO2_147hPa_Night</dc:identifier>
+        <dc:title>MLS_SO2_147hPa_Night</dc:title>
+      </csw:BriefRecord>
+      <csw:BriefRecord>
+        <dc:identifier>PYCSW_IDENTIFIER-MODIS_Aqua_Land_Surface_Temp_Night</dc:identifier>
+        <dc:title>MODIS_Aqua_Land_Surface_Temp_Night</dc:title>
+      </csw:BriefRecord>
+      <csw:BriefRecord>
+        <dc:identifier>PYCSW_IDENTIFIER-MLS_SO2_147hPa_Day</dc:identifier>
+        <dc:title>MLS_SO2_147hPa_Day</dc:title>
+      </csw:BriefRecord>
+      <csw:BriefRecord>
+        <dc:identifier>PYCSW_IDENTIFIER-MODIS_Aqua_Sea_Ice</dc:identifier>
+        <dc:title>MODIS_Aqua_Sea_Ice</dc:title>
+      </csw:BriefRecord>
+      <csw:BriefRecord>
+        <dc:identifier>PYCSW_IDENTIFIER-MODIS_Aqua_Water_Vapor_5km_Night</dc:identifier>
+        <dc:title>MODIS_Aqua_Water_Vapor_5km_Night</dc:title>
+      </csw:BriefRecord>
+      <csw:BriefRecord>
+        <dc:identifier>PYCSW_IDENTIFIER-MODIS_Aqua_Data_No_Data</dc:identifier>
+        <dc:title>MODIS_Aqua_Data_No_Data</dc:title>
+      </csw:BriefRecord>
+      <csw:BriefRecord>
+        <dc:identifier>PYCSW_IDENTIFIER-OMI_SO2_Upper_Troposphere_and_Stratosphere</dc:identifier>
+        <dc:title>OMI_SO2_Upper_Troposphere_and_Stratosphere</dc:title>
+      </csw:BriefRecord>
+      <csw:BriefRecord>
+        <dc:identifier>PYCSW_IDENTIFIER-ASTER_GDEM_Color_Shaded_Relief</dc:identifier>
+        <dc:title>ASTER_GDEM_Color_Shaded_Relief</dc:title>
+      </csw:BriefRecord>
+    </csw:InsertResult>
+  </csw:TransactionResponse>
+</csw:HarvestResponse>
diff --git a/tests/expected/suites_harvesting_post_Harvest-wps.xml b/tests/expected/suites_harvesting_post_Harvest-wps.xml
index a402ca6..d4da1a5 100644
--- a/tests/expected/suites_harvesting_post_Harvest-wps.xml
+++ b/tests/expected/suites_harvesting_post_Harvest-wps.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<csw:HarvestResponse xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:inspire_common="http://inspire.ec.europa.eu/schemas/common/1.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dct="http://purl.org/dc/terms/" xmlns:ows="http://www.opengis.net/ows" xmlns:apiso="http://www.opengis.net/cat/csw/apiso/1.0" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xlink="http://www.w3.org/1999/xlink" xml [...]
+<csw:HarvestResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/cat/csw/2.0.2 http://schemas.opengis.net/csw/2.0.2/CSW-publication.xsd">
   <csw:TransactionResponse version="2.0.2">
     <csw:TransactionSummary>
       <csw:totalInserted>1</csw:totalInserted>
diff --git a/tests/expected/suites_harvesting_post_Harvest-zzz-post-GetRecords-filter-ows-dc.xml b/tests/expected/suites_harvesting_post_Harvest-zzz-post-GetRecords-filter-ows-dc.xml
index 45b4df5..8f8611f 100644
--- a/tests/expected/suites_harvesting_post_Harvest-zzz-post-GetRecords-filter-ows-dc.xml
+++ b/tests/expected/suites_harvesting_post_Harvest-zzz-post-GetRecords-filter-ows-dc.xml
@@ -1,23 +1,28 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<csw:GetRecordsResponse xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:inspire_common="http://inspire.ec.europa.eu/schemas/common/1.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dct="http://purl.org/dc/terms/" xmlns:ows="http://www.opengis.net/ows" xmlns:apiso="http://www.opengis.net/cat/csw/apiso/1.0" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xlink="http://www.w3.org/1999/xlink"  [...]
+<csw:GetRecordsResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.0.2" xsi:schemaLocation="http://www.opengis.net/cat/csw/2.0.2 http://schemas.opengis.net/csw/2.0.2/CSW-di [...]
   <csw:SearchStatus timestamp="PYCSW_TIMESTAMP"/>
-  <csw:SearchResults nextRecord="6" numberOfRecordsMatched="8" numberOfRecordsReturned="5" recordSchema="http://www.opengis.net/cat/csw/2.0.2" elementSet="full">
+  <csw:SearchResults nextRecord="6" numberOfRecordsMatched="11" numberOfRecordsReturned="5" recordSchema="http://www.opengis.net/cat/csw/2.0.2" elementSet="full">
     <csw:Record>
       <dc:identifier>PYCSW_IDENTIFIER</dc:identifier>
-      <dc:title></dc:title>
+      <dc:title>pycsw Geospatial Catalogue OGC services demo</dc:title>
       <dc:type>service</dc:type>
-      <dc:subject></dc:subject>
+      <dc:subject>catalogue</dc:subject>
+      <dc:subject>discovery</dc:subject>
+      <dc:subject>metadata</dc:subject>
+      <dc:subject>services</dc:subject>
       <dc:format>CSW</dc:format>
-      <dct:references scheme="OGC:CSW">http://sdi.georchestra.org/geoserver/ows</dct:references>
-      <dc:creator>geOrchestra PSC</dc:creator>
-      <dc:publisher>geOrchestra</dc:publisher>
-      <dc:contributor>geOrchestra PSC</dc:contributor>
-      <dc:source>http://sdi.georchestra.org/geoserver/ows</dc:source>
+      <dct:references scheme="OGC:CSW">http://demo.pycsw.org/services/csw</dct:references>
+      <dct:abstract>pycsw is an OGC CSW server implementation written in Python</dct:abstract>
+      <dc:creator>Lastname, Firstname</dc:creator>
+      <dc:publisher>Organization Name</dc:publisher>
+      <dc:contributor>Lastname, Firstname</dc:contributor>
+      <dc:source>http://demo.pycsw.org/services/csw</dc:source>
+      <dc:rights>None</dc:rights>
     </csw:Record>
     <csw:Record>
       <dc:identifier>PYCSW_IDENTIFIER</dc:identifier>
-      <dc:title>pycsw Geospatial Catalogue OGC CITE demo and Reference Implementation</dc:title>
+      <dc:title>pycsw OGC CITE demo and Reference Implementation</dc:title>
       <dc:type>service</dc:type>
       <dc:subject>ogc</dc:subject>
       <dc:subject>cite</dc:subject>
diff --git a/tests/expected/suites_harvesting_post_Harvest-zzz-post-GetRecords-filter-sos-abstract-dc.xml b/tests/expected/suites_harvesting_post_Harvest-zzz-post-GetRecords-filter-sos-abstract-dc.xml
index 96c31fb..f5af507 100644
--- a/tests/expected/suites_harvesting_post_Harvest-zzz-post-GetRecords-filter-sos-abstract-dc.xml
+++ b/tests/expected/suites_harvesting_post_Harvest-zzz-post-GetRecords-filter-sos-abstract-dc.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<csw:GetRecordsResponse xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:inspire_common="http://inspire.ec.europa.eu/schemas/common/1.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dct="http://purl.org/dc/terms/" xmlns:ows="http://www.opengis.net/ows" xmlns:apiso="http://www.opengis.net/cat/csw/apiso/1.0" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xlink="http://www.w3.org/1999/xlink"  [...]
+<csw:GetRecordsResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.0.2" xsi:schemaLocation="http://www.opengis.net/cat/csw/2.0.2 http://schemas.opengis.net/csw/2.0.2/CSW-di [...]
   <csw:SearchStatus timestamp="PYCSW_TIMESTAMP"/>
   <csw:SearchResults nextRecord="0" numberOfRecordsMatched="1" numberOfRecordsReturned="1" recordSchema="http://www.opengis.net/cat/csw/2.0.2" elementSet="full">
     <csw:Record>
diff --git a/tests/expected/suites_harvesting_post_Harvest-zzz-post-GetRecords-filter-sos-dc.xml b/tests/expected/suites_harvesting_post_Harvest-zzz-post-GetRecords-filter-sos-dc.xml
index 921f77b..8523426 100644
--- a/tests/expected/suites_harvesting_post_Harvest-zzz-post-GetRecords-filter-sos-dc.xml
+++ b/tests/expected/suites_harvesting_post_Harvest-zzz-post-GetRecords-filter-sos-dc.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<csw:GetRecordsResponse xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:inspire_common="http://inspire.ec.europa.eu/schemas/common/1.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dct="http://purl.org/dc/terms/" xmlns:ows="http://www.opengis.net/ows" xmlns:apiso="http://www.opengis.net/cat/csw/apiso/1.0" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xlink="http://www.w3.org/1999/xlink"  [...]
+<csw:GetRecordsResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.0.2" xsi:schemaLocation="http://www.opengis.net/cat/csw/2.0.2 http://schemas.opengis.net/csw/2.0.2/CSW-di [...]
   <csw:SearchStatus timestamp="PYCSW_TIMESTAMP"/>
   <csw:SearchResults nextRecord="0" numberOfRecordsMatched="2" numberOfRecordsReturned="2" recordSchema="http://www.opengis.net/cat/csw/2.0.2" elementSet="full">
     <csw:Record>
diff --git a/tests/expected/suites_harvesting_post_Harvest-zzz-post-GetRecords-filter-sos-iso.xml b/tests/expected/suites_harvesting_post_Harvest-zzz-post-GetRecords-filter-sos-iso.xml
index 92e0af7..5192a0f 100644
--- a/tests/expected/suites_harvesting_post_Harvest-zzz-post-GetRecords-filter-sos-iso.xml
+++ b/tests/expected/suites_harvesting_post_Harvest-zzz-post-GetRecords-filter-sos-iso.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<csw:GetRecordsResponse xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:inspire_common="http://inspire.ec.europa.eu/schemas/common/1.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dct="http://purl.org/dc/terms/" xmlns:ows="http://www.opengis.net/ows" xmlns:apiso="http://www.opengis.net/cat/csw/apiso/1.0" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xlink="http://www.w3.org/1999/xlink"  [...]
+<csw:GetRecordsResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gco="http://www.isotc211.org/2005/gco" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:srv="http://www.isotc211.org/2005/srv" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XML [...]
   <csw:SearchStatus timestamp="PYCSW_TIMESTAMP"/>
   <csw:SearchResults nextRecord="0" numberOfRecordsMatched="2" numberOfRecordsReturned="2" recordSchema="http://www.isotc211.org/2005/gmd" elementSet="full">
     <gmd:MD_Metadata xsi:schemaLocation="http://www.isotc211.org/2005/gmd http://schemas.opengis.net/csw/2.0.2/profiles/apiso/1.0.0/apiso.xsd">
diff --git a/tests/expected/suites_harvesting_post_Harvest-zzz-post-GetRecords-filter-wfs-iso.xml b/tests/expected/suites_harvesting_post_Harvest-zzz-post-GetRecords-filter-wfs-iso.xml
index a869821..5078cd1 100644
--- a/tests/expected/suites_harvesting_post_Harvest-zzz-post-GetRecords-filter-wfs-iso.xml
+++ b/tests/expected/suites_harvesting_post_Harvest-zzz-post-GetRecords-filter-wfs-iso.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<csw:GetRecordsResponse xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:inspire_common="http://inspire.ec.europa.eu/schemas/common/1.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dct="http://purl.org/dc/terms/" xmlns:ows="http://www.opengis.net/ows" xmlns:apiso="http://www.opengis.net/cat/csw/apiso/1.0" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xlink="http://www.w3.org/1999/xlink"  [...]
+<csw:GetRecordsResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gco="http://www.isotc211.org/2005/gco" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:srv="http://www.isotc211.org/2005/srv" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XML [...]
   <csw:SearchStatus timestamp="PYCSW_TIMESTAMP"/>
   <csw:SearchResults nextRecord="0" numberOfRecordsMatched="1" numberOfRecordsReturned="1" recordSchema="http://www.isotc211.org/2005/gmd" elementSet="full">
     <gmd:MD_Metadata xsi:schemaLocation="http://www.isotc211.org/2005/gmd http://schemas.opengis.net/csw/2.0.2/profiles/apiso/1.0.0/apiso.xsd">
@@ -126,16 +126,16 @@
               <gmd:geographicElement>
                 <gmd:EX_GeographicBoundingBox>
                   <gmd:westBoundLongitude>
-                    <gco:Decimal>-189.85</gco:Decimal>
+                    <gco:Decimal>-179.87</gco:Decimal>
                   </gmd:westBoundLongitude>
                   <gmd:eastBoundLongitude>
-                    <gco:Decimal>190.98</gco:Decimal>
+                    <gco:Decimal>179.99</gco:Decimal>
                   </gmd:eastBoundLongitude>
                   <gmd:southBoundLatitude>
-                    <gco:Decimal>-176.73</gco:Decimal>
+                    <gco:Decimal>-54.61</gco:Decimal>
                   </gmd:southBoundLatitude>
                   <gmd:northBoundLatitude>
-                    <gco:Decimal>212.97</gco:Decimal>
+                    <gco:Decimal>83.46</gco:Decimal>
                   </gmd:northBoundLatitude>
                 </gmd:EX_GeographicBoundingBox>
               </gmd:geographicElement>
diff --git a/tests/expected/suites_harvesting_post_Harvest-zzz-post-GetRecords-filter-wms-dc.xml b/tests/expected/suites_harvesting_post_Harvest-zzz-post-GetRecords-filter-wms-dc.xml
index 4e1ada3..42e9a1d 100644
--- a/tests/expected/suites_harvesting_post_Harvest-zzz-post-GetRecords-filter-wms-dc.xml
+++ b/tests/expected/suites_harvesting_post_Harvest-zzz-post-GetRecords-filter-wms-dc.xml
@@ -1,8 +1,72 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<csw:GetRecordsResponse xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:inspire_common="http://inspire.ec.europa.eu/schemas/common/1.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dct="http://purl.org/dc/terms/" xmlns:ows="http://www.opengis.net/ows" xmlns:apiso="http://www.opengis.net/cat/csw/apiso/1.0" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xlink="http://www.w3.org/1999/xlink"  [...]
+<csw:GetRecordsResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.0.2" xsi:schemaLocation="http://www.opengis.net/cat/csw/2.0.2 http://schemas.opengis.net/csw/2.0.2/CSW-di [...]
   <csw:SearchStatus timestamp="PYCSW_TIMESTAMP"/>
-  <csw:SearchResults nextRecord="0" numberOfRecordsMatched="1" numberOfRecordsReturned="1" recordSchema="http://www.opengis.net/cat/csw/2.0.2" elementSet="full">
+  <csw:SearchResults nextRecord="0" numberOfRecordsMatched="4" numberOfRecordsReturned="4" recordSchema="http://www.opengis.net/cat/csw/2.0.2" elementSet="full">
+    <csw:Record>
+      <dc:identifier>PYCSW_IDENTIFIER</dc:identifier>
+      <dc:title>1 Million Scale WMS Layers from the National Atlas of the United States</dc:title>
+      <dc:type>service</dc:type>
+      <dc:subject></dc:subject>
+      <dct:references scheme="OGC:WMS">http://webservices.nationalatlas.gov/wms/1million</dct:references>
+      <dct:references scheme="OGC:WMS-1.1.1-http-get-capabilities">http://webservices.nationalatlas.gov/wms/1million?version=1.1.1&request=GetCapabilities&service=WMS</dct:references>
+      <dct:references scheme="None">http://webservices.nationalatlas.gov/wms/1million</dct:references>
+      <dct:references scheme="None">http://webservices.nationalatlas.gov/wms/1million</dct:references>
+      <dct:references scheme="None">http://webservices.nationalatlas.gov/wms/1million</dct:references>
+      <dct:references scheme="None">http://webservices.nationalatlas.gov/wms/1million</dct:references>
+      <dct:references scheme="None">http://webservices.nationalatlas.gov/wms/1million</dct:references>
+      <dct:references scheme="None">http://webservices.nationalatlas.gov/wms/1million</dct:references>
+      <dc:source>http://demo.pycsw.org/services/csw</dc:source>
+      <ows:BoundingBox crs="urn:x-ogc:def:crs:EPSG:6.11:4326" dimensions="2">
+        <ows:LowerCorner>18.92 -179.13</ows:LowerCorner>
+        <ows:UpperCorner>71.4 179.79</ows:UpperCorner>
+      </ows:BoundingBox>
+    </csw:Record>
+    <csw:Record>
+      <dc:identifier>PYCSW_IDENTIFIER</dc:identifier>
+      <dc:title>Wisconsin Lake Clarity</dc:title>
+      <dc:type>service</dc:type>
+      <dc:subject>SSEC</dc:subject>
+      <dc:subject>PAW</dc:subject>
+      <dc:subject>remote sensing</dc:subject>
+      <dc:subject>meteorology</dc:subject>
+      <dc:subject>atmospheric science</dc:subject>
+      <dc:subject>University of Wisconsin</dc:subject>
+      <dc:subject>Madison</dc:subject>
+      <dc:subject>weather</dc:subject>
+      <dc:subject>land</dc:subject>
+      <dct:references scheme="OGC:WMS">http://wms.ssec.wisc.edu/cgi-bin/mapserv?map=/home/wms/data/mapfiles/lakestsi.map</dct:references>
+      <dct:references scheme="OGC:WMS-1.1.1-http-get-capabilities">http://wms.ssec.wisc.edu/cgi-bin/mapserv?map=%2Fhome%2Fwms%2Fdata%2Fmapfiles%2Flakestsi.map&version=1.1.1&request=GetCapabilities&service=WMS</dct:references>
+      <dct:references scheme="None">http://wms.ssec.wisc.edu/cgi-bin/mapserv?map=/home/wms/data/mapfiles/lakestsi.map</dct:references>
+      <dct:references scheme="None">http://wms.ssec.wisc.edu/cgi-bin/mapserv?map=/home/wms/data/mapfiles/lakestsi.map</dct:references>
+      <dct:references scheme="None">http://wms.ssec.wisc.edu/cgi-bin/mapserv?map=/home/wms/data/mapfiles/lakestsi.map</dct:references>
+      <dct:abstract>General: This server hosts a set of experimental OGC Web Services of remote sensing data products for use in a broad range of both desktop and mobile device clients.</dct:abstract>
+      <dc:source>http://demo.pycsw.org/services/csw</dc:source>
+      <ows:BoundingBox crs="urn:x-ogc:def:crs:EPSG:6.11:4326" dimensions="2">
+        <ows:LowerCorner>42.41 -93.03</ows:LowerCorner>
+        <ows:UpperCorner>47.13 -86.64</ows:UpperCorner>
+      </ows:BoundingBox>
+    </csw:Record>
+    <csw:Record>
+      <dc:identifier>PYCSW_IDENTIFIER</dc:identifier>
+      <dc:title>View & download service for EU-DEM data provided by EOX</dc:title>
+      <dc:type>service</dc:type>
+      <dc:subject>EU-DEM</dc:subject>
+      <dct:references scheme="OGC:WMS">http://data.eox.at/eudem_ows</dct:references>
+      <dct:references scheme="OGC:WMS-1.1.1-http-get-capabilities">http://data.eox.at/eudem_ows?version=1.1.1&request=GetCapabilities&service=WMS</dct:references>
+      <dct:references scheme="None">http://data.eox.at/eudem_ows</dct:references>
+      <dct:references scheme="None">http://data.eox.at/eudem_ows</dct:references>
+      <dct:references scheme="None">http://data.eox.at/eudem_ows</dct:references>
+      <dct:references scheme="None">http://data.eox.at/eudem_ows</dct:references>
+      <dct:references scheme="None">http://data.eox.at/eudem_ows</dct:references>
+      <dct:references scheme="None">http://data.eox.at/eudem_ows</dct:references>
+      <dct:abstract>Produced using Copernicus data and information funded by the European Union - EU-DEM layers.</dct:abstract>
+      <dc:source>http://demo.pycsw.org/services/csw</dc:source>
+      <ows:BoundingBox crs="urn:x-ogc:def:crs:EPSG:6.11:4326" dimensions="2">
+        <ows:LowerCorner>12.99 -29.09</ows:LowerCorner>
+        <ows:UpperCorner>12.99 -29.09</ows:UpperCorner>
+      </ows:BoundingBox>
+    </csw:Record>
     <csw:Record>
       <dc:identifier>PYCSW_IDENTIFIER</dc:identifier>
       <dc:title>IEM WMS Service</dc:title>
diff --git a/tests/expected/suites_harvesting_post_Harvest-zzz-post-GetRecords-filter-wms-iso.xml b/tests/expected/suites_harvesting_post_Harvest-zzz-post-GetRecords-filter-wms-iso.xml
index b918a00..2baa6c8 100644
--- a/tests/expected/suites_harvesting_post_Harvest-zzz-post-GetRecords-filter-wms-iso.xml
+++ b/tests/expected/suites_harvesting_post_Harvest-zzz-post-GetRecords-filter-wms-iso.xml
@@ -1,8 +1,1061 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<csw:GetRecordsResponse xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:inspire_common="http://inspire.ec.europa.eu/schemas/common/1.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dct="http://purl.org/dc/terms/" xmlns:ows="http://www.opengis.net/ows" xmlns:apiso="http://www.opengis.net/cat/csw/apiso/1.0" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xlink="http://www.w3.org/1999/xlink"  [...]
+<csw:GetRecordsResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gco="http://www.isotc211.org/2005/gco" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:srv="http://www.isotc211.org/2005/srv" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XML [...]
   <csw:SearchStatus timestamp="PYCSW_TIMESTAMP"/>
-  <csw:SearchResults nextRecord="0" numberOfRecordsMatched="1" numberOfRecordsReturned="1" recordSchema="http://www.isotc211.org/2005/gmd" elementSet="full">
+  <csw:SearchResults nextRecord="0" numberOfRecordsMatched="4" numberOfRecordsReturned="4" recordSchema="http://www.isotc211.org/2005/gmd" elementSet="full">
+    <gmd:MD_Metadata xsi:schemaLocation="http://www.isotc211.org/2005/gmd http://schemas.opengis.net/csw/2.0.2/profiles/apiso/1.0.0/apiso.xsd">
+      <gmd:fileIdentifier>
+        <gco:CharacterString>PYCSW_IDENTIFIER</gco:CharacterString>
+      </gmd:fileIdentifier>
+      <gmd:language>
+        <gco:CharacterString/>
+      </gmd:language>
+      <gmd:hierarchyLevel>
+        <gmd:MD_ScopeCode codeList="http://www.isotc211.org/2005/resources/Codelist/gmxCodelists.xml#MD_ScopeCode" codeListValue="service" codeSpace="ISOTC211/19115">service</gmd:MD_ScopeCode>
+      </gmd:hierarchyLevel>
+      <gmd:contact/>
+      <gmd:dateStamp>
+        <gco:Date/>
+      </gmd:dateStamp>
+      <gmd:metadataStandardName>
+        <gco:CharacterString>ISO19119</gco:CharacterString>
+      </gmd:metadataStandardName>
+      <gmd:metadataStandardVersion>
+        <gco:CharacterString>2005/PDAM 1</gco:CharacterString>
+      </gmd:metadataStandardVersion>
+      <gmd:identificationInfo>
+        <srv:SV_ServiceIdentification id="PYCSW_IDENTIFIER">
+          <gmd:citation>
+            <gmd:CI_Citation>
+              <gmd:title>
+                <gco:CharacterString>1 Million Scale WMS Layers from the National Atlas of the United States</gco:CharacterString>
+              </gmd:title>
+            </gmd:CI_Citation>
+          </gmd:citation>
+          <gmd:abstract>
+            <gco:CharacterString/>
+          </gmd:abstract>
+          <gmd:descriptiveKeywords>
+            <gmd:MD_Keywords>
+              <gmd:keyword>
+                <gco:CharacterString/>
+              </gmd:keyword>
+            </gmd:MD_Keywords>
+          </gmd:descriptiveKeywords>
+          <gmd:language>
+            <gco:CharacterString/>
+          </gmd:language>
+          <srv:serviceType>
+            <gco:LocalName>OGC:WMS</gco:LocalName>
+          </srv:serviceType>
+          <srv:serviceTypeVersion>
+            <gco:CharacterString>1.1.1</gco:CharacterString>
+          </srv:serviceTypeVersion>
+          <srv:keywords>
+            <gmd:MD_Keywords>
+              <gmd:keyword>
+                <gco:CharacterString/>
+              </gmd:keyword>
+            </gmd:MD_Keywords>
+          </srv:keywords>
+          <srv:extent>
+            <gmd:EX_Extent>
+              <gmd:geographicElement>
+                <gmd:EX_GeographicBoundingBox>
+                  <gmd:westBoundLongitude>
+                    <gco:Decimal>-179.13</gco:Decimal>
+                  </gmd:westBoundLongitude>
+                  <gmd:eastBoundLongitude>
+                    <gco:Decimal>179.79</gco:Decimal>
+                  </gmd:eastBoundLongitude>
+                  <gmd:southBoundLatitude>
+                    <gco:Decimal>18.92</gco:Decimal>
+                  </gmd:southBoundLatitude>
+                  <gmd:northBoundLatitude>
+                    <gco:Decimal>71.4</gco:Decimal>
+                  </gmd:northBoundLatitude>
+                </gmd:EX_GeographicBoundingBox>
+              </gmd:geographicElement>
+            </gmd:EX_Extent>
+          </srv:extent>
+          <srv:couplingType>
+            <srv:SV_CouplingType codeList="http://www.isotc211.org/2005/resources/Codelist/gmxCodelists.xml#SV_CouplingType" codeListValue="tight">tight</srv:SV_CouplingType>
+          </srv:couplingType>
+          <srv:coupledResource>
+            <srv:SV_CoupledResource>
+              <srv:operationName>
+                <gco:CharacterString>GetMap</gco:CharacterString>
+              </srv:operationName>
+              <srv:identifier>
+                <gco:CharacterString>ports1m</gco:CharacterString>
+              </srv:identifier>
+            </srv:SV_CoupledResource>
+          </srv:coupledResource>
+          <srv:coupledResource>
+            <srv:SV_CoupledResource>
+              <srv:operationName>
+                <gco:CharacterString>GetMap</gco:CharacterString>
+              </srv:operationName>
+              <srv:identifier>
+                <gco:CharacterString>national1m</gco:CharacterString>
+              </srv:identifier>
+            </srv:SV_CoupledResource>
+          </srv:coupledResource>
+          <srv:coupledResource>
+            <srv:SV_CoupledResource>
+              <srv:operationName>
+                <gco:CharacterString>GetMap</gco:CharacterString>
+              </srv:operationName>
+              <srv:identifier>
+                <gco:CharacterString>elevation</gco:CharacterString>
+              </srv:identifier>
+            </srv:SV_CoupledResource>
+          </srv:coupledResource>
+          <srv:coupledResource>
+            <srv:SV_CoupledResource>
+              <srv:operationName>
+                <gco:CharacterString>GetMap</gco:CharacterString>
+              </srv:operationName>
+              <srv:identifier>
+                <gco:CharacterString>impervious</gco:CharacterString>
+              </srv:identifier>
+            </srv:SV_CoupledResource>
+          </srv:coupledResource>
+          <srv:coupledResource>
+            <srv:SV_CoupledResource>
+              <srv:operationName>
+                <gco:CharacterString>GetMap</gco:CharacterString>
+              </srv:operationName>
+              <srv:identifier>
+                <gco:CharacterString>coast1m</gco:CharacterString>
+              </srv:identifier>
+            </srv:SV_CoupledResource>
+          </srv:coupledResource>
+          <srv:coupledResource>
+            <srv:SV_CoupledResource>
+              <srv:operationName>
+                <gco:CharacterString>GetMap</gco:CharacterString>
+              </srv:operationName>
+              <srv:identifier>
+                <gco:CharacterString>cdl</gco:CharacterString>
+              </srv:identifier>
+            </srv:SV_CoupledResource>
+          </srv:coupledResource>
+          <srv:coupledResource>
+            <srv:SV_CoupledResource>
+              <srv:operationName>
+                <gco:CharacterString>GetMap</gco:CharacterString>
+              </srv:operationName>
+              <srv:identifier>
+                <gco:CharacterString>states1m</gco:CharacterString>
+              </srv:identifier>
+            </srv:SV_CoupledResource>
+          </srv:coupledResource>
+          <srv:coupledResource>
+            <srv:SV_CoupledResource>
+              <srv:operationName>
+                <gco:CharacterString>GetMap</gco:CharacterString>
+              </srv:operationName>
+              <srv:identifier>
+                <gco:CharacterString>elsli0100g</gco:CharacterString>
+              </srv:identifier>
+            </srv:SV_CoupledResource>
+          </srv:coupledResource>
+          <srv:coupledResource>
+            <srv:SV_CoupledResource>
+              <srv:operationName>
+                <gco:CharacterString>GetMap</gco:CharacterString>
+              </srv:operationName>
+              <srv:identifier>
+                <gco:CharacterString>landcov100m</gco:CharacterString>
+              </srv:identifier>
+            </srv:SV_CoupledResource>
+          </srv:coupledResource>
+          <srv:coupledResource>
+            <srv:SV_CoupledResource>
+              <srv:operationName>
+                <gco:CharacterString>GetMap</gco:CharacterString>
+              </srv:operationName>
+              <srv:identifier>
+                <gco:CharacterString>cdp</gco:CharacterString>
+              </srv:identifier>
+            </srv:SV_CoupledResource>
+          </srv:coupledResource>
+          <srv:coupledResource>
+            <srv:SV_CoupledResource>
+              <srv:operationName>
+                <gco:CharacterString>GetMap</gco:CharacterString>
+              </srv:operationName>
+              <srv:identifier>
+                <gco:CharacterString>amtrak1m</gco:CharacterString>
+              </srv:identifier>
+            </srv:SV_CoupledResource>
+          </srv:coupledResource>
+          <srv:coupledResource>
+            <srv:SV_CoupledResource>
+              <srv:operationName>
+                <gco:CharacterString>GetMap</gco:CharacterString>
+              </srv:operationName>
+              <srv:identifier>
+                <gco:CharacterString>airports1m</gco:CharacterString>
+              </srv:identifier>
+            </srv:SV_CoupledResource>
+          </srv:coupledResource>
+          <srv:coupledResource>
+            <srv:SV_CoupledResource>
+              <srv:operationName>
+                <gco:CharacterString>GetMap</gco:CharacterString>
+              </srv:operationName>
+              <srv:identifier>
+                <gco:CharacterString>one_million</gco:CharacterString>
+              </srv:identifier>
+            </srv:SV_CoupledResource>
+          </srv:coupledResource>
+          <srv:coupledResource>
+            <srv:SV_CoupledResource>
+              <srv:operationName>
+                <gco:CharacterString>GetMap</gco:CharacterString>
+              </srv:operationName>
+              <srv:identifier>
+                <gco:CharacterString>satvi0100g</gco:CharacterString>
+              </srv:identifier>
+            </srv:SV_CoupledResource>
+          </srv:coupledResource>
+          <srv:coupledResource>
+            <srv:SV_CoupledResource>
+              <srv:operationName>
+                <gco:CharacterString>GetMap</gco:CharacterString>
+              </srv:operationName>
+              <srv:identifier>
+                <gco:CharacterString>srcoi0100g</gco:CharacterString>
+              </srv:identifier>
+            </srv:SV_CoupledResource>
+          </srv:coupledResource>
+          <srv:coupledResource>
+            <srv:SV_CoupledResource>
+              <srv:operationName>
+                <gco:CharacterString>GetMap</gco:CharacterString>
+              </srv:operationName>
+              <srv:identifier>
+                <gco:CharacterString>srgri0100g</gco:CharacterString>
+              </srv:identifier>
+            </srv:SV_CoupledResource>
+          </srv:coupledResource>
+          <srv:coupledResource>
+            <srv:SV_CoupledResource>
+              <srv:operationName>
+                <gco:CharacterString>GetMap</gco:CharacterString>
+              </srv:operationName>
+              <srv:identifier>
+                <gco:CharacterString>treecanopy</gco:CharacterString>
+              </srv:identifier>
+            </srv:SV_CoupledResource>
+          </srv:coupledResource>
+          <srv:coupledResource>
+            <srv:SV_CoupledResource>
+              <srv:operationName>
+                <gco:CharacterString>GetMap</gco:CharacterString>
+              </srv:operationName>
+              <srv:identifier>
+                <gco:CharacterString>svsri0100g</gco:CharacterString>
+              </srv:identifier>
+            </srv:SV_CoupledResource>
+          </srv:coupledResource>
+          <srv:containsOperations>
+            <srv:SV_OperationMetadata>
+              <srv:operationName>
+                <gco:CharacterString>GetCapabilities</gco:CharacterString>
+              </srv:operationName>
+              <srv:DCP>
+                <srv:DCPList codeList="http://www.isotc211.org/2005/resources/Codelist/gmxCodelists.xml#DCPList" codeListValue="HTTPGet">HTTPGet</srv:DCPList>
+              </srv:DCP>
+              <srv:DCP>
+                <srv:DCPList codeList="http://www.isotc211.org/2005/resources/Codelist/gmxCodelists.xml#DCPList" codeListValue="HTTPPost">HTTPPost</srv:DCPList>
+              </srv:DCP>
+              <srv:connectPoint>
+                <gmd:CI_OnlineResource>
+                  <gmd:linkage>
+                    <gmd:URL>http://webservices.nationalatlas.gov/wms/1million</gmd:URL>
+                  </gmd:linkage>
+                </gmd:CI_OnlineResource>
+              </srv:connectPoint>
+            </srv:SV_OperationMetadata>
+          </srv:containsOperations>
+          <srv:containsOperations>
+            <srv:SV_OperationMetadata>
+              <srv:operationName>
+                <gco:CharacterString>GetMap</gco:CharacterString>
+              </srv:operationName>
+              <srv:DCP>
+                <srv:DCPList codeList="http://www.isotc211.org/2005/resources/Codelist/gmxCodelists.xml#DCPList" codeListValue="HTTPGet">HTTPGet</srv:DCPList>
+              </srv:DCP>
+              <srv:DCP>
+                <srv:DCPList codeList="http://www.isotc211.org/2005/resources/Codelist/gmxCodelists.xml#DCPList" codeListValue="HTTPPost">HTTPPost</srv:DCPList>
+              </srv:DCP>
+              <srv:connectPoint>
+                <gmd:CI_OnlineResource>
+                  <gmd:linkage>
+                    <gmd:URL>http://webservices.nationalatlas.gov/wms/1million</gmd:URL>
+                  </gmd:linkage>
+                </gmd:CI_OnlineResource>
+              </srv:connectPoint>
+            </srv:SV_OperationMetadata>
+          </srv:containsOperations>
+          <srv:containsOperations>
+            <srv:SV_OperationMetadata>
+              <srv:operationName>
+                <gco:CharacterString>GetFeatureInfo</gco:CharacterString>
+              </srv:operationName>
+              <srv:DCP>
+                <srv:DCPList codeList="http://www.isotc211.org/2005/resources/Codelist/gmxCodelists.xml#DCPList" codeListValue="HTTPGet">HTTPGet</srv:DCPList>
+              </srv:DCP>
+              <srv:DCP>
+                <srv:DCPList codeList="http://www.isotc211.org/2005/resources/Codelist/gmxCodelists.xml#DCPList" codeListValue="HTTPPost">HTTPPost</srv:DCPList>
+              </srv:DCP>
+              <srv:connectPoint>
+                <gmd:CI_OnlineResource>
+                  <gmd:linkage>
+                    <gmd:URL>http://webservices.nationalatlas.gov/wms/1million</gmd:URL>
+                  </gmd:linkage>
+                </gmd:CI_OnlineResource>
+              </srv:connectPoint>
+            </srv:SV_OperationMetadata>
+          </srv:containsOperations>
+          <srv:containsOperations>
+            <srv:SV_OperationMetadata>
+              <srv:operationName>
+                <gco:CharacterString>DescribeLayer</gco:CharacterString>
+              </srv:operationName>
+              <srv:DCP>
+                <srv:DCPList codeList="http://www.isotc211.org/2005/resources/Codelist/gmxCodelists.xml#DCPList" codeListValue="HTTPGet">HTTPGet</srv:DCPList>
+              </srv:DCP>
+              <srv:DCP>
+                <srv:DCPList codeList="http://www.isotc211.org/2005/resources/Codelist/gmxCodelists.xml#DCPList" codeListValue="HTTPPost">HTTPPost</srv:DCPList>
+              </srv:DCP>
+              <srv:connectPoint>
+                <gmd:CI_OnlineResource>
+                  <gmd:linkage>
+                    <gmd:URL>http://webservices.nationalatlas.gov/wms/1million</gmd:URL>
+                  </gmd:linkage>
+                </gmd:CI_OnlineResource>
+              </srv:connectPoint>
+            </srv:SV_OperationMetadata>
+          </srv:containsOperations>
+          <srv:containsOperations>
+            <srv:SV_OperationMetadata>
+              <srv:operationName>
+                <gco:CharacterString>GetLegendGraphic</gco:CharacterString>
+              </srv:operationName>
+              <srv:DCP>
+                <srv:DCPList codeList="http://www.isotc211.org/2005/resources/Codelist/gmxCodelists.xml#DCPList" codeListValue="HTTPGet">HTTPGet</srv:DCPList>
+              </srv:DCP>
+              <srv:DCP>
+                <srv:DCPList codeList="http://www.isotc211.org/2005/resources/Codelist/gmxCodelists.xml#DCPList" codeListValue="HTTPPost">HTTPPost</srv:DCPList>
+              </srv:DCP>
+              <srv:connectPoint>
+                <gmd:CI_OnlineResource>
+                  <gmd:linkage>
+                    <gmd:URL>http://webservices.nationalatlas.gov/wms/1million</gmd:URL>
+                  </gmd:linkage>
+                </gmd:CI_OnlineResource>
+              </srv:connectPoint>
+            </srv:SV_OperationMetadata>
+          </srv:containsOperations>
+          <srv:containsOperations>
+            <srv:SV_OperationMetadata>
+              <srv:operationName>
+                <gco:CharacterString>GetStyles</gco:CharacterString>
+              </srv:operationName>
+              <srv:DCP>
+                <srv:DCPList codeList="http://www.isotc211.org/2005/resources/Codelist/gmxCodelists.xml#DCPList" codeListValue="HTTPGet">HTTPGet</srv:DCPList>
+              </srv:DCP>
+              <srv:DCP>
+                <srv:DCPList codeList="http://www.isotc211.org/2005/resources/Codelist/gmxCodelists.xml#DCPList" codeListValue="HTTPPost">HTTPPost</srv:DCPList>
+              </srv:DCP>
+              <srv:connectPoint>
+                <gmd:CI_OnlineResource>
+                  <gmd:linkage>
+                    <gmd:URL>http://webservices.nationalatlas.gov/wms/1million</gmd:URL>
+                  </gmd:linkage>
+                </gmd:CI_OnlineResource>
+              </srv:connectPoint>
+            </srv:SV_OperationMetadata>
+          </srv:containsOperations>
+          <srv:operatesOn uuidref="ports1m" xlink:href="http://demo.pycsw.org/services/csw?service=CSW&version=2.0.2&request=GetRecordById&outputschema=http://www.isotc211.org/2005/gmd&id=PYCSW_IDENTIFIER-ports1m"/>
+          <srv:operatesOn uuidref="national1m" xlink:href="http://demo.pycsw.org/services/csw?service=CSW&version=2.0.2&request=GetRecordById&outputschema=http://www.isotc211.org/2005/gmd&id=PYCSW_IDENTIFIER-national1m"/>
+          <srv:operatesOn uuidref="elevation" xlink:href="http://demo.pycsw.org/services/csw?service=CSW&version=2.0.2&request=GetRecordById&outputschema=http://www.isotc211.org/2005/gmd&id=PYCSW_IDENTIFIER-elevation"/>
+          <srv:operatesOn uuidref="impervious" xlink:href="http://demo.pycsw.org/services/csw?service=CSW&version=2.0.2&request=GetRecordById&outputschema=http://www.isotc211.org/2005/gmd&id=PYCSW_IDENTIFIER-impervious"/>
+          <srv:operatesOn uuidref="coast1m" xlink:href="http://demo.pycsw.org/services/csw?service=CSW&version=2.0.2&request=GetRecordById&outputschema=http://www.isotc211.org/2005/gmd&id=PYCSW_IDENTIFIER-coast1m"/>
+          <srv:operatesOn uuidref="cdl" xlink:href="http://demo.pycsw.org/services/csw?service=CSW&version=2.0.2&request=GetRecordById&outputschema=http://www.isotc211.org/2005/gmd&id=PYCSW_IDENTIFIER-cdl"/>
+          <srv:operatesOn uuidref="states1m" xlink:href="http://demo.pycsw.org/services/csw?service=CSW&version=2.0.2&request=GetRecordById&outputschema=http://www.isotc211.org/2005/gmd&id=PYCSW_IDENTIFIER-states1m"/>
+          <srv:operatesOn uuidref="elsli0100g" xlink:href="http://demo.pycsw.org/services/csw?service=CSW&version=2.0.2&request=GetRecordById&outputschema=http://www.isotc211.org/2005/gmd&id=PYCSW_IDENTIFIER-elsli0100g"/>
+          <srv:operatesOn uuidref="landcov100m" xlink:href="http://demo.pycsw.org/services/csw?service=CSW&version=2.0.2&request=GetRecordById&outputschema=http://www.isotc211.org/2005/gmd&id=PYCSW_IDENTIFIER-landcov100m"/>
+          <srv:operatesOn uuidref="cdp" xlink:href="http://demo.pycsw.org/services/csw?service=CSW&version=2.0.2&request=GetRecordById&outputschema=http://www.isotc211.org/2005/gmd&id=PYCSW_IDENTIFIER-cdp"/>
+          <srv:operatesOn uuidref="amtrak1m" xlink:href="http://demo.pycsw.org/services/csw?service=CSW&version=2.0.2&request=GetRecordById&outputschema=http://www.isotc211.org/2005/gmd&id=PYCSW_IDENTIFIER-amtrak1m"/>
+          <srv:operatesOn uuidref="airports1m" xlink:href="http://demo.pycsw.org/services/csw?service=CSW&version=2.0.2&request=GetRecordById&outputschema=http://www.isotc211.org/2005/gmd&id=PYCSW_IDENTIFIER-airports1m"/>
+          <srv:operatesOn uuidref="one_million" xlink:href="http://demo.pycsw.org/services/csw?service=CSW&version=2.0.2&request=GetRecordById&outputschema=http://www.isotc211.org/2005/gmd&id=PYCSW_IDENTIFIER-one_million"/>
+          <srv:operatesOn uuidref="satvi0100g" xlink:href="http://demo.pycsw.org/services/csw?service=CSW&version=2.0.2&request=GetRecordById&outputschema=http://www.isotc211.org/2005/gmd&id=PYCSW_IDENTIFIER-satvi0100g"/>
+          <srv:operatesOn uuidref="srcoi0100g" xlink:href="http://demo.pycsw.org/services/csw?service=CSW&version=2.0.2&request=GetRecordById&outputschema=http://www.isotc211.org/2005/gmd&id=PYCSW_IDENTIFIER-srcoi0100g"/>
+          <srv:operatesOn uuidref="srgri0100g" xlink:href="http://demo.pycsw.org/services/csw?service=CSW&version=2.0.2&request=GetRecordById&outputschema=http://www.isotc211.org/2005/gmd&id=PYCSW_IDENTIFIER-srgri0100g"/>
+          <srv:operatesOn uuidref="treecanopy" xlink:href="http://demo.pycsw.org/services/csw?service=CSW&version=2.0.2&request=GetRecordById&outputschema=http://www.isotc211.org/2005/gmd&id=PYCSW_IDENTIFIER-treecanopy"/>
+          <srv:operatesOn uuidref="svsri0100g" xlink:href="http://demo.pycsw.org/services/csw?service=CSW&version=2.0.2&request=GetRecordById&outputschema=http://www.isotc211.org/2005/gmd&id=PYCSW_IDENTIFIER-svsri0100g"/>
+        </srv:SV_ServiceIdentification>
+      </gmd:identificationInfo>
+      <gmd:distributionInfo>
+        <gmd:MD_Distribution>
+          <gmd:transferOptions>
+            <gmd:MD_DigitalTransferOptions>
+              <gmd:onLine>
+                <gmd:CI_OnlineResource>
+                  <gmd:linkage>
+                    <gmd:URL>http://webservices.nationalatlas.gov/wms/1million</gmd:URL>
+                  </gmd:linkage>
+                  <gmd:protocol>
+                    <gco:CharacterString>OGC:WMS</gco:CharacterString>
+                  </gmd:protocol>
+                  <gmd:name>
+                    <gco:CharacterString>PYCSW_IDENTIFIER</gco:CharacterString>
+                  </gmd:name>
+                  <gmd:description>
+                    <gco:CharacterString>OGC-WMS Web Map Service</gco:CharacterString>
+                  </gmd:description>
+                </gmd:CI_OnlineResource>
+              </gmd:onLine>
+              <gmd:onLine>
+                <gmd:CI_OnlineResource>
+                  <gmd:linkage>
+                    <gmd:URL>http://webservices.nationalatlas.gov/wms/1million?version=1.1.1&request=GetCapabilities&service=WMS</gmd:URL>
+                  </gmd:linkage>
+                  <gmd:protocol>
+                    <gco:CharacterString>OGC:WMS-1.1.1-http-get-capabilities</gco:CharacterString>
+                  </gmd:protocol>
+                  <gmd:name>
+                    <gco:CharacterString>PYCSW_IDENTIFIER</gco:CharacterString>
+                  </gmd:name>
+                  <gmd:description>
+                    <gco:CharacterString>OGC-WMS Capabilities service (ver 1.1.1)</gco:CharacterString>
+                  </gmd:description>
+                </gmd:CI_OnlineResource>
+              </gmd:onLine>
+            </gmd:MD_DigitalTransferOptions>
+          </gmd:transferOptions>
+        </gmd:MD_Distribution>
+      </gmd:distributionInfo>
+    </gmd:MD_Metadata>
+    <gmd:MD_Metadata xsi:schemaLocation="http://www.isotc211.org/2005/gmd http://schemas.opengis.net/csw/2.0.2/profiles/apiso/1.0.0/apiso.xsd">
+      <gmd:fileIdentifier>
+        <gco:CharacterString>PYCSW_IDENTIFIER</gco:CharacterString>
+      </gmd:fileIdentifier>
+      <gmd:language>
+        <gco:CharacterString/>
+      </gmd:language>
+      <gmd:hierarchyLevel>
+        <gmd:MD_ScopeCode codeList="http://www.isotc211.org/2005/resources/Codelist/gmxCodelists.xml#MD_ScopeCode" codeListValue="service" codeSpace="ISOTC211/19115">service</gmd:MD_ScopeCode>
+      </gmd:hierarchyLevel>
+      <gmd:contact>
+        <gmd:CI_ResponsibleParty>
+          <gmd:organisationName>
+            <gco:CharacterString>Dr. Sam Batzli</gco:CharacterString>
+          </gmd:organisationName>
+        </gmd:CI_ResponsibleParty>
+      </gmd:contact>
+      <gmd:dateStamp>
+        <gco:Date/>
+      </gmd:dateStamp>
+      <gmd:metadataStandardName>
+        <gco:CharacterString>ISO19119</gco:CharacterString>
+      </gmd:metadataStandardName>
+      <gmd:metadataStandardVersion>
+        <gco:CharacterString>2005/PDAM 1</gco:CharacterString>
+      </gmd:metadataStandardVersion>
+      <gmd:identificationInfo>
+        <srv:SV_ServiceIdentification id="PYCSW_IDENTIFIER">
+          <gmd:citation>
+            <gmd:CI_Citation>
+              <gmd:title>
+                <gco:CharacterString>Wisconsin Lake Clarity</gco:CharacterString>
+              </gmd:title>
+            </gmd:CI_Citation>
+          </gmd:citation>
+          <gmd:abstract>
+            <gco:CharacterString>General: This server hosts a set of experimental OGC Web Services of remote sensing data products for use in a broad range of both desktop and mobile device clients.</gco:CharacterString>
+          </gmd:abstract>
+          <gmd:descriptiveKeywords>
+            <gmd:MD_Keywords>
+              <gmd:keyword>
+                <gco:CharacterString>SSEC</gco:CharacterString>
+              </gmd:keyword>
+              <gmd:keyword>
+                <gco:CharacterString>PAW</gco:CharacterString>
+              </gmd:keyword>
+              <gmd:keyword>
+                <gco:CharacterString>remote sensing</gco:CharacterString>
+              </gmd:keyword>
+              <gmd:keyword>
+                <gco:CharacterString>meteorology</gco:CharacterString>
+              </gmd:keyword>
+              <gmd:keyword>
+                <gco:CharacterString>atmospheric science</gco:CharacterString>
+              </gmd:keyword>
+              <gmd:keyword>
+                <gco:CharacterString>University of Wisconsin</gco:CharacterString>
+              </gmd:keyword>
+              <gmd:keyword>
+                <gco:CharacterString>Madison</gco:CharacterString>
+              </gmd:keyword>
+              <gmd:keyword>
+                <gco:CharacterString>weather</gco:CharacterString>
+              </gmd:keyword>
+              <gmd:keyword>
+                <gco:CharacterString>land</gco:CharacterString>
+              </gmd:keyword>
+            </gmd:MD_Keywords>
+          </gmd:descriptiveKeywords>
+          <gmd:language>
+            <gco:CharacterString/>
+          </gmd:language>
+          <srv:serviceType>
+            <gco:LocalName>OGC:WMS</gco:LocalName>
+          </srv:serviceType>
+          <srv:serviceTypeVersion>
+            <gco:CharacterString>1.1.1</gco:CharacterString>
+          </srv:serviceTypeVersion>
+          <srv:keywords>
+            <gmd:MD_Keywords>
+              <gmd:keyword>
+                <gco:CharacterString>SSEC</gco:CharacterString>
+              </gmd:keyword>
+              <gmd:keyword>
+                <gco:CharacterString>PAW</gco:CharacterString>
+              </gmd:keyword>
+              <gmd:keyword>
+                <gco:CharacterString>remote sensing</gco:CharacterString>
+              </gmd:keyword>
+              <gmd:keyword>
+                <gco:CharacterString>meteorology</gco:CharacterString>
+              </gmd:keyword>
+              <gmd:keyword>
+                <gco:CharacterString>atmospheric science</gco:CharacterString>
+              </gmd:keyword>
+              <gmd:keyword>
+                <gco:CharacterString>University of Wisconsin</gco:CharacterString>
+              </gmd:keyword>
+              <gmd:keyword>
+                <gco:CharacterString>Madison</gco:CharacterString>
+              </gmd:keyword>
+              <gmd:keyword>
+                <gco:CharacterString>weather</gco:CharacterString>
+              </gmd:keyword>
+              <gmd:keyword>
+                <gco:CharacterString>land</gco:CharacterString>
+              </gmd:keyword>
+            </gmd:MD_Keywords>
+          </srv:keywords>
+          <srv:extent>
+            <gmd:EX_Extent>
+              <gmd:geographicElement>
+                <gmd:EX_GeographicBoundingBox>
+                  <gmd:westBoundLongitude>
+                    <gco:Decimal>-93.03</gco:Decimal>
+                  </gmd:westBoundLongitude>
+                  <gmd:eastBoundLongitude>
+                    <gco:Decimal>-86.64</gco:Decimal>
+                  </gmd:eastBoundLongitude>
+                  <gmd:southBoundLatitude>
+                    <gco:Decimal>42.41</gco:Decimal>
+                  </gmd:southBoundLatitude>
+                  <gmd:northBoundLatitude>
+                    <gco:Decimal>47.13</gco:Decimal>
+                  </gmd:northBoundLatitude>
+                </gmd:EX_GeographicBoundingBox>
+              </gmd:geographicElement>
+            </gmd:EX_Extent>
+          </srv:extent>
+          <srv:couplingType>
+            <srv:SV_CouplingType codeList="http://www.isotc211.org/2005/resources/Codelist/gmxCodelists.xml#SV_CouplingType" codeListValue="tight">tight</srv:SV_CouplingType>
+          </srv:couplingType>
+          <srv:coupledResource>
+            <srv:SV_CoupledResource>
+              <srv:operationName>
+                <gco:CharacterString>GetMap</gco:CharacterString>
+              </srv:operationName>
+              <srv:identifier>
+                <gco:CharacterString>Highways</gco:CharacterString>
+              </srv:identifier>
+            </srv:SV_CoupledResource>
+          </srv:coupledResource>
+          <srv:coupledResource>
+            <srv:SV_CoupledResource>
+              <srv:operationName>
+                <gco:CharacterString>GetMap</gco:CharacterString>
+              </srv:operationName>
+              <srv:identifier>
+                <gco:CharacterString>LakesTSI</gco:CharacterString>
+              </srv:identifier>
+            </srv:SV_CoupledResource>
+          </srv:coupledResource>
+          <srv:coupledResource>
+            <srv:SV_CoupledResource>
+              <srv:operationName>
+                <gco:CharacterString>GetMap</gco:CharacterString>
+              </srv:operationName>
+              <srv:identifier>
+                <gco:CharacterString>LakeClarity</gco:CharacterString>
+              </srv:identifier>
+            </srv:SV_CoupledResource>
+          </srv:coupledResource>
+          <srv:coupledResource>
+            <srv:SV_CoupledResource>
+              <srv:operationName>
+                <gco:CharacterString>GetMap</gco:CharacterString>
+              </srv:operationName>
+              <srv:identifier>
+                <gco:CharacterString>LakesTSI_0305</gco:CharacterString>
+              </srv:identifier>
+            </srv:SV_CoupledResource>
+          </srv:coupledResource>
+          <srv:coupledResource>
+            <srv:SV_CoupledResource>
+              <srv:operationName>
+                <gco:CharacterString>GetMap</gco:CharacterString>
+              </srv:operationName>
+              <srv:identifier>
+                <gco:CharacterString>Relief</gco:CharacterString>
+              </srv:identifier>
+            </srv:SV_CoupledResource>
+          </srv:coupledResource>
+          <srv:coupledResource>
+            <srv:SV_CoupledResource>
+              <srv:operationName>
+                <gco:CharacterString>GetMap</gco:CharacterString>
+              </srv:operationName>
+              <srv:identifier>
+                <gco:CharacterString>LakeNames_0305</gco:CharacterString>
+              </srv:identifier>
+            </srv:SV_CoupledResource>
+          </srv:coupledResource>
+          <srv:coupledResource>
+            <srv:SV_CoupledResource>
+              <srv:operationName>
+                <gco:CharacterString>GetMap</gco:CharacterString>
+              </srv:operationName>
+              <srv:identifier>
+                <gco:CharacterString>Roads</gco:CharacterString>
+              </srv:identifier>
+            </srv:SV_CoupledResource>
+          </srv:coupledResource>
+          <srv:coupledResource>
+            <srv:SV_CoupledResource>
+              <srv:operationName>
+                <gco:CharacterString>GetMap</gco:CharacterString>
+              </srv:operationName>
+              <srv:identifier>
+                <gco:CharacterString>LakeNames</gco:CharacterString>
+              </srv:identifier>
+            </srv:SV_CoupledResource>
+          </srv:coupledResource>
+          <srv:coupledResource>
+            <srv:SV_CoupledResource>
+              <srv:operationName>
+                <gco:CharacterString>GetMap</gco:CharacterString>
+              </srv:operationName>
+              <srv:identifier>
+                <gco:CharacterString>Counties</gco:CharacterString>
+              </srv:identifier>
+            </srv:SV_CoupledResource>
+          </srv:coupledResource>
+          <srv:containsOperations>
+            <srv:SV_OperationMetadata>
+              <srv:operationName>
+                <gco:CharacterString>GetCapabilities</gco:CharacterString>
+              </srv:operationName>
+              <srv:DCP>
+                <srv:DCPList codeList="http://www.isotc211.org/2005/resources/Codelist/gmxCodelists.xml#DCPList" codeListValue="HTTPGet">HTTPGet</srv:DCPList>
+              </srv:DCP>
+              <srv:DCP>
+                <srv:DCPList codeList="http://www.isotc211.org/2005/resources/Codelist/gmxCodelists.xml#DCPList" codeListValue="HTTPPost">HTTPPost</srv:DCPList>
+              </srv:DCP>
+              <srv:connectPoint>
+                <gmd:CI_OnlineResource>
+                  <gmd:linkage>
+                    <gmd:URL>http://wms.ssec.wisc.edu/cgi-bin/mapserv?map=/home/wms/data/mapfiles/lakestsi.map</gmd:URL>
+                  </gmd:linkage>
+                </gmd:CI_OnlineResource>
+              </srv:connectPoint>
+            </srv:SV_OperationMetadata>
+          </srv:containsOperations>
+          <srv:containsOperations>
+            <srv:SV_OperationMetadata>
+              <srv:operationName>
+                <gco:CharacterString>GetMap</gco:CharacterString>
+              </srv:operationName>
+              <srv:DCP>
+                <srv:DCPList codeList="http://www.isotc211.org/2005/resources/Codelist/gmxCodelists.xml#DCPList" codeListValue="HTTPGet">HTTPGet</srv:DCPList>
+              </srv:DCP>
+              <srv:DCP>
+                <srv:DCPList codeList="http://www.isotc211.org/2005/resources/Codelist/gmxCodelists.xml#DCPList" codeListValue="HTTPPost">HTTPPost</srv:DCPList>
+              </srv:DCP>
+              <srv:connectPoint>
+                <gmd:CI_OnlineResource>
+                  <gmd:linkage>
+                    <gmd:URL>http://wms.ssec.wisc.edu/cgi-bin/mapserv?map=/home/wms/data/mapfiles/lakestsi.map</gmd:URL>
+                  </gmd:linkage>
+                </gmd:CI_OnlineResource>
+              </srv:connectPoint>
+            </srv:SV_OperationMetadata>
+          </srv:containsOperations>
+          <srv:containsOperations>
+            <srv:SV_OperationMetadata>
+              <srv:operationName>
+                <gco:CharacterString>GetFeatureInfo</gco:CharacterString>
+              </srv:operationName>
+              <srv:DCP>
+                <srv:DCPList codeList="http://www.isotc211.org/2005/resources/Codelist/gmxCodelists.xml#DCPList" codeListValue="HTTPGet">HTTPGet</srv:DCPList>
+              </srv:DCP>
+              <srv:DCP>
+                <srv:DCPList codeList="http://www.isotc211.org/2005/resources/Codelist/gmxCodelists.xml#DCPList" codeListValue="HTTPPost">HTTPPost</srv:DCPList>
+              </srv:DCP>
+              <srv:connectPoint>
+                <gmd:CI_OnlineResource>
+                  <gmd:linkage>
+                    <gmd:URL>http://wms.ssec.wisc.edu/cgi-bin/mapserv?map=/home/wms/data/mapfiles/lakestsi.map</gmd:URL>
+                  </gmd:linkage>
+                </gmd:CI_OnlineResource>
+              </srv:connectPoint>
+            </srv:SV_OperationMetadata>
+          </srv:containsOperations>
+          <srv:operatesOn uuidref="Highways" xlink:href="http://demo.pycsw.org/services/csw?service=CSW&version=2.0.2&request=GetRecordById&outputschema=http://www.isotc211.org/2005/gmd&id=PYCSW_IDENTIFIER-Highways"/>
+          <srv:operatesOn uuidref="LakesTSI" xlink:href="http://demo.pycsw.org/services/csw?service=CSW&version=2.0.2&request=GetRecordById&outputschema=http://www.isotc211.org/2005/gmd&id=PYCSW_IDENTIFIER-LakesTSI"/>
+          <srv:operatesOn uuidref="LakeClarity" xlink:href="http://demo.pycsw.org/services/csw?service=CSW&version=2.0.2&request=GetRecordById&outputschema=http://www.isotc211.org/2005/gmd&id=PYCSW_IDENTIFIER-LakeClarity"/>
+          <srv:operatesOn uuidref="LakesTSI_0305" xlink:href="http://demo.pycsw.org/services/csw?service=CSW&version=2.0.2&request=GetRecordById&outputschema=http://www.isotc211.org/2005/gmd&id=PYCSW_IDENTIFIER-LakesTSI_0305"/>
+          <srv:operatesOn uuidref="Relief" xlink:href="http://demo.pycsw.org/services/csw?service=CSW&version=2.0.2&request=GetRecordById&outputschema=http://www.isotc211.org/2005/gmd&id=PYCSW_IDENTIFIER-Relief"/>
+          <srv:operatesOn uuidref="LakeNames_0305" xlink:href="http://demo.pycsw.org/services/csw?service=CSW&version=2.0.2&request=GetRecordById&outputschema=http://www.isotc211.org/2005/gmd&id=PYCSW_IDENTIFIER-LakeNames_0305"/>
+          <srv:operatesOn uuidref="Roads" xlink:href="http://demo.pycsw.org/services/csw?service=CSW&version=2.0.2&request=GetRecordById&outputschema=http://www.isotc211.org/2005/gmd&id=PYCSW_IDENTIFIER-Roads"/>
+          <srv:operatesOn uuidref="LakeNames" xlink:href="http://demo.pycsw.org/services/csw?service=CSW&version=2.0.2&request=GetRecordById&outputschema=http://www.isotc211.org/2005/gmd&id=PYCSW_IDENTIFIER-LakeNames"/>
+          <srv:operatesOn uuidref="Counties" xlink:href="http://demo.pycsw.org/services/csw?service=CSW&version=2.0.2&request=GetRecordById&outputschema=http://www.isotc211.org/2005/gmd&id=PYCSW_IDENTIFIER-Counties"/>
+        </srv:SV_ServiceIdentification>
+      </gmd:identificationInfo>
+      <gmd:distributionInfo>
+        <gmd:MD_Distribution>
+          <gmd:transferOptions>
+            <gmd:MD_DigitalTransferOptions>
+              <gmd:onLine>
+                <gmd:CI_OnlineResource>
+                  <gmd:linkage>
+                    <gmd:URL>http://wms.ssec.wisc.edu/cgi-bin/mapserv?map=/home/wms/data/mapfiles/lakestsi.map</gmd:URL>
+                  </gmd:linkage>
+                  <gmd:protocol>
+                    <gco:CharacterString>OGC:WMS</gco:CharacterString>
+                  </gmd:protocol>
+                  <gmd:name>
+                    <gco:CharacterString>PYCSW_IDENTIFIER</gco:CharacterString>
+                  </gmd:name>
+                  <gmd:description>
+                    <gco:CharacterString>OGC-WMS Web Map Service</gco:CharacterString>
+                  </gmd:description>
+                </gmd:CI_OnlineResource>
+              </gmd:onLine>
+              <gmd:onLine>
+                <gmd:CI_OnlineResource>
+                  <gmd:linkage>
+                    <gmd:URL>http://wms.ssec.wisc.edu/cgi-bin/mapserv?map=%2Fhome%2Fwms%2Fdata%2Fmapfiles%2Flakestsi.map&version=1.1.1&request=GetCapabilities&service=WMS</gmd:URL>
+                  </gmd:linkage>
+                  <gmd:protocol>
+                    <gco:CharacterString>OGC:WMS-1.1.1-http-get-capabilities</gco:CharacterString>
+                  </gmd:protocol>
+                  <gmd:name>
+                    <gco:CharacterString>PYCSW_IDENTIFIER</gco:CharacterString>
+                  </gmd:name>
+                  <gmd:description>
+                    <gco:CharacterString>OGC-WMS Capabilities service (ver 1.1.1)</gco:CharacterString>
+                  </gmd:description>
+                </gmd:CI_OnlineResource>
+              </gmd:onLine>
+            </gmd:MD_DigitalTransferOptions>
+          </gmd:transferOptions>
+        </gmd:MD_Distribution>
+      </gmd:distributionInfo>
+    </gmd:MD_Metadata>
+    <gmd:MD_Metadata xsi:schemaLocation="http://www.isotc211.org/2005/gmd http://schemas.opengis.net/csw/2.0.2/profiles/apiso/1.0.0/apiso.xsd">
+      <gmd:fileIdentifier>
+        <gco:CharacterString>PYCSW_IDENTIFIER</gco:CharacterString>
+      </gmd:fileIdentifier>
+      <gmd:language>
+        <gco:CharacterString/>
+      </gmd:language>
+      <gmd:hierarchyLevel>
+        <gmd:MD_ScopeCode codeList="http://www.isotc211.org/2005/resources/Codelist/gmxCodelists.xml#MD_ScopeCode" codeListValue="service" codeSpace="ISOTC211/19115">service</gmd:MD_ScopeCode>
+      </gmd:hierarchyLevel>
+      <gmd:contact>
+        <gmd:CI_ResponsibleParty>
+          <gmd:organisationName>
+            <gco:CharacterString>Stephan Meissl</gco:CharacterString>
+          </gmd:organisationName>
+        </gmd:CI_ResponsibleParty>
+      </gmd:contact>
+      <gmd:dateStamp>
+        <gco:Date/>
+      </gmd:dateStamp>
+      <gmd:metadataStandardName>
+        <gco:CharacterString>ISO19119</gco:CharacterString>
+      </gmd:metadataStandardName>
+      <gmd:metadataStandardVersion>
+        <gco:CharacterString>2005/PDAM 1</gco:CharacterString>
+      </gmd:metadataStandardVersion>
+      <gmd:identificationInfo>
+        <srv:SV_ServiceIdentification id="PYCSW_IDENTIFIER">
+          <gmd:citation>
+            <gmd:CI_Citation>
+              <gmd:title>
+                <gco:CharacterString>View & download service for EU-DEM data provided by EOX</gco:CharacterString>
+              </gmd:title>
+            </gmd:CI_Citation>
+          </gmd:citation>
+          <gmd:abstract>
+            <gco:CharacterString>Produced using Copernicus data and information funded by the European Union - EU-DEM layers.</gco:CharacterString>
+          </gmd:abstract>
+          <gmd:descriptiveKeywords>
+            <gmd:MD_Keywords>
+              <gmd:keyword>
+                <gco:CharacterString>EU-DEM</gco:CharacterString>
+              </gmd:keyword>
+            </gmd:MD_Keywords>
+          </gmd:descriptiveKeywords>
+          <gmd:language>
+            <gco:CharacterString/>
+          </gmd:language>
+          <srv:serviceType>
+            <gco:LocalName>OGC:WMS</gco:LocalName>
+          </srv:serviceType>
+          <srv:serviceTypeVersion>
+            <gco:CharacterString>1.1.1</gco:CharacterString>
+          </srv:serviceTypeVersion>
+          <srv:keywords>
+            <gmd:MD_Keywords>
+              <gmd:keyword>
+                <gco:CharacterString>EU-DEM</gco:CharacterString>
+              </gmd:keyword>
+            </gmd:MD_Keywords>
+          </srv:keywords>
+          <srv:extent>
+            <gmd:EX_Extent>
+              <gmd:geographicElement>
+                <gmd:EX_GeographicBoundingBox>
+                  <gmd:westBoundLongitude>
+                    <gco:Decimal>-29.09</gco:Decimal>
+                  </gmd:westBoundLongitude>
+                  <gmd:eastBoundLongitude>
+                    <gco:Decimal>-29.09</gco:Decimal>
+                  </gmd:eastBoundLongitude>
+                  <gmd:southBoundLatitude>
+                    <gco:Decimal>12.99</gco:Decimal>
+                  </gmd:southBoundLatitude>
+                  <gmd:northBoundLatitude>
+                    <gco:Decimal>12.99</gco:Decimal>
+                  </gmd:northBoundLatitude>
+                </gmd:EX_GeographicBoundingBox>
+              </gmd:geographicElement>
+            </gmd:EX_Extent>
+          </srv:extent>
+          <srv:couplingType>
+            <srv:SV_CouplingType codeList="http://www.isotc211.org/2005/resources/Codelist/gmxCodelists.xml#SV_CouplingType" codeListValue="tight">tight</srv:SV_CouplingType>
+          </srv:couplingType>
+          <srv:coupledResource>
+            <srv:SV_CoupledResource>
+              <srv:operationName>
+                <gco:CharacterString>GetMap</gco:CharacterString>
+              </srv:operationName>
+              <srv:identifier>
+                <gco:CharacterString>EU-DEM</gco:CharacterString>
+              </srv:identifier>
+            </srv:SV_CoupledResource>
+          </srv:coupledResource>
+          <srv:coupledResource>
+            <srv:SV_CoupledResource>
+              <srv:operationName>
+                <gco:CharacterString>GetMap</gco:CharacterString>
+              </srv:operationName>
+              <srv:identifier>
+                <gco:CharacterString>MS</gco:CharacterString>
+              </srv:identifier>
+            </srv:SV_CoupledResource>
+          </srv:coupledResource>
+          <srv:coupledResource>
+            <srv:SV_CoupledResource>
+              <srv:operationName>
+                <gco:CharacterString>GetMap</gco:CharacterString>
+              </srv:operationName>
+              <srv:identifier>
+                <gco:CharacterString>eudem_color</gco:CharacterString>
+              </srv:identifier>
+            </srv:SV_CoupledResource>
+          </srv:coupledResource>
+          <srv:containsOperations>
+            <srv:SV_OperationMetadata>
+              <srv:operationName>
+                <gco:CharacterString>GetCapabilities</gco:CharacterString>
+              </srv:operationName>
+              <srv:DCP>
+                <srv:DCPList codeList="http://www.isotc211.org/2005/resources/Codelist/gmxCodelists.xml#DCPList" codeListValue="HTTPGet">HTTPGet</srv:DCPList>
+              </srv:DCP>
+              <srv:DCP>
+                <srv:DCPList codeList="http://www.isotc211.org/2005/resources/Codelist/gmxCodelists.xml#DCPList" codeListValue="HTTPPost">HTTPPost</srv:DCPList>
+              </srv:DCP>
+              <srv:connectPoint>
+                <gmd:CI_OnlineResource>
+                  <gmd:linkage>
+                    <gmd:URL>http://data.eox.at/eudem_ows</gmd:URL>
+                  </gmd:linkage>
+                </gmd:CI_OnlineResource>
+              </srv:connectPoint>
+            </srv:SV_OperationMetadata>
+          </srv:containsOperations>
+          <srv:containsOperations>
+            <srv:SV_OperationMetadata>
+              <srv:operationName>
+                <gco:CharacterString>GetMap</gco:CharacterString>
+              </srv:operationName>
+              <srv:DCP>
+                <srv:DCPList codeList="http://www.isotc211.org/2005/resources/Codelist/gmxCodelists.xml#DCPList" codeListValue="HTTPGet">HTTPGet</srv:DCPList>
+              </srv:DCP>
+              <srv:DCP>
+                <srv:DCPList codeList="http://www.isotc211.org/2005/resources/Codelist/gmxCodelists.xml#DCPList" codeListValue="HTTPPost">HTTPPost</srv:DCPList>
+              </srv:DCP>
+              <srv:connectPoint>
+                <gmd:CI_OnlineResource>
+                  <gmd:linkage>
+                    <gmd:URL>http://data.eox.at/eudem_ows</gmd:URL>
+                  </gmd:linkage>
+                </gmd:CI_OnlineResource>
+              </srv:connectPoint>
+            </srv:SV_OperationMetadata>
+          </srv:containsOperations>
+          <srv:containsOperations>
+            <srv:SV_OperationMetadata>
+              <srv:operationName>
+                <gco:CharacterString>GetFeatureInfo</gco:CharacterString>
+              </srv:operationName>
+              <srv:DCP>
+                <srv:DCPList codeList="http://www.isotc211.org/2005/resources/Codelist/gmxCodelists.xml#DCPList" codeListValue="HTTPGet">HTTPGet</srv:DCPList>
+              </srv:DCP>
+              <srv:DCP>
+                <srv:DCPList codeList="http://www.isotc211.org/2005/resources/Codelist/gmxCodelists.xml#DCPList" codeListValue="HTTPPost">HTTPPost</srv:DCPList>
+              </srv:DCP>
+              <srv:connectPoint>
+                <gmd:CI_OnlineResource>
+                  <gmd:linkage>
+                    <gmd:URL>http://data.eox.at/eudem_ows</gmd:URL>
+                  </gmd:linkage>
+                </gmd:CI_OnlineResource>
+              </srv:connectPoint>
+            </srv:SV_OperationMetadata>
+          </srv:containsOperations>
+          <srv:containsOperations>
+            <srv:SV_OperationMetadata>
+              <srv:operationName>
+                <gco:CharacterString>DescribeLayer</gco:CharacterString>
+              </srv:operationName>
+              <srv:DCP>
+                <srv:DCPList codeList="http://www.isotc211.org/2005/resources/Codelist/gmxCodelists.xml#DCPList" codeListValue="HTTPGet">HTTPGet</srv:DCPList>
+              </srv:DCP>
+              <srv:DCP>
+                <srv:DCPList codeList="http://www.isotc211.org/2005/resources/Codelist/gmxCodelists.xml#DCPList" codeListValue="HTTPPost">HTTPPost</srv:DCPList>
+              </srv:DCP>
+              <srv:connectPoint>
+                <gmd:CI_OnlineResource>
+                  <gmd:linkage>
+                    <gmd:URL>http://data.eox.at/eudem_ows</gmd:URL>
+                  </gmd:linkage>
+                </gmd:CI_OnlineResource>
+              </srv:connectPoint>
+            </srv:SV_OperationMetadata>
+          </srv:containsOperations>
+          <srv:containsOperations>
+            <srv:SV_OperationMetadata>
+              <srv:operationName>
+                <gco:CharacterString>GetLegendGraphic</gco:CharacterString>
+              </srv:operationName>
+              <srv:DCP>
+                <srv:DCPList codeList="http://www.isotc211.org/2005/resources/Codelist/gmxCodelists.xml#DCPList" codeListValue="HTTPGet">HTTPGet</srv:DCPList>
+              </srv:DCP>
+              <srv:DCP>
+                <srv:DCPList codeList="http://www.isotc211.org/2005/resources/Codelist/gmxCodelists.xml#DCPList" codeListValue="HTTPPost">HTTPPost</srv:DCPList>
+              </srv:DCP>
+              <srv:connectPoint>
+                <gmd:CI_OnlineResource>
+                  <gmd:linkage>
+                    <gmd:URL>http://data.eox.at/eudem_ows</gmd:URL>
+                  </gmd:linkage>
+                </gmd:CI_OnlineResource>
+              </srv:connectPoint>
+            </srv:SV_OperationMetadata>
+          </srv:containsOperations>
+          <srv:containsOperations>
+            <srv:SV_OperationMetadata>
+              <srv:operationName>
+                <gco:CharacterString>GetStyles</gco:CharacterString>
+              </srv:operationName>
+              <srv:DCP>
+                <srv:DCPList codeList="http://www.isotc211.org/2005/resources/Codelist/gmxCodelists.xml#DCPList" codeListValue="HTTPGet">HTTPGet</srv:DCPList>
+              </srv:DCP>
+              <srv:DCP>
+                <srv:DCPList codeList="http://www.isotc211.org/2005/resources/Codelist/gmxCodelists.xml#DCPList" codeListValue="HTTPPost">HTTPPost</srv:DCPList>
+              </srv:DCP>
+              <srv:connectPoint>
+                <gmd:CI_OnlineResource>
+                  <gmd:linkage>
+                    <gmd:URL>http://data.eox.at/eudem_ows</gmd:URL>
+                  </gmd:linkage>
+                </gmd:CI_OnlineResource>
+              </srv:connectPoint>
+            </srv:SV_OperationMetadata>
+          </srv:containsOperations>
+          <srv:operatesOn uuidref="EU-DEM" xlink:href="http://demo.pycsw.org/services/csw?service=CSW&version=2.0.2&request=GetRecordById&outputschema=http://www.isotc211.org/2005/gmd&id=PYCSW_IDENTIFIER-EU-DEM"/>
+          <srv:operatesOn uuidref="MS" xlink:href="http://demo.pycsw.org/services/csw?service=CSW&version=2.0.2&request=GetRecordById&outputschema=http://www.isotc211.org/2005/gmd&id=PYCSW_IDENTIFIER-MS"/>
+          <srv:operatesOn uuidref="eudem_color" xlink:href="http://demo.pycsw.org/services/csw?service=CSW&version=2.0.2&request=GetRecordById&outputschema=http://www.isotc211.org/2005/gmd&id=PYCSW_IDENTIFIER-eudem_color"/>
+        </srv:SV_ServiceIdentification>
+      </gmd:identificationInfo>
+      <gmd:distributionInfo>
+        <gmd:MD_Distribution>
+          <gmd:transferOptions>
+            <gmd:MD_DigitalTransferOptions>
+              <gmd:onLine>
+                <gmd:CI_OnlineResource>
+                  <gmd:linkage>
+                    <gmd:URL>http://data.eox.at/eudem_ows</gmd:URL>
+                  </gmd:linkage>
+                  <gmd:protocol>
+                    <gco:CharacterString>OGC:WMS</gco:CharacterString>
+                  </gmd:protocol>
+                  <gmd:name>
+                    <gco:CharacterString>PYCSW_IDENTIFIER</gco:CharacterString>
+                  </gmd:name>
+                  <gmd:description>
+                    <gco:CharacterString>OGC-WMS Web Map Service</gco:CharacterString>
+                  </gmd:description>
+                </gmd:CI_OnlineResource>
+              </gmd:onLine>
+              <gmd:onLine>
+                <gmd:CI_OnlineResource>
+                  <gmd:linkage>
+                    <gmd:URL>http://data.eox.at/eudem_ows?version=1.1.1&request=GetCapabilities&service=WMS</gmd:URL>
+                  </gmd:linkage>
+                  <gmd:protocol>
+                    <gco:CharacterString>OGC:WMS-1.1.1-http-get-capabilities</gco:CharacterString>
+                  </gmd:protocol>
+                  <gmd:name>
+                    <gco:CharacterString>PYCSW_IDENTIFIER</gco:CharacterString>
+                  </gmd:name>
+                  <gmd:description>
+                    <gco:CharacterString>OGC-WMS Capabilities service (ver 1.1.1)</gco:CharacterString>
+                  </gmd:description>
+                </gmd:CI_OnlineResource>
+              </gmd:onLine>
+            </gmd:MD_DigitalTransferOptions>
+          </gmd:transferOptions>
+        </gmd:MD_Distribution>
+      </gmd:distributionInfo>
+    </gmd:MD_Metadata>
     <gmd:MD_Metadata xsi:schemaLocation="http://www.isotc211.org/2005/gmd http://schemas.opengis.net/csw/2.0.2/profiles/apiso/1.0.0/apiso.xsd">
       <gmd:fileIdentifier>
         <gco:CharacterString>PYCSW_IDENTIFIER</gco:CharacterString>
@@ -130,7 +1183,7 @@
                 <gco:CharacterString>GetMap</gco:CharacterString>
               </srv:operationName>
               <srv:identifier>
-                <gco:CharacterString>time_idx</gco:CharacterString>
+                <gco:CharacterString>nexrad_base_reflect</gco:CharacterString>
               </srv:identifier>
             </srv:SV_CoupledResource>
           </srv:coupledResource>
@@ -140,7 +1193,7 @@
                 <gco:CharacterString>GetMap</gco:CharacterString>
               </srv:operationName>
               <srv:identifier>
-                <gco:CharacterString>nexrad-n0r-wmst</gco:CharacterString>
+                <gco:CharacterString>time_idx</gco:CharacterString>
               </srv:identifier>
             </srv:SV_CoupledResource>
           </srv:coupledResource>
@@ -150,7 +1203,7 @@
                 <gco:CharacterString>GetMap</gco:CharacterString>
               </srv:operationName>
               <srv:identifier>
-                <gco:CharacterString>nexrad_base_reflect</gco:CharacterString>
+                <gco:CharacterString>nexrad-n0r-wmst</gco:CharacterString>
               </srv:identifier>
             </srv:SV_CoupledResource>
           </srv:coupledResource>
@@ -274,9 +1327,9 @@
               </srv:connectPoint>
             </srv:SV_OperationMetadata>
           </srv:containsOperations>
+          <srv:operatesOn uuidref="nexrad_base_reflect" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/harvesting/default.cfg&service=CSW&version=2.0.2&request=GetRecordById&outputschema=http://www.isotc211.org/2005/gmd&id=PYCSW_IDENTIFIER-nexrad_base_reflect"/>
           <srv:operatesOn uuidref="time_idx" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/harvesting/default.cfg&service=CSW&version=2.0.2&request=GetRecordById&outputschema=http://www.isotc211.org/2005/gmd&id=PYCSW_IDENTIFIER-time_idx"/>
           <srv:operatesOn uuidref="nexrad-n0r-wmst" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/harvesting/default.cfg&service=CSW&version=2.0.2&request=GetRecordById&outputschema=http://www.isotc211.org/2005/gmd&id=PYCSW_IDENTIFIER-nexrad-n0r-wmst"/>
-          <srv:operatesOn uuidref="nexrad_base_reflect" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/harvesting/default.cfg&service=CSW&version=2.0.2&request=GetRecordById&outputschema=http://www.isotc211.org/2005/gmd&id=PYCSW_IDENTIFIER-nexrad_base_reflect"/>
         </srv:SV_ServiceIdentification>
       </gmd:identificationInfo>
       <gmd:distributionInfo>
diff --git a/tests/expected/suites_harvesting_post_Harvest-zzz-post-GetRecords-filter-wms-layer.xml b/tests/expected/suites_harvesting_post_Harvest-zzz-post-GetRecords-filter-wms-layer.xml
index 478c621..1bc09e7 100644
--- a/tests/expected/suites_harvesting_post_Harvest-zzz-post-GetRecords-filter-wms-layer.xml
+++ b/tests/expected/suites_harvesting_post_Harvest-zzz-post-GetRecords-filter-wms-layer.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<csw:GetRecordsResponse xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:inspire_common="http://inspire.ec.europa.eu/schemas/common/1.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dct="http://purl.org/dc/terms/" xmlns:ows="http://www.opengis.net/ows" xmlns:apiso="http://www.opengis.net/cat/csw/apiso/1.0" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xlink="http://www.w3.org/1999/xlink"  [...]
+<csw:GetRecordsResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.0.2" xsi:schemaLocation="http://www.opengis.net/cat/csw/2.0.2 http://schemas.opengis.net/csw/2.0.2/CSW-di [...]
   <csw:SearchStatus timestamp="PYCSW_TIMESTAMP"/>
   <csw:SearchResults nextRecord="0" numberOfRecordsMatched="2" numberOfRecordsReturned="2" recordSchema="http://www.opengis.net/cat/csw/2.0.2" elementSet="full">
     <csw:Record>
diff --git a/tests/expected/suites_harvesting_post_Transaction-000-delete-all.xml b/tests/expected/suites_harvesting_post_Transaction-000-delete-all.xml
index 866312a..53f45a6 100644
--- a/tests/expected/suites_harvesting_post_Transaction-000-delete-all.xml
+++ b/tests/expected/suites_harvesting_post_Transaction-000-delete-all.xml
@@ -1,9 +1,9 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<csw:TransactionResponse xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:inspire_common="http://inspire.ec.europa.eu/schemas/common/1.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dct="http://purl.org/dc/terms/" xmlns:ows="http://www.opengis.net/ows" xmlns:apiso="http://www.opengis.net/cat/csw/apiso/1.0" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xlink="http://www.w3.org/1999/xlink" [...]
+<csw:TransactionResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.0.2" xsi:schemaLocation="http://www.opengis.net/cat/csw/2.0.2 http://schemas.opengis.net/csw/2.0.2/CSW-p [...]
   <csw:TransactionSummary>
     <csw:totalInserted>0</csw:totalInserted>
     <csw:totalUpdated>0</csw:totalUpdated>
-    <csw:totalDeleted>108</csw:totalDeleted>
+    <csw:totalDeleted>276</csw:totalDeleted>
   </csw:TransactionSummary>
 </csw:TransactionResponse>
diff --git a/tests/expected/suites_manager_post_Clear-000-delete-all.xml b/tests/expected/suites_manager_post_Clear-000-delete-all.xml
index 381db66..01ccdf6 100644
--- a/tests/expected/suites_manager_post_Clear-000-delete-all.xml
+++ b/tests/expected/suites_manager_post_Clear-000-delete-all.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<csw:TransactionResponse xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:inspire_common="http://inspire.ec.europa.eu/schemas/common/1.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dct="http://purl.org/dc/terms/" xmlns:ows="http://www.opengis.net/ows" xmlns:apiso="http://www.opengis.net/cat/csw/apiso/1.0" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xlink="http://www.w3.org/1999/xlink" [...]
+<csw:TransactionResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.0.2" xsi:schemaLocation="http://www.opengis.net/cat/csw/2.0.2 http://schemas.opengis.net/csw/2.0.2/CSW-p [...]
   <csw:TransactionSummary>
     <csw:totalInserted>0</csw:totalInserted>
     <csw:totalUpdated>0</csw:totalUpdated>
diff --git a/tests/expected/suites_manager_post_GetCapabilities.xml b/tests/expected/suites_manager_post_GetCapabilities.xml
index 4bdcaec..02d588e 100644
--- a/tests/expected/suites_manager_post_GetCapabilities.xml
+++ b/tests/expected/suites_manager_post_GetCapabilities.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<csw:Capabilities xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:inspire_common="http://inspire.ec.europa.eu/schemas/common/1.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dct="http://purl.org/dc/terms/" xmlns:ows="http://www.opengis.net/ows" xmlns:apiso="http://www.opengis.net/cat/csw/apiso/1.0" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns: [...]
+<csw:Capabilities xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ogc="http://www.opengis.net/ogc" xmlns:ows="http://www.opengis.net/ows" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" updateSequence="PYCSW_UPDATESEQUENCE" ve [...]
   <ows:ServiceIdentification>
     <ows:Title>pycsw Geospatial Catalogue</ows:Title>
     <ows:Abstract>pycsw is an OGC CSW server implementation written in Python</ows:Abstract>
@@ -11,6 +11,7 @@
     </ows:Keywords>
     <ows:ServiceType codeSpace="OGC">CSW</ows:ServiceType>
     <ows:ServiceTypeVersion>2.0.2</ows:ServiceTypeVersion>
+    <ows:ServiceTypeVersion>3.0.0</ows:ServiceTypeVersion>
     <ows:Fees>None</ows:Fees>
     <ows:AccessConstraints>None</ows:AccessConstraints>
   </ows:ServiceIdentification>
@@ -49,26 +50,12 @@
         </ows:HTTP>
       </ows:DCP>
       <ows:Parameter name="sections">
+        <ows:Value>Filter_Capabilities</ows:Value>
+        <ows:Value>OperationsMetadata</ows:Value>
         <ows:Value>ServiceIdentification</ows:Value>
         <ows:Value>ServiceProvider</ows:Value>
-        <ows:Value>OperationsMetadata</ows:Value>
-        <ows:Value>Filter_Capabilities</ows:Value>
       </ows:Parameter>
     </ows:Operation>
-    <ows:Operation name="Transaction">
-      <ows:DCP>
-        <ows:HTTP>
-          <ows:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/manager/default.cfg"/>
-        </ows:HTTP>
-      </ows:DCP>
-    </ows:Operation>
-    <ows:Operation name="GetRepositoryItem">
-      <ows:DCP>
-        <ows:HTTP>
-          <ows:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/manager/default.cfg"/>
-        </ows:HTTP>
-      </ows:DCP>
-    </ows:Operation>
     <ows:Operation name="DescribeRecord">
       <ows:DCP>
         <ows:HTTP>
@@ -76,14 +63,14 @@
           <ows:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/manager/default.cfg"/>
         </ows:HTTP>
       </ows:DCP>
-      <ows:Parameter name="schemaLanguage">
-        <ows:Value>http://www.w3.org/XML/Schema</ows:Value>
-        <ows:Value>http://www.w3.org/TR/xmlschema-1/</ows:Value>
-        <ows:Value>http://www.w3.org/2001/XMLSchema</ows:Value>
-      </ows:Parameter>
       <ows:Parameter name="outputFormat">
-        <ows:Value>application/xml</ows:Value>
         <ows:Value>application/json</ows:Value>
+        <ows:Value>application/xml</ows:Value>
+      </ows:Parameter>
+      <ows:Parameter name="schemaLanguage">
+        <ows:Value>http://www.w3.org/2001/XMLSchema</ows:Value>
+        <ows:Value>http://www.w3.org/TR/xmlschema-1/</ows:Value>
+        <ows:Value>http://www.w3.org/XML/Schema</ows:Value>
       </ows:Parameter>
       <ows:Parameter name="typeName">
         <ows:Value>csw:Record</ows:Value>
@@ -98,67 +85,50 @@
         </ows:HTTP>
       </ows:DCP>
       <ows:Parameter name="ParameterName">
-        <ows:Value>GetCapabilities.sections</ows:Value>
-        <ows:Value>DescribeRecord.schemaLanguage</ows:Value>
         <ows:Value>DescribeRecord.outputFormat</ows:Value>
+        <ows:Value>DescribeRecord.schemaLanguage</ows:Value>
         <ows:Value>DescribeRecord.typeName</ows:Value>
+        <ows:Value>GetCapabilities.sections</ows:Value>
+        <ows:Value>GetRecordById.ElementSetName</ows:Value>
         <ows:Value>GetRecordById.outputFormat</ows:Value>
         <ows:Value>GetRecordById.outputSchema</ows:Value>
-        <ows:Value>GetRecordById.ElementSetName</ows:Value>
+        <ows:Value>GetRecords.CONSTRAINTLANGUAGE</ows:Value>
+        <ows:Value>GetRecords.ElementSetName</ows:Value>
         <ows:Value>GetRecords.outputFormat</ows:Value>
         <ows:Value>GetRecords.outputSchema</ows:Value>
-        <ows:Value>GetRecords.CONSTRAINTLANGUAGE</ows:Value>
         <ows:Value>GetRecords.resultType</ows:Value>
         <ows:Value>GetRecords.typeNames</ows:Value>
-        <ows:Value>GetRecords.ElementSetName</ows:Value>
         <ows:Value>Harvest.ResourceType</ows:Value>
+        <ows:Value>Transaction.TransactionSchemas</ows:Value>
       </ows:Parameter>
     </ows:Operation>
-    <ows:Operation name="GetRecordById">
+    <ows:Operation name="GetRecords">
       <ows:DCP>
         <ows:HTTP>
           <ows:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/manager/default.cfg"/>
           <ows:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/manager/default.cfg"/>
         </ows:HTTP>
       </ows:DCP>
-      <ows:Parameter name="outputFormat">
-        <ows:Value>application/xml</ows:Value>
-        <ows:Value>application/json</ows:Value>
-      </ows:Parameter>
-      <ows:Parameter name="outputSchema">
-        <ows:Value>http://www.opengis.net/cat/csw/2.0.2</ows:Value>
-        <ows:Value>http://www.isotc211.org/2005/gmd</ows:Value>
-        <ows:Value>http://www.w3.org/2005/Atom</ows:Value>
-        <ows:Value>http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/</ows:Value>
-        <ows:Value>http://www.opengis.net/cat/csw/csdgm</ows:Value>
+      <ows:Parameter name="CONSTRAINTLANGUAGE">
+        <ows:Value>CQL_TEXT</ows:Value>
+        <ows:Value>FILTER</ows:Value>
       </ows:Parameter>
       <ows:Parameter name="ElementSetName">
         <ows:Value>brief</ows:Value>
-        <ows:Value>summary</ows:Value>
         <ows:Value>full</ows:Value>
+        <ows:Value>summary</ows:Value>
       </ows:Parameter>
-    </ows:Operation>
-    <ows:Operation name="GetRecords">
-      <ows:DCP>
-        <ows:HTTP>
-          <ows:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/manager/default.cfg"/>
-          <ows:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/manager/default.cfg"/>
-        </ows:HTTP>
-      </ows:DCP>
       <ows:Parameter name="outputFormat">
-        <ows:Value>application/xml</ows:Value>
         <ows:Value>application/json</ows:Value>
+        <ows:Value>application/xml</ows:Value>
       </ows:Parameter>
       <ows:Parameter name="outputSchema">
-        <ows:Value>http://www.opengis.net/cat/csw/2.0.2</ows:Value>
-        <ows:Value>http://www.isotc211.org/2005/gmd</ows:Value>
-        <ows:Value>http://www.w3.org/2005/Atom</ows:Value>
         <ows:Value>http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/</ows:Value>
+        <ows:Value>http://www.interlis.ch/INTERLIS2.3</ows:Value>
+        <ows:Value>http://www.isotc211.org/2005/gmd</ows:Value>
+        <ows:Value>http://www.opengis.net/cat/csw/2.0.2</ows:Value>
         <ows:Value>http://www.opengis.net/cat/csw/csdgm</ows:Value>
-      </ows:Parameter>
-      <ows:Parameter name="CONSTRAINTLANGUAGE">
-        <ows:Value>FILTER</ows:Value>
-        <ows:Value>CQL_TEXT</ows:Value>
+        <ows:Value>http://www.w3.org/2005/Atom</ows:Value>
       </ows:Parameter>
       <ows:Parameter name="resultType">
         <ows:Value>hits</ows:Value>
@@ -169,114 +139,165 @@
         <ows:Value>csw:Record</ows:Value>
         <ows:Value>gmd:MD_Metadata</ows:Value>
       </ows:Parameter>
-      <ows:Parameter name="ElementSetName">
-        <ows:Value>brief</ows:Value>
-        <ows:Value>summary</ows:Value>
-        <ows:Value>full</ows:Value>
-      </ows:Parameter>
-      <ows:Constraint name="SupportedISOQueryables">
-        <ows:Value>apiso:DistanceValue</ows:Value>
-        <ows:Value>apiso:Abstract</ows:Value>
-        <ows:Value>apiso:RevisionDate</ows:Value>
-        <ows:Value>apiso:Subject</ows:Value>
-        <ows:Value>apiso:KeywordType</ows:Value>
-        <ows:Value>apiso:Title</ows:Value>
-        <ows:Value>apiso:CRS</ows:Value>
-        <ows:Value>apiso:PublicationDate</ows:Value>
-        <ows:Value>apiso:Type</ows:Value>
-        <ows:Value>apiso:AlternateTitle</ows:Value>
-        <ows:Value>apiso:BoundingBox</ows:Value>
-        <ows:Value>apiso:AnyText</ows:Value>
-        <ows:Value>apiso:ParentIdentifier</ows:Value>
-        <ows:Value>apiso:Modified</ows:Value>
-        <ows:Value>apiso:Operation</ows:Value>
-        <ows:Value>apiso:Format</ows:Value>
-        <ows:Value>apiso:TempExtent_end</ows:Value>
-        <ows:Value>apiso:DistanceUOM</ows:Value>
-        <ows:Value>apiso:OrganisationName</ows:Value>
-        <ows:Value>apiso:ServiceType</ows:Value>
-        <ows:Value>apiso:TempExtent_begin</ows:Value>
-        <ows:Value>apiso:ResourceLanguage</ows:Value>
-        <ows:Value>apiso:ServiceTypeVersion</ows:Value>
-        <ows:Value>apiso:OperatesOn</ows:Value>
-        <ows:Value>apiso:Denominator</ows:Value>
-        <ows:Value>apiso:HasSecurityConstraints</ows:Value>
-        <ows:Value>apiso:OperatesOnIdentifier</ows:Value>
-        <ows:Value>apiso:GeographicDescriptionCode</ows:Value>
-        <ows:Value>apiso:Language</ows:Value>
-        <ows:Value>apiso:Identifier</ows:Value>
-        <ows:Value>apiso:OperatesOnName</ows:Value>
-        <ows:Value>apiso:TopicCategory</ows:Value>
-        <ows:Value>apiso:CreationDate</ows:Value>
-        <ows:Value>apiso:CouplingType</ows:Value>
-      </ows:Constraint>
       <ows:Constraint name="AdditionalQueryables">
-        <ows:Value>apiso:Lineage</ows:Value>
+        <ows:Value>apiso:AccessConstraints</ows:Value>
         <ows:Value>apiso:Classification</ows:Value>
+        <ows:Value>apiso:ConditionApplyingToAccessAndUse</ows:Value>
+        <ows:Value>apiso:Contributor</ows:Value>
         <ows:Value>apiso:Creator</ows:Value>
-        <ows:Value>apiso:Relation</ows:Value>
+        <ows:Value>apiso:Degree</ows:Value>
+        <ows:Value>apiso:Lineage</ows:Value>
         <ows:Value>apiso:OtherConstraints</ows:Value>
-        <ows:Value>apiso:SpecificationTitle</ows:Value>
+        <ows:Value>apiso:Publisher</ows:Value>
+        <ows:Value>apiso:Relation</ows:Value>
         <ows:Value>apiso:ResponsiblePartyRole</ows:Value>
-        <ows:Value>apiso:SpecificationDateType</ows:Value>
-        <ows:Value>apiso:Degree</ows:Value>
-        <ows:Value>apiso:Contributor</ows:Value>
-        <ows:Value>apiso:ConditionApplyingToAccessAndUse</ows:Value>
         <ows:Value>apiso:SpecificationDate</ows:Value>
-        <ows:Value>apiso:AccessConstraints</ows:Value>
-        <ows:Value>apiso:Publisher</ows:Value>
+        <ows:Value>apiso:SpecificationDateType</ows:Value>
+        <ows:Value>apiso:SpecificationTitle</ows:Value>
       </ows:Constraint>
       <ows:Constraint name="SupportedDublinCoreQueryables">
+        <ows:Value>csw:AnyText</ows:Value>
         <ows:Value>dc:contributor</ows:Value>
-        <ows:Value>dc:source</ows:Value>
-        <ows:Value>dc:language</ows:Value>
-        <ows:Value>dc:title</ows:Value>
-        <ows:Value>dc:subject</ows:Value>
         <ows:Value>dc:creator</ows:Value>
-        <ows:Value>dc:type</ows:Value>
-        <ows:Value>ows:BoundingBox</ows:Value>
-        <ows:Value>dct:modified</ows:Value>
-        <ows:Value>dct:abstract</ows:Value>
-        <ows:Value>dc:relation</ows:Value>
         <ows:Value>dc:date</ows:Value>
+        <ows:Value>dc:format</ows:Value>
         <ows:Value>dc:identifier</ows:Value>
+        <ows:Value>dc:language</ows:Value>
         <ows:Value>dc:publisher</ows:Value>
-        <ows:Value>dc:format</ows:Value>
-        <ows:Value>csw:AnyText</ows:Value>
+        <ows:Value>dc:relation</ows:Value>
         <ows:Value>dc:rights</ows:Value>
+        <ows:Value>dc:source</ows:Value>
+        <ows:Value>dc:subject</ows:Value>
+        <ows:Value>dc:title</ows:Value>
+        <ows:Value>dc:type</ows:Value>
+        <ows:Value>dct:abstract</ows:Value>
+        <ows:Value>dct:modified</ows:Value>
+        <ows:Value>ows:BoundingBox</ows:Value>
+      </ows:Constraint>
+      <ows:Constraint name="SupportedISOQueryables">
+        <ows:Value>apiso:Abstract</ows:Value>
+        <ows:Value>apiso:AlternateTitle</ows:Value>
+        <ows:Value>apiso:AnyText</ows:Value>
+        <ows:Value>apiso:BoundingBox</ows:Value>
+        <ows:Value>apiso:CRS</ows:Value>
+        <ows:Value>apiso:CouplingType</ows:Value>
+        <ows:Value>apiso:CreationDate</ows:Value>
+        <ows:Value>apiso:Denominator</ows:Value>
+        <ows:Value>apiso:DistanceUOM</ows:Value>
+        <ows:Value>apiso:DistanceValue</ows:Value>
+        <ows:Value>apiso:Format</ows:Value>
+        <ows:Value>apiso:GeographicDescriptionCode</ows:Value>
+        <ows:Value>apiso:HasSecurityConstraints</ows:Value>
+        <ows:Value>apiso:Identifier</ows:Value>
+        <ows:Value>apiso:KeywordType</ows:Value>
+        <ows:Value>apiso:Language</ows:Value>
+        <ows:Value>apiso:Modified</ows:Value>
+        <ows:Value>apiso:OperatesOn</ows:Value>
+        <ows:Value>apiso:OperatesOnIdentifier</ows:Value>
+        <ows:Value>apiso:OperatesOnName</ows:Value>
+        <ows:Value>apiso:Operation</ows:Value>
+        <ows:Value>apiso:OrganisationName</ows:Value>
+        <ows:Value>apiso:ParentIdentifier</ows:Value>
+        <ows:Value>apiso:PublicationDate</ows:Value>
+        <ows:Value>apiso:ResourceLanguage</ows:Value>
+        <ows:Value>apiso:RevisionDate</ows:Value>
+        <ows:Value>apiso:ServiceType</ows:Value>
+        <ows:Value>apiso:ServiceTypeVersion</ows:Value>
+        <ows:Value>apiso:Subject</ows:Value>
+        <ows:Value>apiso:TempExtent_begin</ows:Value>
+        <ows:Value>apiso:TempExtent_end</ows:Value>
+        <ows:Value>apiso:Title</ows:Value>
+        <ows:Value>apiso:TopicCategory</ows:Value>
+        <ows:Value>apiso:Type</ows:Value>
       </ows:Constraint>
     </ows:Operation>
-    <ows:Operation name="Harvest">
+    <ows:Operation name="GetRecordById">
       <ows:DCP>
         <ows:HTTP>
+          <ows:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/manager/default.cfg"/>
           <ows:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/manager/default.cfg"/>
         </ows:HTTP>
       </ows:DCP>
-      <ows:Parameter name="ResourceType">
+      <ows:Parameter name="ElementSetName">
+        <ows:Value>brief</ows:Value>
+        <ows:Value>full</ows:Value>
+        <ows:Value>summary</ows:Value>
+      </ows:Parameter>
+      <ows:Parameter name="outputFormat">
+        <ows:Value>application/json</ows:Value>
+        <ows:Value>application/xml</ows:Value>
+      </ows:Parameter>
+      <ows:Parameter name="outputSchema">
+        <ows:Value>http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/</ows:Value>
+        <ows:Value>http://www.interlis.ch/INTERLIS2.3</ows:Value>
+        <ows:Value>http://www.isotc211.org/2005/gmd</ows:Value>
         <ows:Value>http://www.opengis.net/cat/csw/2.0.2</ows:Value>
-        <ows:Value>http://www.opengis.net/wms</ows:Value>
-        <ows:Value>http://www.opengis.net/wfs</ows:Value>
-        <ows:Value>http://www.opengis.net/wcs</ows:Value>
-        <ows:Value>http://www.opengis.net/wps/1.0.0</ows:Value>
+        <ows:Value>http://www.opengis.net/cat/csw/csdgm</ows:Value>
+        <ows:Value>http://www.w3.org/2005/Atom</ows:Value>
+      </ows:Parameter>
+    </ows:Operation>
+    <ows:Operation name="GetRepositoryItem">
+      <ows:DCP>
+        <ows:HTTP>
+          <ows:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/manager/default.cfg"/>
+        </ows:HTTP>
+      </ows:DCP>
+    </ows:Operation>
+    <ows:Operation name="Transaction">
+      <ows:DCP>
+        <ows:HTTP>
+          <ows:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/manager/default.cfg"/>
+        </ows:HTTP>
+      </ows:DCP>
+      <ows:Parameter name="TransactionSchemas">
+        <ows:Value>http://www.isotc211.org/2005/gmi</ows:Value>
+        <ows:Value>http://www.opengis.net/cat/csw/2.0.2</ows:Value>
+        <ows:Value>http://www.opengis.net/cat/csw/3.0</ows:Value>
         <ows:Value>http://www.opengis.net/sos/1.0</ows:Value>
         <ows:Value>http://www.opengis.net/sos/2.0</ows:Value>
-        <ows:Value>http://www.isotc211.org/2005/gmi</ows:Value>
+        <ows:Value>http://www.opengis.net/wcs</ows:Value>
+        <ows:Value>http://www.opengis.net/wfs</ows:Value>
+        <ows:Value>http://www.opengis.net/wms</ows:Value>
+        <ows:Value>http://www.opengis.net/wmts/1.0</ows:Value>
+        <ows:Value>http://www.opengis.net/wps/1.0.0</ows:Value>
         <ows:Value>urn:geoss:waf</ows:Value>
+      </ows:Parameter>
+    </ows:Operation>
+    <ows:Operation name="Harvest">
+      <ows:DCP>
+        <ows:HTTP>
+          <ows:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/manager/default.cfg"/>
+        </ows:HTTP>
+      </ows:DCP>
+      <ows:Parameter name="ResourceType">
+        <ows:Value>http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/</ows:Value>
+        <ows:Value>http://www.interlis.ch/INTERLIS2.3</ows:Value>
         <ows:Value>http://www.isotc211.org/2005/gmd</ows:Value>
+        <ows:Value>http://www.isotc211.org/2005/gmi</ows:Value>
         <ows:Value>http://www.isotc211.org/schemas/2005/gmd/</ows:Value>
-        <ows:Value>http://www.w3.org/2005/Atom</ows:Value>
-        <ows:Value>http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/</ows:Value>
+        <ows:Value>http://www.opengis.net/cat/csw/2.0.2</ows:Value>
+        <ows:Value>http://www.opengis.net/cat/csw/3.0</ows:Value>
         <ows:Value>http://www.opengis.net/cat/csw/csdgm</ows:Value>
+        <ows:Value>http://www.opengis.net/sos/1.0</ows:Value>
+        <ows:Value>http://www.opengis.net/sos/2.0</ows:Value>
+        <ows:Value>http://www.opengis.net/wcs</ows:Value>
+        <ows:Value>http://www.opengis.net/wfs</ows:Value>
+        <ows:Value>http://www.opengis.net/wms</ows:Value>
+        <ows:Value>http://www.opengis.net/wmts/1.0</ows:Value>
+        <ows:Value>http://www.opengis.net/wps/1.0.0</ows:Value>
+        <ows:Value>http://www.w3.org/2005/Atom</ows:Value>
+        <ows:Value>urn:geoss:waf</ows:Value>
       </ows:Parameter>
     </ows:Operation>
-    <ows:Parameter name="version">
-      <ows:Value>2.0.2</ows:Value>
-    </ows:Parameter>
     <ows:Parameter name="service">
       <ows:Value>CSW</ows:Value>
     </ows:Parameter>
-    <ows:Constraint name="XPathQueryables">
-      <ows:Value>allowed</ows:Value>
+    <ows:Parameter name="version">
+      <ows:Value>2.0.2</ows:Value>
+      <ows:Value>3.0.0</ows:Value>
+    </ows:Parameter>
+    <ows:Constraint name="FederatedCatalogues">
+      <ows:Value>http://geo.data.gov/geoportal/csw/discovery</ows:Value>
     </ows:Constraint>
     <ows:Constraint name="MaxRecordDefault">
       <ows:Value>10</ows:Value>
@@ -285,8 +306,8 @@
       <ows:Value>XML</ows:Value>
       <ows:Value>SOAP</ows:Value>
     </ows:Constraint>
-    <ows:Constraint name="FederatedCatalogues">
-      <ows:Value>http://geo.data.gov/geoportal/csw/discovery</ows:Value>
+    <ows:Constraint name="XPathQueryables">
+      <ows:Value>allowed</ows:Value>
     </ows:Constraint>
   </ows:OperationsMetadata>
   <ogc:Filter_Capabilities>
@@ -316,11 +337,11 @@
       <ogc:ComparisonOperators>
         <ogc:ComparisonOperator>Between</ogc:ComparisonOperator>
         <ogc:ComparisonOperator>EqualTo</ogc:ComparisonOperator>
-        <ogc:ComparisonOperator>LessThanEqualTo</ogc:ComparisonOperator>
         <ogc:ComparisonOperator>GreaterThan</ogc:ComparisonOperator>
-        <ogc:ComparisonOperator>Like</ogc:ComparisonOperator>
-        <ogc:ComparisonOperator>LessThan</ogc:ComparisonOperator>
         <ogc:ComparisonOperator>GreaterThanEqualTo</ogc:ComparisonOperator>
+        <ogc:ComparisonOperator>LessThan</ogc:ComparisonOperator>
+        <ogc:ComparisonOperator>LessThanEqualTo</ogc:ComparisonOperator>
+        <ogc:ComparisonOperator>Like</ogc:ComparisonOperator>
         <ogc:ComparisonOperator>NotEqualTo</ogc:ComparisonOperator>
         <ogc:ComparisonOperator>NullCheck</ogc:ComparisonOperator>
       </ogc:ComparisonOperators>
diff --git a/tests/expected/suites_manager_post_GetDomain-parameter.xml b/tests/expected/suites_manager_post_GetDomain-parameter.xml
index 01db252..a681d2a 100644
--- a/tests/expected/suites_manager_post_GetDomain-parameter.xml
+++ b/tests/expected/suites_manager_post_GetDomain-parameter.xml
@@ -1,23 +1,26 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<csw:GetDomainResponse xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:inspire_common="http://inspire.ec.europa.eu/schemas/common/1.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dct="http://purl.org/dc/terms/" xmlns:ows="http://www.opengis.net/ows" xmlns:apiso="http://www.opengis.net/cat/csw/apiso/1.0" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xlink="http://www.w3.org/1999/xlink" x [...]
+<csw:GetDomainResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/cat/csw/2.0.2 http://schemas.opengis.net/csw/2.0.2/CSW-discovery.xsd">
   <csw:DomainValues type="csw:Record">
     <csw:ParameterName>Harvest.ResourceType</csw:ParameterName>
     <csw:ListOfValues>
+      <csw:Value>http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/</csw:Value>
+      <csw:Value>http://www.interlis.ch/INTERLIS2.3</csw:Value>
+      <csw:Value>http://www.isotc211.org/2005/gmd</csw:Value>
+      <csw:Value>http://www.isotc211.org/2005/gmi</csw:Value>
+      <csw:Value>http://www.isotc211.org/schemas/2005/gmd/</csw:Value>
       <csw:Value>http://www.opengis.net/cat/csw/2.0.2</csw:Value>
-      <csw:Value>http://www.opengis.net/wms</csw:Value>
-      <csw:Value>http://www.opengis.net/wfs</csw:Value>
-      <csw:Value>http://www.opengis.net/wcs</csw:Value>
-      <csw:Value>http://www.opengis.net/wps/1.0.0</csw:Value>
+      <csw:Value>http://www.opengis.net/cat/csw/3.0</csw:Value>
+      <csw:Value>http://www.opengis.net/cat/csw/csdgm</csw:Value>
       <csw:Value>http://www.opengis.net/sos/1.0</csw:Value>
       <csw:Value>http://www.opengis.net/sos/2.0</csw:Value>
-      <csw:Value>http://www.isotc211.org/2005/gmi</csw:Value>
-      <csw:Value>urn:geoss:waf</csw:Value>
-      <csw:Value>http://www.isotc211.org/2005/gmd</csw:Value>
-      <csw:Value>http://www.isotc211.org/schemas/2005/gmd/</csw:Value>
+      <csw:Value>http://www.opengis.net/wcs</csw:Value>
+      <csw:Value>http://www.opengis.net/wfs</csw:Value>
+      <csw:Value>http://www.opengis.net/wms</csw:Value>
+      <csw:Value>http://www.opengis.net/wmts/1.0</csw:Value>
+      <csw:Value>http://www.opengis.net/wps/1.0.0</csw:Value>
       <csw:Value>http://www.w3.org/2005/Atom</csw:Value>
-      <csw:Value>http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/</csw:Value>
-      <csw:Value>http://www.opengis.net/cat/csw/csdgm</csw:Value>
+      <csw:Value>urn:geoss:waf</csw:Value>
     </csw:ListOfValues>
   </csw:DomainValues>
 </csw:GetDomainResponse>
diff --git a/tests/expected/suites_manager_post_Transaction-000-delete-all.xml b/tests/expected/suites_manager_post_Transaction-000-delete-all.xml
index 381db66..01ccdf6 100644
--- a/tests/expected/suites_manager_post_Transaction-000-delete-all.xml
+++ b/tests/expected/suites_manager_post_Transaction-000-delete-all.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<csw:TransactionResponse xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:inspire_common="http://inspire.ec.europa.eu/schemas/common/1.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dct="http://purl.org/dc/terms/" xmlns:ows="http://www.opengis.net/ows" xmlns:apiso="http://www.opengis.net/cat/csw/apiso/1.0" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xlink="http://www.w3.org/1999/xlink" [...]
+<csw:TransactionResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.0.2" xsi:schemaLocation="http://www.opengis.net/cat/csw/2.0.2 http://schemas.opengis.net/csw/2.0.2/CSW-p [...]
   <csw:TransactionSummary>
     <csw:totalInserted>0</csw:totalInserted>
     <csw:totalUpdated>0</csw:totalUpdated>
diff --git a/tests/expected/suites_manager_post_Transaction-dc-01-insert.xml b/tests/expected/suites_manager_post_Transaction-dc-01-insert.xml
index 2c8d849..07d452a 100644
--- a/tests/expected/suites_manager_post_Transaction-dc-01-insert.xml
+++ b/tests/expected/suites_manager_post_Transaction-dc-01-insert.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<csw:TransactionResponse xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:inspire_common="http://inspire.ec.europa.eu/schemas/common/1.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dct="http://purl.org/dc/terms/" xmlns:ows="http://www.opengis.net/ows" xmlns:apiso="http://www.opengis.net/cat/csw/apiso/1.0" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xlink="http://www.w3.org/1999/xlink" [...]
+<csw:TransactionResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.0.2" xsi:schemaLocation="http://www.opengis.net/cat/csw/2.0.2 http://schemas.opengis.net/csw/2.0.2/CSW-p [...]
   <csw:TransactionSummary>
     <csw:totalInserted>1</csw:totalInserted>
     <csw:totalUpdated>0</csw:totalUpdated>
diff --git a/tests/expected/suites_manager_post_Transaction-dc-02-update-full.xml b/tests/expected/suites_manager_post_Transaction-dc-02-update-full.xml
index 7dd477c..0b9104e 100644
--- a/tests/expected/suites_manager_post_Transaction-dc-02-update-full.xml
+++ b/tests/expected/suites_manager_post_Transaction-dc-02-update-full.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<csw:TransactionResponse xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:inspire_common="http://inspire.ec.europa.eu/schemas/common/1.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dct="http://purl.org/dc/terms/" xmlns:ows="http://www.opengis.net/ows" xmlns:apiso="http://www.opengis.net/cat/csw/apiso/1.0" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xlink="http://www.w3.org/1999/xlink" [...]
+<csw:TransactionResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.0.2" xsi:schemaLocation="http://www.opengis.net/cat/csw/2.0.2 http://schemas.opengis.net/csw/2.0.2/CSW-p [...]
   <csw:TransactionSummary>
     <csw:totalInserted>0</csw:totalInserted>
     <csw:totalUpdated>1</csw:totalUpdated>
diff --git a/tests/expected/suites_manager_post_Transaction-fgdc-01-insert.xml b/tests/expected/suites_manager_post_Transaction-fgdc-01-insert.xml
index 1fed608..c44db37 100644
--- a/tests/expected/suites_manager_post_Transaction-fgdc-01-insert.xml
+++ b/tests/expected/suites_manager_post_Transaction-fgdc-01-insert.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<csw:TransactionResponse xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:inspire_common="http://inspire.ec.europa.eu/schemas/common/1.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dct="http://purl.org/dc/terms/" xmlns:ows="http://www.opengis.net/ows" xmlns:apiso="http://www.opengis.net/cat/csw/apiso/1.0" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xlink="http://www.w3.org/1999/xlink" [...]
+<csw:TransactionResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.0.2" xsi:schemaLocation="http://www.opengis.net/cat/csw/2.0.2 http://schemas.opengis.net/csw/2.0.2/CSW-p [...]
   <csw:TransactionSummary>
     <csw:totalInserted>1</csw:totalInserted>
     <csw:totalUpdated>0</csw:totalUpdated>
diff --git a/tests/expected/suites_manager_post_Transaction-fgdc-02-update-recprop.xml b/tests/expected/suites_manager_post_Transaction-fgdc-02-update-recprop.xml
index 7dd477c..0b9104e 100644
--- a/tests/expected/suites_manager_post_Transaction-fgdc-02-update-recprop.xml
+++ b/tests/expected/suites_manager_post_Transaction-fgdc-02-update-recprop.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<csw:TransactionResponse xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:inspire_common="http://inspire.ec.europa.eu/schemas/common/1.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dct="http://purl.org/dc/terms/" xmlns:ows="http://www.opengis.net/ows" xmlns:apiso="http://www.opengis.net/cat/csw/apiso/1.0" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xlink="http://www.w3.org/1999/xlink" [...]
+<csw:TransactionResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.0.2" xsi:schemaLocation="http://www.opengis.net/cat/csw/2.0.2 http://schemas.opengis.net/csw/2.0.2/CSW-p [...]
   <csw:TransactionSummary>
     <csw:totalInserted>0</csw:totalInserted>
     <csw:totalUpdated>1</csw:totalUpdated>
diff --git a/tests/expected/suites_manager_post_Transaction-fgdc-03-delete-all.xml b/tests/expected/suites_manager_post_Transaction-fgdc-03-delete-all.xml
index 3558d43..a788564 100644
--- a/tests/expected/suites_manager_post_Transaction-fgdc-03-delete-all.xml
+++ b/tests/expected/suites_manager_post_Transaction-fgdc-03-delete-all.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<csw:TransactionResponse xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:inspire_common="http://inspire.ec.europa.eu/schemas/common/1.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dct="http://purl.org/dc/terms/" xmlns:ows="http://www.opengis.net/ows" xmlns:apiso="http://www.opengis.net/cat/csw/apiso/1.0" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xlink="http://www.w3.org/1999/xlink" [...]
+<csw:TransactionResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.0.2" xsi:schemaLocation="http://www.opengis.net/cat/csw/2.0.2 http://schemas.opengis.net/csw/2.0.2/CSW-p [...]
   <csw:TransactionSummary>
     <csw:totalInserted>0</csw:totalInserted>
     <csw:totalUpdated>0</csw:totalUpdated>
diff --git a/tests/expected/suites_manager_post_Transaction-iso-00-delete-all.xml b/tests/expected/suites_manager_post_Transaction-iso-00-delete-all.xml
index 381db66..01ccdf6 100644
--- a/tests/expected/suites_manager_post_Transaction-iso-00-delete-all.xml
+++ b/tests/expected/suites_manager_post_Transaction-iso-00-delete-all.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<csw:TransactionResponse xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:inspire_common="http://inspire.ec.europa.eu/schemas/common/1.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dct="http://purl.org/dc/terms/" xmlns:ows="http://www.opengis.net/ows" xmlns:apiso="http://www.opengis.net/cat/csw/apiso/1.0" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xlink="http://www.w3.org/1999/xlink" [...]
+<csw:TransactionResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.0.2" xsi:schemaLocation="http://www.opengis.net/cat/csw/2.0.2 http://schemas.opengis.net/csw/2.0.2/CSW-p [...]
   <csw:TransactionSummary>
     <csw:totalInserted>0</csw:totalInserted>
     <csw:totalUpdated>0</csw:totalUpdated>
diff --git a/tests/expected/suites_manager_post_Transaction-iso-01-insert.xml b/tests/expected/suites_manager_post_Transaction-iso-01-insert.xml
index 99b5433..2e3a528 100644
--- a/tests/expected/suites_manager_post_Transaction-iso-01-insert.xml
+++ b/tests/expected/suites_manager_post_Transaction-iso-01-insert.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<csw:TransactionResponse xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:inspire_common="http://inspire.ec.europa.eu/schemas/common/1.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dct="http://purl.org/dc/terms/" xmlns:ows="http://www.opengis.net/ows" xmlns:apiso="http://www.opengis.net/cat/csw/apiso/1.0" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xlink="http://www.w3.org/1999/xlink" [...]
+<csw:TransactionResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.0.2" xsi:schemaLocation="http://www.opengis.net/cat/csw/2.0.2 http://schemas.opengis.net/csw/2.0.2/CSW-p [...]
   <csw:TransactionSummary>
     <csw:totalInserted>1</csw:totalInserted>
     <csw:totalUpdated>0</csw:totalUpdated>
diff --git a/tests/expected/suites_manager_post_Transaction-iso-02-update-full.xml b/tests/expected/suites_manager_post_Transaction-iso-02-update-full.xml
index 7dd477c..0b9104e 100644
--- a/tests/expected/suites_manager_post_Transaction-iso-02-update-full.xml
+++ b/tests/expected/suites_manager_post_Transaction-iso-02-update-full.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<csw:TransactionResponse xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:inspire_common="http://inspire.ec.europa.eu/schemas/common/1.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dct="http://purl.org/dc/terms/" xmlns:ows="http://www.opengis.net/ows" xmlns:apiso="http://www.opengis.net/cat/csw/apiso/1.0" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xlink="http://www.w3.org/1999/xlink" [...]
+<csw:TransactionResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.0.2" xsi:schemaLocation="http://www.opengis.net/cat/csw/2.0.2 http://schemas.opengis.net/csw/2.0.2/CSW-p [...]
   <csw:TransactionSummary>
     <csw:totalInserted>0</csw:totalInserted>
     <csw:totalUpdated>1</csw:totalUpdated>
diff --git a/tests/expected/suites_manager_post_Transaction-iso-03-update-recprop.xml b/tests/expected/suites_manager_post_Transaction-iso-03-update-recprop.xml
index 7dd477c..0b9104e 100644
--- a/tests/expected/suites_manager_post_Transaction-iso-03-update-recprop.xml
+++ b/tests/expected/suites_manager_post_Transaction-iso-03-update-recprop.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<csw:TransactionResponse xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:inspire_common="http://inspire.ec.europa.eu/schemas/common/1.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dct="http://purl.org/dc/terms/" xmlns:ows="http://www.opengis.net/ows" xmlns:apiso="http://www.opengis.net/cat/csw/apiso/1.0" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xlink="http://www.w3.org/1999/xlink" [...]
+<csw:TransactionResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.0.2" xsi:schemaLocation="http://www.opengis.net/cat/csw/2.0.2 http://schemas.opengis.net/csw/2.0.2/CSW-p [...]
   <csw:TransactionSummary>
     <csw:totalInserted>0</csw:totalInserted>
     <csw:totalUpdated>1</csw:totalUpdated>
diff --git a/tests/expected/suites_manager_post_Transaction-iso-04-update-recprop-no-matches.xml b/tests/expected/suites_manager_post_Transaction-iso-04-update-recprop-no-matches.xml
index 381db66..01ccdf6 100644
--- a/tests/expected/suites_manager_post_Transaction-iso-04-update-recprop-no-matches.xml
+++ b/tests/expected/suites_manager_post_Transaction-iso-04-update-recprop-no-matches.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<csw:TransactionResponse xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:inspire_common="http://inspire.ec.europa.eu/schemas/common/1.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dct="http://purl.org/dc/terms/" xmlns:ows="http://www.opengis.net/ows" xmlns:apiso="http://www.opengis.net/cat/csw/apiso/1.0" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xlink="http://www.w3.org/1999/xlink" [...]
+<csw:TransactionResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.0.2" xsi:schemaLocation="http://www.opengis.net/cat/csw/2.0.2 http://schemas.opengis.net/csw/2.0.2/CSW-p [...]
   <csw:TransactionSummary>
     <csw:totalInserted>0</csw:totalInserted>
     <csw:totalUpdated>0</csw:totalUpdated>
diff --git a/tests/expected/suites_manager_post_Transaction-iso-05-delete.xml b/tests/expected/suites_manager_post_Transaction-iso-05-delete.xml
index 6cb31a7..0e48fd5 100644
--- a/tests/expected/suites_manager_post_Transaction-iso-05-delete.xml
+++ b/tests/expected/suites_manager_post_Transaction-iso-05-delete.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<csw:TransactionResponse xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:inspire_common="http://inspire.ec.europa.eu/schemas/common/1.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dct="http://purl.org/dc/terms/" xmlns:ows="http://www.opengis.net/ows" xmlns:apiso="http://www.opengis.net/cat/csw/apiso/1.0" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xlink="http://www.w3.org/1999/xlink" [...]
+<csw:TransactionResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.0.2" xsi:schemaLocation="http://www.opengis.net/cat/csw/2.0.2 http://schemas.opengis.net/csw/2.0.2/CSW-p [...]
   <csw:TransactionSummary>
     <csw:totalInserted>0</csw:totalInserted>
     <csw:totalUpdated>0</csw:totalUpdated>
diff --git a/tests/expected/suites_manager_post_Transaction-xxx-delete-all.xml b/tests/expected/suites_manager_post_Transaction-xxx-delete-all.xml
index 381db66..01ccdf6 100644
--- a/tests/expected/suites_manager_post_Transaction-xxx-delete-all.xml
+++ b/tests/expected/suites_manager_post_Transaction-xxx-delete-all.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<csw:TransactionResponse xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:inspire_common="http://inspire.ec.europa.eu/schemas/common/1.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dct="http://purl.org/dc/terms/" xmlns:ows="http://www.opengis.net/ows" xmlns:apiso="http://www.opengis.net/cat/csw/apiso/1.0" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xlink="http://www.w3.org/1999/xlink" [...]
+<csw:TransactionResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.0.2" xsi:schemaLocation="http://www.opengis.net/cat/csw/2.0.2 http://schemas.opengis.net/csw/2.0.2/CSW-p [...]
   <csw:TransactionSummary>
     <csw:totalInserted>0</csw:totalInserted>
     <csw:totalUpdated>0</csw:totalUpdated>
diff --git a/tests/expected/suites_oaipmh_get_GetRecord_bad_metadata_prefix.xml b/tests/expected/suites_oaipmh_get_GetRecord_bad_metadata_prefix.xml
index 41851ea..8633a42 100644
--- a/tests/expected/suites_oaipmh_get_GetRecord_bad_metadata_prefix.xml
+++ b/tests/expected/suites_oaipmh_get_GetRecord_bad_metadata_prefix.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<oai:OAI-PMH xmlns:oai_dc="http://www.openarchives.org/OAI/2.0/oai_dc/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:oai="http://www.openarchives.org/OAI/2.0/" xsi:schemaLocation="http://www.openarchives.org/OAI/2.0/ http://www.openarchives.org/OAI/2.0/OAI-PMH.xsd">
+<oai:OAI-PMH xmlns:oai="http://www.openarchives.org/OAI/2.0/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.openarchives.org/OAI/2.0/ http://www.openarchives.org/OAI/2.0/OAI-PMH.xsd">
   <oai:responseDate>PYCSW_TIMESTAMP</oai:responseDate>
   <oai:request identifier="urn:uuid:19887a8a-f6b0-4a63-ae56-7fba0e17801f" metadataprefix="csw-recordd" verb="GetRecord">http://localhost/pycsw/csw.py?config=tests/suites/oaipmh/default.cfg&mode=oaipmh</oai:request>
   <oai:error code="badArgument">Invalid outputschema parameter csw-recordd</oai:error>
diff --git a/tests/expected/suites_oaipmh_get_GetRecord_dc.xml b/tests/expected/suites_oaipmh_get_GetRecord_dc.xml
index ea1dfc7..367da88 100644
--- a/tests/expected/suites_oaipmh_get_GetRecord_dc.xml
+++ b/tests/expected/suites_oaipmh_get_GetRecord_dc.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<oai:OAI-PMH xmlns:oai_dc="http://www.openarchives.org/OAI/2.0/oai_dc/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:oai="http://www.openarchives.org/OAI/2.0/" xsi:schemaLocation="http://www.openarchives.org/OAI/2.0/ http://www.openarchives.org/OAI/2.0/OAI-PMH.xsd">
+<oai:OAI-PMH xmlns:oai="http://www.openarchives.org/OAI/2.0/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.openarchives.org/OAI/2.0/ http://www.openarchives.org/OAI/2.0/OAI-PMH.xsd">
   <oai:responseDate>PYCSW_TIMESTAMP</oai:responseDate>
   <oai:request identifier="urn:uuid:19887a8a-f6b0-4a63-ae56-7fba0e17801f" metadataprefix="csw-record" verb="GetRecord">http://localhost/pycsw/csw.py?config=tests/suites/oaipmh/default.cfg&mode=oaipmh</oai:request>
   <oai:GetRecord>
diff --git a/tests/expected/suites_oaipmh_get_GetRecord_iso.xml b/tests/expected/suites_oaipmh_get_GetRecord_iso.xml
index 813e46e..8a482b6 100644
--- a/tests/expected/suites_oaipmh_get_GetRecord_iso.xml
+++ b/tests/expected/suites_oaipmh_get_GetRecord_iso.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<oai:OAI-PMH xmlns:oai_dc="http://www.openarchives.org/OAI/2.0/oai_dc/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:oai="http://www.openarchives.org/OAI/2.0/" xsi:schemaLocation="http://www.openarchives.org/OAI/2.0/ http://www.openarchives.org/OAI/2.0/OAI-PMH.xsd">
+<oai:OAI-PMH xmlns:oai="http://www.openarchives.org/OAI/2.0/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.openarchives.org/OAI/2.0/ http://www.openarchives.org/OAI/2.0/OAI-PMH.xsd">
   <oai:responseDate>PYCSW_TIMESTAMP</oai:responseDate>
   <oai:request identifier="urn:uuid:19887a8a-f6b0-4a63-ae56-7fba0e17801f" metadataprefix="iso19139" verb="GetRecord">http://localhost/pycsw/csw.py?config=tests/suites/oaipmh/default.cfg&mode=oaipmh</oai:request>
   <oai:GetRecord>
diff --git a/tests/expected/suites_oaipmh_get_GetRecord_oai_dc.xml b/tests/expected/suites_oaipmh_get_GetRecord_oai_dc.xml
index 7420484..c8840ef 100644
--- a/tests/expected/suites_oaipmh_get_GetRecord_oai_dc.xml
+++ b/tests/expected/suites_oaipmh_get_GetRecord_oai_dc.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<oai:OAI-PMH xmlns:oai_dc="http://www.openarchives.org/OAI/2.0/oai_dc/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:oai="http://www.openarchives.org/OAI/2.0/" xsi:schemaLocation="http://www.openarchives.org/OAI/2.0/ http://www.openarchives.org/OAI/2.0/OAI-PMH.xsd">
+<oai:OAI-PMH xmlns:oai="http://www.openarchives.org/OAI/2.0/" xmlns:oai_dc="http://www.openarchives.org/OAI/2.0/oai_dc/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.openarchives.org/OAI/2.0/ http://www.openarchives.org/OAI/2.0/OAI-PMH.xsd">
   <oai:responseDate>PYCSW_TIMESTAMP</oai:responseDate>
   <oai:request identifier="urn:uuid:19887a8a-f6b0-4a63-ae56-7fba0e17801f" metadataprefix="oai_dc" verb="GetRecord">http://localhost/pycsw/csw.py?config=tests/suites/oaipmh/default.cfg&mode=oaipmh</oai:request>
   <oai:GetRecord>
diff --git a/tests/expected/suites_oaipmh_get_Identify.xml b/tests/expected/suites_oaipmh_get_Identify.xml
index d6f3e63..967a385 100644
--- a/tests/expected/suites_oaipmh_get_Identify.xml
+++ b/tests/expected/suites_oaipmh_get_Identify.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<oai:OAI-PMH xmlns:oai_dc="http://www.openarchives.org/OAI/2.0/oai_dc/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:oai="http://www.openarchives.org/OAI/2.0/" xsi:schemaLocation="http://www.openarchives.org/OAI/2.0/ http://www.openarchives.org/OAI/2.0/OAI-PMH.xsd">
+<oai:OAI-PMH xmlns:oai="http://www.openarchives.org/OAI/2.0/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.openarchives.org/OAI/2.0/ http://www.openarchives.org/OAI/2.0/OAI-PMH.xsd">
   <oai:responseDate>PYCSW_TIMESTAMP</oai:responseDate>
   <oai:request verb="Identify">http://localhost/pycsw/csw.py?config=tests/suites/oaipmh/default.cfg&mode=oaipmh</oai:request>
   <oai:Identify>
diff --git a/tests/expected/suites_oaipmh_get_ListIdentifiers_bad_metadata_prefix.xml b/tests/expected/suites_oaipmh_get_ListIdentifiers_bad_metadata_prefix.xml
index 1784dec..3eaa03c 100644
--- a/tests/expected/suites_oaipmh_get_ListIdentifiers_bad_metadata_prefix.xml
+++ b/tests/expected/suites_oaipmh_get_ListIdentifiers_bad_metadata_prefix.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<oai:OAI-PMH xmlns:oai_dc="http://www.openarchives.org/OAI/2.0/oai_dc/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:oai="http://www.openarchives.org/OAI/2.0/" xsi:schemaLocation="http://www.openarchives.org/OAI/2.0/ http://www.openarchives.org/OAI/2.0/OAI-PMH.xsd">
+<oai:OAI-PMH xmlns:oai="http://www.openarchives.org/OAI/2.0/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.openarchives.org/OAI/2.0/ http://www.openarchives.org/OAI/2.0/OAI-PMH.xsd">
   <oai:responseDate>PYCSW_TIMESTAMP</oai:responseDate>
   <oai:request metadataprefix="foo" verb="ListIdentifiers">http://localhost/pycsw/csw.py?config=tests/suites/oaipmh/default.cfg&mode=oaipmh</oai:request>
   <oai:error code="badArgument">Invalid outputSchema parameter value: foo</oai:error>
diff --git a/tests/expected/suites_oaipmh_get_ListIdentifiers_dc.xml b/tests/expected/suites_oaipmh_get_ListIdentifiers_dc.xml
index b26577e..388be64 100644
--- a/tests/expected/suites_oaipmh_get_ListIdentifiers_dc.xml
+++ b/tests/expected/suites_oaipmh_get_ListIdentifiers_dc.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<oai:OAI-PMH xmlns:oai_dc="http://www.openarchives.org/OAI/2.0/oai_dc/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:oai="http://www.openarchives.org/OAI/2.0/" xsi:schemaLocation="http://www.openarchives.org/OAI/2.0/ http://www.openarchives.org/OAI/2.0/OAI-PMH.xsd">
+<oai:OAI-PMH xmlns:oai="http://www.openarchives.org/OAI/2.0/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.openarchives.org/OAI/2.0/ http://www.openarchives.org/OAI/2.0/OAI-PMH.xsd">
   <oai:responseDate>PYCSW_TIMESTAMP</oai:responseDate>
   <oai:request metadataprefix="csw-record" verb="ListIdentifiers">http://localhost/pycsw/csw.py?config=tests/suites/oaipmh/default.cfg&mode=oaipmh</oai:request>
   <oai:ListIdentifiers>
diff --git a/tests/expected/suites_oaipmh_get_ListIdentifiers_iso.xml b/tests/expected/suites_oaipmh_get_ListIdentifiers_iso.xml
index cccf0cc..1ab8be8 100644
--- a/tests/expected/suites_oaipmh_get_ListIdentifiers_iso.xml
+++ b/tests/expected/suites_oaipmh_get_ListIdentifiers_iso.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<oai:OAI-PMH xmlns:oai_dc="http://www.openarchives.org/OAI/2.0/oai_dc/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:oai="http://www.openarchives.org/OAI/2.0/" xsi:schemaLocation="http://www.openarchives.org/OAI/2.0/ http://www.openarchives.org/OAI/2.0/OAI-PMH.xsd">
+<oai:OAI-PMH xmlns:oai="http://www.openarchives.org/OAI/2.0/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.openarchives.org/OAI/2.0/ http://www.openarchives.org/OAI/2.0/OAI-PMH.xsd">
   <oai:responseDate>PYCSW_TIMESTAMP</oai:responseDate>
   <oai:request metadataprefix="iso19139" verb="ListIdentifiers">http://localhost/pycsw/csw.py?config=tests/suites/oaipmh/default.cfg&mode=oaipmh</oai:request>
   <oai:ListIdentifiers>
diff --git a/tests/expected/suites_oaipmh_get_ListIdentifiers_missing_metadata_prefix.xml b/tests/expected/suites_oaipmh_get_ListIdentifiers_missing_metadata_prefix.xml
index 7136aa6..4104799 100644
--- a/tests/expected/suites_oaipmh_get_ListIdentifiers_missing_metadata_prefix.xml
+++ b/tests/expected/suites_oaipmh_get_ListIdentifiers_missing_metadata_prefix.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<oai:OAI-PMH xmlns:oai_dc="http://www.openarchives.org/OAI/2.0/oai_dc/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:oai="http://www.openarchives.org/OAI/2.0/" xsi:schemaLocation="http://www.openarchives.org/OAI/2.0/ http://www.openarchives.org/OAI/2.0/OAI-PMH.xsd">
+<oai:OAI-PMH xmlns:oai="http://www.openarchives.org/OAI/2.0/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.openarchives.org/OAI/2.0/ http://www.openarchives.org/OAI/2.0/OAI-PMH.xsd">
   <oai:responseDate>PYCSW_TIMESTAMP</oai:responseDate>
   <oai:request verb="ListIdentifiers">http://localhost/pycsw/csw.py?config=tests/suites/oaipmh/default.cfg&mode=oaipmh</oai:request>
   <oai:error code="badArgument">Missing metadataPrefix parameter</oai:error>
diff --git a/tests/expected/suites_oaipmh_get_ListIdentifiers_oai_dc.xml b/tests/expected/suites_oaipmh_get_ListIdentifiers_oai_dc.xml
index f3dda7c..a41a083 100644
--- a/tests/expected/suites_oaipmh_get_ListIdentifiers_oai_dc.xml
+++ b/tests/expected/suites_oaipmh_get_ListIdentifiers_oai_dc.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<oai:OAI-PMH xmlns:oai_dc="http://www.openarchives.org/OAI/2.0/oai_dc/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:oai="http://www.openarchives.org/OAI/2.0/" xsi:schemaLocation="http://www.openarchives.org/OAI/2.0/ http://www.openarchives.org/OAI/2.0/OAI-PMH.xsd">
+<oai:OAI-PMH xmlns:oai="http://www.openarchives.org/OAI/2.0/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.openarchives.org/OAI/2.0/ http://www.openarchives.org/OAI/2.0/OAI-PMH.xsd">
   <oai:responseDate>PYCSW_TIMESTAMP</oai:responseDate>
   <oai:request metadataprefix="oai_dc" verb="ListIdentifiers">http://localhost/pycsw/csw.py?config=tests/suites/oaipmh/default.cfg&mode=oaipmh</oai:request>
   <oai:ListIdentifiers>
diff --git a/tests/expected/suites_oaipmh_get_ListMetadataFormats.xml b/tests/expected/suites_oaipmh_get_ListMetadataFormats.xml
index 99903ec..2549bc9 100644
--- a/tests/expected/suites_oaipmh_get_ListMetadataFormats.xml
+++ b/tests/expected/suites_oaipmh_get_ListMetadataFormats.xml
@@ -1,18 +1,13 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<oai:OAI-PMH xmlns:oai_dc="http://www.openarchives.org/OAI/2.0/oai_dc/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:oai="http://www.openarchives.org/OAI/2.0/" xsi:schemaLocation="http://www.openarchives.org/OAI/2.0/ http://www.openarchives.org/OAI/2.0/OAI-PMH.xsd">
+<oai:OAI-PMH xmlns:oai="http://www.openarchives.org/OAI/2.0/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.openarchives.org/OAI/2.0/ http://www.openarchives.org/OAI/2.0/OAI-PMH.xsd">
   <oai:responseDate>PYCSW_TIMESTAMP</oai:responseDate>
   <oai:request verb="ListMetadataFormats">http://localhost/pycsw/csw.py?config=tests/suites/oaipmh/default.cfg&mode=oaipmh</oai:request>
   <oai:ListMetadataFormats>
     <oai:metadataFormat>
-      <oai:metadataPrefix>oai_dc</oai:metadataPrefix>
-      <oai:schema>http://www.openarchives.org/OAI/2.0/oai_dc.xsd</oai:schema>
-      <oai:metadataNamespace>http://www.openarchives.org/OAI/2.0/oai_dc/</oai:metadataNamespace>
-    </oai:metadataFormat>
-    <oai:metadataFormat>
-      <oai:metadataPrefix>iso19139</oai:metadataPrefix>
-      <oai:schema>http://www.isotc211.org/2005/gmd/gmd.xsd</oai:schema>
-      <oai:metadataNamespace>http://www.isotc211.org/2005/gmd</oai:metadataNamespace>
+      <oai:metadataPrefix>csw-record</oai:metadataPrefix>
+      <oai:schema>http://schemas.opengis.net/csw/2.0.2/record.xsd</oai:schema>
+      <oai:metadataNamespace>http://www.opengis.net/cat/csw/2.0.2</oai:metadataNamespace>
     </oai:metadataFormat>
     <oai:metadataFormat>
       <oai:metadataPrefix>dif</oai:metadataPrefix>
@@ -25,9 +20,19 @@
       <oai:metadataNamespace>http://www.opengis.net/cat/csw/csdgm</oai:metadataNamespace>
     </oai:metadataFormat>
     <oai:metadataFormat>
-      <oai:metadataPrefix>csw-record</oai:metadataPrefix>
-      <oai:schema>http://schemas.opengis.net/csw/2.0.2/record.xsd</oai:schema>
-      <oai:metadataNamespace>http://www.opengis.net/cat/csw/2.0.2</oai:metadataNamespace>
+      <oai:metadataPrefix>gm03</oai:metadataPrefix>
+      <oai:schema>http://www.geocat.ch/internet/geocat/en/home/documentation/gm03.parsys.50316.downloadList.86742.DownloadFile.tmp/gm0321.zip</oai:schema>
+      <oai:metadataNamespace>http://www.interlis.ch/INTERLIS2.3</oai:metadataNamespace>
+    </oai:metadataFormat>
+    <oai:metadataFormat>
+      <oai:metadataPrefix>iso19139</oai:metadataPrefix>
+      <oai:schema>http://www.isotc211.org/2005/gmd/gmd.xsd</oai:schema>
+      <oai:metadataNamespace>http://www.isotc211.org/2005/gmd</oai:metadataNamespace>
+    </oai:metadataFormat>
+    <oai:metadataFormat>
+      <oai:metadataPrefix>oai_dc</oai:metadataPrefix>
+      <oai:schema>http://www.openarchives.org/OAI/2.0/oai_dc.xsd</oai:schema>
+      <oai:metadataNamespace>http://www.openarchives.org/OAI/2.0/oai_dc/</oai:metadataNamespace>
     </oai:metadataFormat>
   </oai:ListMetadataFormats>
 </oai:OAI-PMH>
diff --git a/tests/expected/suites_oaipmh_get_ListRecords_dc.xml b/tests/expected/suites_oaipmh_get_ListRecords_dc.xml
index e053a29..43a853d 100644
--- a/tests/expected/suites_oaipmh_get_ListRecords_dc.xml
+++ b/tests/expected/suites_oaipmh_get_ListRecords_dc.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<oai:OAI-PMH xmlns:oai_dc="http://www.openarchives.org/OAI/2.0/oai_dc/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:oai="http://www.openarchives.org/OAI/2.0/" xsi:schemaLocation="http://www.openarchives.org/OAI/2.0/ http://www.openarchives.org/OAI/2.0/OAI-PMH.xsd">
+<oai:OAI-PMH xmlns:oai="http://www.openarchives.org/OAI/2.0/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.openarchives.org/OAI/2.0/ http://www.openarchives.org/OAI/2.0/OAI-PMH.xsd">
   <oai:responseDate>PYCSW_TIMESTAMP</oai:responseDate>
   <oai:request metadataprefix="csw-record" verb="ListRecords">http://localhost/pycsw/csw.py?config=tests/suites/oaipmh/default.cfg&mode=oaipmh</oai:request>
   <oai:ListRecords>
diff --git a/tests/expected/suites_oaipmh_get_ListRecords_dc_bad_metadata_prefix.xml b/tests/expected/suites_oaipmh_get_ListRecords_dc_bad_metadata_prefix.xml
index 0243a52..6ed9a9c 100644
--- a/tests/expected/suites_oaipmh_get_ListRecords_dc_bad_metadata_prefix.xml
+++ b/tests/expected/suites_oaipmh_get_ListRecords_dc_bad_metadata_prefix.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<oai:OAI-PMH xmlns:oai_dc="http://www.openarchives.org/OAI/2.0/oai_dc/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:oai="http://www.openarchives.org/OAI/2.0/" xsi:schemaLocation="http://www.openarchives.org/OAI/2.0/ http://www.openarchives.org/OAI/2.0/OAI-PMH.xsd">
+<oai:OAI-PMH xmlns:oai="http://www.openarchives.org/OAI/2.0/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.openarchives.org/OAI/2.0/ http://www.openarchives.org/OAI/2.0/OAI-PMH.xsd">
   <oai:responseDate>PYCSW_TIMESTAMP</oai:responseDate>
   <oai:request metadataprefix="csw-recording" verb="ListRecords">http://localhost/pycsw/csw.py?config=tests/suites/oaipmh/default.cfg&mode=oaipmh</oai:request>
   <oai:error code="badArgument">Invalid outputSchema parameter value: csw-recording</oai:error>
diff --git a/tests/expected/suites_oaipmh_get_ListRecords_iso19139.xml b/tests/expected/suites_oaipmh_get_ListRecords_iso19139.xml
index b54b7e3..58bd002 100644
--- a/tests/expected/suites_oaipmh_get_ListRecords_iso19139.xml
+++ b/tests/expected/suites_oaipmh_get_ListRecords_iso19139.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<oai:OAI-PMH xmlns:oai_dc="http://www.openarchives.org/OAI/2.0/oai_dc/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:oai="http://www.openarchives.org/OAI/2.0/" xsi:schemaLocation="http://www.openarchives.org/OAI/2.0/ http://www.openarchives.org/OAI/2.0/OAI-PMH.xsd">
+<oai:OAI-PMH xmlns:oai="http://www.openarchives.org/OAI/2.0/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.openarchives.org/OAI/2.0/ http://www.openarchives.org/OAI/2.0/OAI-PMH.xsd">
   <oai:responseDate>PYCSW_TIMESTAMP</oai:responseDate>
   <oai:request metadataprefix="iso19139" verb="ListRecords">http://localhost/pycsw/csw.py?config=tests/suites/oaipmh/default.cfg&mode=oaipmh</oai:request>
   <oai:ListRecords>
diff --git a/tests/expected/suites_oaipmh_get_ListRecords_oai_dc.xml b/tests/expected/suites_oaipmh_get_ListRecords_oai_dc.xml
index 5135cc1..a5dc399 100644
--- a/tests/expected/suites_oaipmh_get_ListRecords_oai_dc.xml
+++ b/tests/expected/suites_oaipmh_get_ListRecords_oai_dc.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<oai:OAI-PMH xmlns:oai_dc="http://www.openarchives.org/OAI/2.0/oai_dc/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:oai="http://www.openarchives.org/OAI/2.0/" xsi:schemaLocation="http://www.openarchives.org/OAI/2.0/ http://www.openarchives.org/OAI/2.0/OAI-PMH.xsd">
+<oai:OAI-PMH xmlns:oai="http://www.openarchives.org/OAI/2.0/" xmlns:oai_dc="http://www.openarchives.org/OAI/2.0/oai_dc/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.openarchives.org/OAI/2.0/ http://www.openarchives.org/OAI/2.0/OAI-PMH.xsd">
   <oai:responseDate>PYCSW_TIMESTAMP</oai:responseDate>
   <oai:request metadataprefix="oai_dc" verb="ListRecords">http://localhost/pycsw/csw.py?config=tests/suites/oaipmh/default.cfg&mode=oaipmh</oai:request>
   <oai:ListRecords>
diff --git a/tests/expected/suites_oaipmh_get_ListSets.xml b/tests/expected/suites_oaipmh_get_ListSets.xml
index 3d0f9dd..2be9080 100644
--- a/tests/expected/suites_oaipmh_get_ListSets.xml
+++ b/tests/expected/suites_oaipmh_get_ListSets.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<oai:OAI-PMH xmlns:oai_dc="http://www.openarchives.org/OAI/2.0/oai_dc/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:oai="http://www.openarchives.org/OAI/2.0/" xsi:schemaLocation="http://www.openarchives.org/OAI/2.0/ http://www.openarchives.org/OAI/2.0/OAI-PMH.xsd">
+<oai:OAI-PMH xmlns:oai="http://www.openarchives.org/OAI/2.0/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.openarchives.org/OAI/2.0/ http://www.openarchives.org/OAI/2.0/OAI-PMH.xsd">
   <oai:responseDate>PYCSW_TIMESTAMP</oai:responseDate>
   <oai:request verb="ListSets">http://localhost/pycsw/csw.py?config=tests/suites/oaipmh/default.cfg&mode=oaipmh</oai:request>
   <oai:ListSets>
diff --git a/tests/expected/suites_oaipmh_get_bad_verb.xml b/tests/expected/suites_oaipmh_get_bad_verb.xml
index a1a2fde..0e3dfba 100644
--- a/tests/expected/suites_oaipmh_get_bad_verb.xml
+++ b/tests/expected/suites_oaipmh_get_bad_verb.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<oai:OAI-PMH xmlns:oai_dc="http://www.openarchives.org/OAI/2.0/oai_dc/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:oai="http://www.openarchives.org/OAI/2.0/" xsi:schemaLocation="http://www.openarchives.org/OAI/2.0/ http://www.openarchives.org/OAI/2.0/OAI-PMH.xsd">
+<oai:OAI-PMH xmlns:oai="http://www.openarchives.org/OAI/2.0/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.openarchives.org/OAI/2.0/ http://www.openarchives.org/OAI/2.0/OAI-PMH.xsd">
   <oai:responseDate>PYCSW_TIMESTAMP</oai:responseDate>
   <oai:request verb="foo">http://localhost/pycsw/csw.py?config=tests/suites/oaipmh/default.cfg&mode=oaipmh</oai:request>
   <oai:error code="badArgument">Unknown verb 'foo'</oai:error>
diff --git a/tests/expected/suites_oaipmh_get_empty.xml b/tests/expected/suites_oaipmh_get_empty.xml
index 2ce10bb..1f6d54a 100644
--- a/tests/expected/suites_oaipmh_get_empty.xml
+++ b/tests/expected/suites_oaipmh_get_empty.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<oai:OAI-PMH xmlns:oai_dc="http://www.openarchives.org/OAI/2.0/oai_dc/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:oai="http://www.openarchives.org/OAI/2.0/" xsi:schemaLocation="http://www.openarchives.org/OAI/2.0/ http://www.openarchives.org/OAI/2.0/OAI-PMH.xsd">
+<oai:OAI-PMH xmlns:oai="http://www.openarchives.org/OAI/2.0/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.openarchives.org/OAI/2.0/ http://www.openarchives.org/OAI/2.0/OAI-PMH.xsd">
   <oai:responseDate>PYCSW_TIMESTAMP</oai:responseDate>
   <oai:request>http://localhost/pycsw/csw.py?config=tests/suites/oaipmh/default.cfg&mode=oaipmh</oai:request>
   <oai:error code="badArgument">Missing 'verb' parameter</oai:error>
diff --git a/tests/expected/suites_oaipmh_get_empty_with_amp.xml b/tests/expected/suites_oaipmh_get_empty_with_amp.xml
index 2ce10bb..1f6d54a 100644
--- a/tests/expected/suites_oaipmh_get_empty_with_amp.xml
+++ b/tests/expected/suites_oaipmh_get_empty_with_amp.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<oai:OAI-PMH xmlns:oai_dc="http://www.openarchives.org/OAI/2.0/oai_dc/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:oai="http://www.openarchives.org/OAI/2.0/" xsi:schemaLocation="http://www.openarchives.org/OAI/2.0/ http://www.openarchives.org/OAI/2.0/OAI-PMH.xsd">
+<oai:OAI-PMH xmlns:oai="http://www.openarchives.org/OAI/2.0/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.openarchives.org/OAI/2.0/ http://www.openarchives.org/OAI/2.0/OAI-PMH.xsd">
   <oai:responseDate>PYCSW_TIMESTAMP</oai:responseDate>
   <oai:request>http://localhost/pycsw/csw.py?config=tests/suites/oaipmh/default.cfg&mode=oaipmh</oai:request>
   <oai:error code="badArgument">Missing 'verb' parameter</oai:error>
diff --git a/tests/expected/suites_oaipmh_get_illegal_verb.xml b/tests/expected/suites_oaipmh_get_illegal_verb.xml
index 858be36..4a88ffe 100644
--- a/tests/expected/suites_oaipmh_get_illegal_verb.xml
+++ b/tests/expected/suites_oaipmh_get_illegal_verb.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<oai:OAI-PMH xmlns:oai_dc="http://www.openarchives.org/OAI/2.0/oai_dc/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:oai="http://www.openarchives.org/OAI/2.0/" xsi:schemaLocation="http://www.openarchives.org/OAI/2.0/ http://www.openarchives.org/OAI/2.0/OAI-PMH.xsd">
+<oai:OAI-PMH xmlns:oai="http://www.openarchives.org/OAI/2.0/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.openarchives.org/OAI/2.0/ http://www.openarchives.org/OAI/2.0/OAI-PMH.xsd">
   <oai:responseDate>PYCSW_TIMESTAMP</oai:responseDate>
   <oai:request foo="bar" verb="foo">http://localhost/pycsw/csw.py?config=tests/suites/oaipmh/default.cfg&mode=oaipmh</oai:request>
   <oai:error code="badArgument">Unknown verb 'foo'</oai:error>
diff --git a/tests/expected/suites_repofilter_post_GetRecordById-masked.xml b/tests/expected/suites_repofilter_post_GetRecordById-masked.xml
index 15857d5..9bf61df 100644
--- a/tests/expected/suites_repofilter_post_GetRecordById-masked.xml
+++ b/tests/expected/suites_repofilter_post_GetRecordById-masked.xml
@@ -1,3 +1,3 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<csw:GetRecordByIdResponse xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ows="http://www.opengis.net/ows" xmlns:fgdc="http://www.opengis.net/cat/csw/c [...]
+<csw:GetRecordByIdResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/cat/csw/2.0.2 http://schemas.opengis.net/csw/2.0.2/CSW-discovery.xsd"/>
diff --git a/tests/expected/suites_repofilter_post_GetRecords-all.xml b/tests/expected/suites_repofilter_post_GetRecords-all.xml
index a374050..99af61e 100644
--- a/tests/expected/suites_repofilter_post_GetRecords-all.xml
+++ b/tests/expected/suites_repofilter_post_GetRecords-all.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<csw:GetRecordsResponse xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ows="http://www.opengis.net/ows" xmlns:fgdc="http://www.opengis.net/cat/csw/csdg [...]
+<csw:GetRecordsResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.0.2" xsi:schemaLocation="http://www.opengis.net/cat/csw/2.0.2 http://schemas.opengis.net/csw/2.0.2/CSW-di [...]
   <csw:SearchStatus timestamp="PYCSW_TIMESTAMP"/>
   <csw:SearchResults nextRecord="0" numberOfRecordsMatched="3" numberOfRecordsReturned="3" recordSchema="http://www.opengis.net/cat/csw/2.0.2" elementSet="full">
     <csw:Record>
diff --git a/tests/expected/suites_sru_get_explain.xml b/tests/expected/suites_sru_get_explain.xml
index 91fc757..3410390 100644
--- a/tests/expected/suites_sru_get_explain.xml
+++ b/tests/expected/suites_sru_get_explain.xml
@@ -1,11 +1,11 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<zs:explainResponse xmlns:zd="http://www.loc.gov/zing/srw/diagnostic/" xmlns:zs="http://www.loc.gov/zing/srw/" xmlns:srw_dc="info:srw/schema/1/dc-schema" xmlns:zr="http://explain.z3950.org/dtd/2.1/" xmlns:sru="http://www.loc.gov/zing/srw/">
-  <zs:version>1.1</zs:version>
-  <zs:record>
-    <zs:recordPacking>XML</zs:recordPacking>
-    <zs:recordSchema>http://explain.z3950.org/dtd/2.1/</zs:recordSchema>
-    <zs:recordData>
+<sru:explainResponse xmlns:sru="http://www.loc.gov/zing/srw/" xmlns:zr="http://explain.z3950.org/dtd/2.1/">
+  <sru:version>1.1</sru:version>
+  <sru:record>
+    <sru:recordPacking>XML</sru:recordPacking>
+    <sru:recordSchema>http://explain.z3950.org/dtd/2.1/</sru:recordSchema>
+    <sru:recordData>
       <zr:explain>
         <zr:serverInfo method="GET POST SOAP" protocol="SRU" transport="http" version="1.1">
           <zr:host>PYCSW_HOST</zr:host>
@@ -18,12 +18,6 @@
         </zr:databaseInfo>
         <zr:indexInfo>
           <zr:set identifier="info:srw/cql-context-set/1/dc-v1.1" name="dc"/>
-          <zr:index id="1034">
-            <zr:title>format</zr:title>
-            <zr:map>
-              <zr:map set="dc">format</zr:map>
-            </zr:map>
-          </zr:index>
           <zr:index id="62">
             <zr:title>abstract</zr:title>
             <zr:map>
@@ -36,10 +30,10 @@
               <zr:map set="dc">contributor</zr:map>
             </zr:map>
           </zr:index>
-          <zr:index id="TBD">
-            <zr:title>relation</zr:title>
+          <zr:index id="1003">
+            <zr:title>creator</zr:title>
             <zr:map>
-              <zr:map set="dc">relation</zr:map>
+              <zr:map set="dc">creator</zr:map>
             </zr:map>
           </zr:index>
           <zr:index id="30">
@@ -48,46 +42,46 @@
               <zr:map set="dc">date</zr:map>
             </zr:map>
           </zr:index>
-          <zr:index id="29">
-            <zr:title>subject</zr:title>
+          <zr:index id="1034">
+            <zr:title>format</zr:title>
             <zr:map>
-              <zr:map set="dc">subject</zr:map>
+              <zr:map set="dc">format</zr:map>
             </zr:map>
           </zr:index>
-          <zr:index id="1018">
-            <zr:title>publisher</zr:title>
+          <zr:index id="12">
+            <zr:title>identifier</zr:title>
             <zr:map>
-              <zr:map set="dc">publisher</zr:map>
+              <zr:map set="dc">identifier</zr:map>
             </zr:map>
           </zr:index>
           <zr:index id="TBD">
-            <zr:title>rights</zr:title>
+            <zr:title>language</zr:title>
             <zr:map>
-              <zr:map set="dc">rights</zr:map>
+              <zr:map set="dc">language</zr:map>
             </zr:map>
           </zr:index>
           <zr:index id="TBD">
-            <zr:title>language</zr:title>
+            <zr:title>modified</zr:title>
             <zr:map>
-              <zr:map set="dc">language</zr:map>
+              <zr:map set="dc">modified</zr:map>
             </zr:map>
           </zr:index>
-          <zr:index id="4">
-            <zr:title>title</zr:title>
+          <zr:index id="1018">
+            <zr:title>publisher</zr:title>
             <zr:map>
-              <zr:map set="dc">title</zr:map>
+              <zr:map set="dc">publisher</zr:map>
             </zr:map>
           </zr:index>
-          <zr:index id="1003">
-            <zr:title>creator</zr:title>
+          <zr:index id="TBD">
+            <zr:title>relation</zr:title>
             <zr:map>
-              <zr:map set="dc">creator</zr:map>
+              <zr:map set="dc">relation</zr:map>
             </zr:map>
           </zr:index>
           <zr:index id="TBD">
-            <zr:title>modified</zr:title>
+            <zr:title>rights</zr:title>
             <zr:map>
-              <zr:map set="dc">modified</zr:map>
+              <zr:map set="dc">rights</zr:map>
             </zr:map>
           </zr:index>
           <zr:index id="TBD">
@@ -96,10 +90,16 @@
               <zr:map set="dc">source</zr:map>
             </zr:map>
           </zr:index>
-          <zr:index id="12">
-            <zr:title>identifier</zr:title>
+          <zr:index id="29">
+            <zr:title>subject</zr:title>
             <zr:map>
-              <zr:map set="dc">identifier</zr:map>
+              <zr:map set="dc">subject</zr:map>
+            </zr:map>
+          </zr:index>
+          <zr:index id="4">
+            <zr:title>title</zr:title>
+            <zr:map>
+              <zr:map set="dc">title</zr:map>
             </zr:map>
           </zr:index>
           <zr:index id="1031">
@@ -123,6 +123,6 @@
           <zr:default type="numberOfRecords">0</zr:default>
         </zr:configInfo>
       </zr:explain>
-    </zs:recordData>
-  </zs:record>
-</zs:explainResponse>
+    </sru:recordData>
+  </sru:record>
+</sru:explainResponse>
diff --git a/tests/expected/suites_sru_get_search.xml b/tests/expected/suites_sru_get_search.xml
index e788077..ce70bc1 100644
--- a/tests/expected/suites_sru_get_search.xml
+++ b/tests/expected/suites_sru_get_search.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<zs:searchRetrieveResponse xmlns:zd="http://www.loc.gov/zing/srw/diagnostic/" xmlns:zs="http://www.loc.gov/zing/srw/" xmlns:srw_dc="info:srw/schema/1/dc-schema" xmlns:zr="http://explain.z3950.org/dtd/2.1/" xmlns:sru="http://www.loc.gov/zing/srw/">
-  <zs:version>1.1</zs:version>
-  <zs:numberOfRecords>5</zs:numberOfRecords>
-</zs:searchRetrieveResponse>
+<sru:searchRetrieveResponse xmlns:sru="http://www.loc.gov/zing/srw/">
+  <sru:version>1.1</sru:version>
+  <sru:numberOfRecords>5</sru:numberOfRecords>
+</sru:searchRetrieveResponse>
diff --git a/tests/expected/suites_sru_get_search_cql.xml b/tests/expected/suites_sru_get_search_cql.xml
index ef71e1e..9a98be9 100644
--- a/tests/expected/suites_sru_get_search_cql.xml
+++ b/tests/expected/suites_sru_get_search_cql.xml
@@ -1,30 +1,30 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<zs:searchRetrieveResponse xmlns:zd="http://www.loc.gov/zing/srw/diagnostic/" xmlns:zs="http://www.loc.gov/zing/srw/" xmlns:srw_dc="info:srw/schema/1/dc-schema" xmlns:zr="http://explain.z3950.org/dtd/2.1/" xmlns:sru="http://www.loc.gov/zing/srw/">
-  <zs:version>1.1</zs:version>
-  <zs:numberOfRecords>2</zs:numberOfRecords>
-  <zs:record>
-    <zs:recordData>
+<sru:searchRetrieveResponse xmlns:sru="http://www.loc.gov/zing/srw/" xmlns:srw_dc="info:srw/schema/1/dc-schema">
+  <sru:version>1.1</sru:version>
+  <sru:numberOfRecords>2</sru:numberOfRecords>
+  <sru:record>
+    <sru:recordData>
       <srw_dc:srw_dc xmlns:dc="http://purl.org/dc/elements/1.1/">
         <dc:identifier>urn:uuid:19887a8a-f6b0-4a63-ae56-7fba0e17801f</dc:identifier>
         <dc:title>Lorem ipsum</dc:title>
         <dc:type>http://purl.org/dc/dcmitype/Image</dc:type>
       </srw_dc:srw_dc>
-    </zs:recordData>
-    <zs:recordPosition>-2</zs:recordPosition>
-  </zs:record>
-  <zs:recordSchema>info:srw/schema/1/dc-v1.1</zs:recordSchema>
-  <zs:recordPacking>xml</zs:recordPacking>
-  <zs:record>
-    <zs:recordData>
+    </sru:recordData>
+    <sru:recordPosition>-2</sru:recordPosition>
+  </sru:record>
+  <sru:recordSchema>info:srw/schema/1/dc-v1.1</sru:recordSchema>
+  <sru:recordPacking>xml</sru:recordPacking>
+  <sru:record>
+    <sru:recordData>
       <srw_dc:srw_dc xmlns:dc="http://purl.org/dc/elements/1.1/">
         <dc:identifier>urn:uuid:a06af396-3105-442d-8b40-22b57a90d2f2</dc:identifier>
         <dc:title>Lorem ipsum dolor sit amet</dc:title>
         <dc:type>http://purl.org/dc/dcmitype/Image</dc:type>
       </srw_dc:srw_dc>
-    </zs:recordData>
-    <zs:recordPosition>-1</zs:recordPosition>
-  </zs:record>
-  <zs:recordSchema>info:srw/schema/1/dc-v1.1</zs:recordSchema>
-  <zs:recordPacking>xml</zs:recordPacking>
-</zs:searchRetrieveResponse>
+    </sru:recordData>
+    <sru:recordPosition>-1</sru:recordPosition>
+  </sru:record>
+  <sru:recordSchema>info:srw/schema/1/dc-v1.1</sru:recordSchema>
+  <sru:recordPacking>xml</sru:recordPacking>
+</sru:searchRetrieveResponse>
diff --git a/tests/expected/suites_sru_get_search_maxrecords.xml b/tests/expected/suites_sru_get_search_maxrecords.xml
index ef6da13..cba2314 100644
--- a/tests/expected/suites_sru_get_search_maxrecords.xml
+++ b/tests/expected/suites_sru_get_search_maxrecords.xml
@@ -1,30 +1,30 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<zs:searchRetrieveResponse xmlns:zd="http://www.loc.gov/zing/srw/diagnostic/" xmlns:zs="http://www.loc.gov/zing/srw/" xmlns:srw_dc="info:srw/schema/1/dc-schema" xmlns:zr="http://explain.z3950.org/dtd/2.1/" xmlns:sru="http://www.loc.gov/zing/srw/">
-  <zs:version>1.1</zs:version>
-  <zs:numberOfRecords>5</zs:numberOfRecords>
-  <zs:record>
-    <zs:recordData>
+<sru:searchRetrieveResponse xmlns:sru="http://www.loc.gov/zing/srw/" xmlns:srw_dc="info:srw/schema/1/dc-schema">
+  <sru:version>1.1</sru:version>
+  <sru:numberOfRecords>5</sru:numberOfRecords>
+  <sru:record>
+    <sru:recordData>
       <srw_dc:srw_dc xmlns:dc="http://purl.org/dc/elements/1.1/">
         <dc:identifier>urn:uuid:19887a8a-f6b0-4a63-ae56-7fba0e17801f</dc:identifier>
         <dc:title>Lorem ipsum</dc:title>
         <dc:type>http://purl.org/dc/dcmitype/Image</dc:type>
       </srw_dc:srw_dc>
-    </zs:recordData>
-    <zs:recordPosition>1</zs:recordPosition>
-  </zs:record>
-  <zs:recordSchema>info:srw/schema/1/dc-v1.1</zs:recordSchema>
-  <zs:recordPacking>xml</zs:recordPacking>
-  <zs:record>
-    <zs:recordData>
+    </sru:recordData>
+    <sru:recordPosition>1</sru:recordPosition>
+  </sru:record>
+  <sru:recordSchema>info:srw/schema/1/dc-v1.1</sru:recordSchema>
+  <sru:recordPacking>xml</sru:recordPacking>
+  <sru:record>
+    <sru:recordData>
       <srw_dc:srw_dc xmlns:dc="http://purl.org/dc/elements/1.1/">
         <dc:identifier>urn:uuid:88247b56-4cbc-4df9-9860-db3f8042e357</dc:identifier>
         <dc:title></dc:title>
         <dc:type>http://purl.org/dc/dcmitype/Dataset</dc:type>
       </srw_dc:srw_dc>
-    </zs:recordData>
-    <zs:recordPosition>2</zs:recordPosition>
-  </zs:record>
-  <zs:recordSchema>info:srw/schema/1/dc-v1.1</zs:recordSchema>
-  <zs:recordPacking>xml</zs:recordPacking>
-</zs:searchRetrieveResponse>
+    </sru:recordData>
+    <sru:recordPosition>2</sru:recordPosition>
+  </sru:record>
+  <sru:recordSchema>info:srw/schema/1/dc-v1.1</sru:recordSchema>
+  <sru:recordPacking>xml</sru:recordPacking>
+</sru:searchRetrieveResponse>
diff --git a/tests/expected/suites_sru_get_search_startrecord_maxrecords.xml b/tests/expected/suites_sru_get_search_startrecord_maxrecords.xml
index ef6da13..cba2314 100644
--- a/tests/expected/suites_sru_get_search_startrecord_maxrecords.xml
+++ b/tests/expected/suites_sru_get_search_startrecord_maxrecords.xml
@@ -1,30 +1,30 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<zs:searchRetrieveResponse xmlns:zd="http://www.loc.gov/zing/srw/diagnostic/" xmlns:zs="http://www.loc.gov/zing/srw/" xmlns:srw_dc="info:srw/schema/1/dc-schema" xmlns:zr="http://explain.z3950.org/dtd/2.1/" xmlns:sru="http://www.loc.gov/zing/srw/">
-  <zs:version>1.1</zs:version>
-  <zs:numberOfRecords>5</zs:numberOfRecords>
-  <zs:record>
-    <zs:recordData>
+<sru:searchRetrieveResponse xmlns:sru="http://www.loc.gov/zing/srw/" xmlns:srw_dc="info:srw/schema/1/dc-schema">
+  <sru:version>1.1</sru:version>
+  <sru:numberOfRecords>5</sru:numberOfRecords>
+  <sru:record>
+    <sru:recordData>
       <srw_dc:srw_dc xmlns:dc="http://purl.org/dc/elements/1.1/">
         <dc:identifier>urn:uuid:19887a8a-f6b0-4a63-ae56-7fba0e17801f</dc:identifier>
         <dc:title>Lorem ipsum</dc:title>
         <dc:type>http://purl.org/dc/dcmitype/Image</dc:type>
       </srw_dc:srw_dc>
-    </zs:recordData>
-    <zs:recordPosition>1</zs:recordPosition>
-  </zs:record>
-  <zs:recordSchema>info:srw/schema/1/dc-v1.1</zs:recordSchema>
-  <zs:recordPacking>xml</zs:recordPacking>
-  <zs:record>
-    <zs:recordData>
+    </sru:recordData>
+    <sru:recordPosition>1</sru:recordPosition>
+  </sru:record>
+  <sru:recordSchema>info:srw/schema/1/dc-v1.1</sru:recordSchema>
+  <sru:recordPacking>xml</sru:recordPacking>
+  <sru:record>
+    <sru:recordData>
       <srw_dc:srw_dc xmlns:dc="http://purl.org/dc/elements/1.1/">
         <dc:identifier>urn:uuid:88247b56-4cbc-4df9-9860-db3f8042e357</dc:identifier>
         <dc:title></dc:title>
         <dc:type>http://purl.org/dc/dcmitype/Dataset</dc:type>
       </srw_dc:srw_dc>
-    </zs:recordData>
-    <zs:recordPosition>2</zs:recordPosition>
-  </zs:record>
-  <zs:recordSchema>info:srw/schema/1/dc-v1.1</zs:recordSchema>
-  <zs:recordPacking>xml</zs:recordPacking>
-</zs:searchRetrieveResponse>
+    </sru:recordData>
+    <sru:recordPosition>2</sru:recordPosition>
+  </sru:record>
+  <sru:recordSchema>info:srw/schema/1/dc-v1.1</sru:recordSchema>
+  <sru:recordPacking>xml</sru:recordPacking>
+</sru:searchRetrieveResponse>
diff --git a/tests/expected/suites_utf-8_post_GetCapabilities.xml b/tests/expected/suites_utf-8_post_GetCapabilities.xml
index e41a829..094ce11 100644
--- a/tests/expected/suites_utf-8_post_GetCapabilities.xml
+++ b/tests/expected/suites_utf-8_post_GetCapabilities.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!-- PYCSW_VERSION -->
-<csw:Capabilities xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope" xmlns:gml="http://www.opengis.net/gml" xmlns:dif="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ows="http://www.opengis.net/ows" xmlns:fgdc="http://www.opengis.net/cat/csw/csdgm" xml [...]
+<csw:Capabilities xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ogc="http://www.opengis.net/ogc" xmlns:ows="http://www.opengis.net/ows" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" updateSequence="PYCSW_UPDATESEQUENCE" ve [...]
   <ows:ServiceIdentification>
     <ows:Title>ErrŹĆŁÓdd</ows:Title>
     <ows:Abstract>pycsw is an OGC CSW server implementation written in Python</ows:Abstract>
@@ -11,6 +11,7 @@
     </ows:Keywords>
     <ows:ServiceType codeSpace="OGC">CSW</ows:ServiceType>
     <ows:ServiceTypeVersion>2.0.2</ows:ServiceTypeVersion>
+    <ows:ServiceTypeVersion>3.0.0</ows:ServiceTypeVersion>
     <ows:Fees>None</ows:Fees>
     <ows:AccessConstraints>None</ows:AccessConstraints>
   </ows:ServiceIdentification>
@@ -49,19 +50,12 @@
         </ows:HTTP>
       </ows:DCP>
       <ows:Parameter name="sections">
+        <ows:Value>Filter_Capabilities</ows:Value>
+        <ows:Value>OperationsMetadata</ows:Value>
         <ows:Value>ServiceIdentification</ows:Value>
         <ows:Value>ServiceProvider</ows:Value>
-        <ows:Value>OperationsMetadata</ows:Value>
-        <ows:Value>Filter_Capabilities</ows:Value>
       </ows:Parameter>
     </ows:Operation>
-    <ows:Operation name="GetRepositoryItem">
-      <ows:DCP>
-        <ows:HTTP>
-          <ows:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/utf-8/default.cfg"/>
-        </ows:HTTP>
-      </ows:DCP>
-    </ows:Operation>
     <ows:Operation name="DescribeRecord">
       <ows:DCP>
         <ows:HTTP>
@@ -69,14 +63,14 @@
           <ows:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/utf-8/default.cfg"/>
         </ows:HTTP>
       </ows:DCP>
-      <ows:Parameter name="schemaLanguage">
-        <ows:Value>http://www.w3.org/XML/Schema</ows:Value>
-        <ows:Value>http://www.w3.org/TR/xmlschema-1/</ows:Value>
-        <ows:Value>http://www.w3.org/2001/XMLSchema</ows:Value>
-      </ows:Parameter>
       <ows:Parameter name="outputFormat">
-        <ows:Value>application/xml</ows:Value>
         <ows:Value>application/json</ows:Value>
+        <ows:Value>application/xml</ows:Value>
+      </ows:Parameter>
+      <ows:Parameter name="schemaLanguage">
+        <ows:Value>http://www.w3.org/2001/XMLSchema</ows:Value>
+        <ows:Value>http://www.w3.org/TR/xmlschema-1/</ows:Value>
+        <ows:Value>http://www.w3.org/XML/Schema</ows:Value>
       </ows:Parameter>
       <ows:Parameter name="typeName">
         <ows:Value>csw:Record</ows:Value>
@@ -90,64 +84,47 @@
         </ows:HTTP>
       </ows:DCP>
       <ows:Parameter name="ParameterName">
+        <ows:Value>DescribeRecord.outputFormat</ows:Value>
+        <ows:Value>DescribeRecord.schemaLanguage</ows:Value>
+        <ows:Value>DescribeRecord.typeName</ows:Value>
+        <ows:Value>GetCapabilities.sections</ows:Value>
+        <ows:Value>GetRecordById.ElementSetName</ows:Value>
+        <ows:Value>GetRecordById.outputFormat</ows:Value>
+        <ows:Value>GetRecordById.outputSchema</ows:Value>
+        <ows:Value>GetRecords.CONSTRAINTLANGUAGE</ows:Value>
+        <ows:Value>GetRecords.ElementSetName</ows:Value>
         <ows:Value>GetRecords.outputFormat</ows:Value>
         <ows:Value>GetRecords.outputSchema</ows:Value>
-        <ows:Value>GetRecords.CONSTRAINTLANGUAGE</ows:Value>
         <ows:Value>GetRecords.resultType</ows:Value>
         <ows:Value>GetRecords.typeNames</ows:Value>
-        <ows:Value>GetRecords.ElementSetName</ows:Value>
-        <ows:Value>GetCapabilities.sections</ows:Value>
-        <ows:Value>GetRecordById.outputFormat</ows:Value>
-        <ows:Value>GetRecordById.outputSchema</ows:Value>
-        <ows:Value>GetRecordById.ElementSetName</ows:Value>
-        <ows:Value>DescribeRecord.schemaLanguage</ows:Value>
-        <ows:Value>DescribeRecord.outputFormat</ows:Value>
-        <ows:Value>DescribeRecord.typeName</ows:Value>
       </ows:Parameter>
     </ows:Operation>
-    <ows:Operation name="GetRecordById">
+    <ows:Operation name="GetRecords">
       <ows:DCP>
         <ows:HTTP>
           <ows:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/utf-8/default.cfg"/>
           <ows:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/utf-8/default.cfg"/>
         </ows:HTTP>
       </ows:DCP>
-      <ows:Parameter name="outputFormat">
-        <ows:Value>application/xml</ows:Value>
-        <ows:Value>application/json</ows:Value>
-      </ows:Parameter>
-      <ows:Parameter name="outputSchema">
-        <ows:Value>http://www.opengis.net/cat/csw/2.0.2</ows:Value>
-        <ows:Value>http://www.w3.org/2005/Atom</ows:Value>
-        <ows:Value>http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/</ows:Value>
-        <ows:Value>http://www.opengis.net/cat/csw/csdgm</ows:Value>
+      <ows:Parameter name="CONSTRAINTLANGUAGE">
+        <ows:Value>CQL_TEXT</ows:Value>
+        <ows:Value>FILTER</ows:Value>
       </ows:Parameter>
       <ows:Parameter name="ElementSetName">
         <ows:Value>brief</ows:Value>
-        <ows:Value>summary</ows:Value>
         <ows:Value>full</ows:Value>
+        <ows:Value>summary</ows:Value>
       </ows:Parameter>
-    </ows:Operation>
-    <ows:Operation name="GetRecords">
-      <ows:DCP>
-        <ows:HTTP>
-          <ows:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/utf-8/default.cfg"/>
-          <ows:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/utf-8/default.cfg"/>
-        </ows:HTTP>
-      </ows:DCP>
       <ows:Parameter name="outputFormat">
-        <ows:Value>application/xml</ows:Value>
         <ows:Value>application/json</ows:Value>
+        <ows:Value>application/xml</ows:Value>
       </ows:Parameter>
       <ows:Parameter name="outputSchema">
-        <ows:Value>http://www.opengis.net/cat/csw/2.0.2</ows:Value>
-        <ows:Value>http://www.w3.org/2005/Atom</ows:Value>
         <ows:Value>http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/</ows:Value>
+        <ows:Value>http://www.interlis.ch/INTERLIS2.3</ows:Value>
+        <ows:Value>http://www.opengis.net/cat/csw/2.0.2</ows:Value>
         <ows:Value>http://www.opengis.net/cat/csw/csdgm</ows:Value>
-      </ows:Parameter>
-      <ows:Parameter name="CONSTRAINTLANGUAGE">
-        <ows:Value>FILTER</ows:Value>
-        <ows:Value>CQL_TEXT</ows:Value>
+        <ows:Value>http://www.w3.org/2005/Atom</ows:Value>
       </ows:Parameter>
       <ows:Parameter name="resultType">
         <ows:Value>hits</ows:Value>
@@ -157,39 +134,66 @@
       <ows:Parameter name="typeNames">
         <ows:Value>csw:Record</ows:Value>
       </ows:Parameter>
-      <ows:Parameter name="ElementSetName">
-        <ows:Value>brief</ows:Value>
-        <ows:Value>summary</ows:Value>
-        <ows:Value>full</ows:Value>
-      </ows:Parameter>
       <ows:Constraint name="SupportedDublinCoreQueryables">
+        <ows:Value>csw:AnyText</ows:Value>
         <ows:Value>dc:contributor</ows:Value>
-        <ows:Value>dc:source</ows:Value>
-        <ows:Value>dc:language</ows:Value>
-        <ows:Value>dc:title</ows:Value>
-        <ows:Value>dc:subject</ows:Value>
         <ows:Value>dc:creator</ows:Value>
-        <ows:Value>dc:type</ows:Value>
-        <ows:Value>ows:BoundingBox</ows:Value>
-        <ows:Value>dct:modified</ows:Value>
-        <ows:Value>dct:abstract</ows:Value>
-        <ows:Value>dc:relation</ows:Value>
         <ows:Value>dc:date</ows:Value>
+        <ows:Value>dc:format</ows:Value>
         <ows:Value>dc:identifier</ows:Value>
+        <ows:Value>dc:language</ows:Value>
         <ows:Value>dc:publisher</ows:Value>
-        <ows:Value>dc:format</ows:Value>
-        <ows:Value>csw:AnyText</ows:Value>
+        <ows:Value>dc:relation</ows:Value>
         <ows:Value>dc:rights</ows:Value>
+        <ows:Value>dc:source</ows:Value>
+        <ows:Value>dc:subject</ows:Value>
+        <ows:Value>dc:title</ows:Value>
+        <ows:Value>dc:type</ows:Value>
+        <ows:Value>dct:abstract</ows:Value>
+        <ows:Value>dct:modified</ows:Value>
+        <ows:Value>ows:BoundingBox</ows:Value>
       </ows:Constraint>
     </ows:Operation>
-    <ows:Parameter name="version">
-      <ows:Value>2.0.2</ows:Value>
-    </ows:Parameter>
+    <ows:Operation name="GetRecordById">
+      <ows:DCP>
+        <ows:HTTP>
+          <ows:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/utf-8/default.cfg"/>
+          <ows:Post xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/utf-8/default.cfg"/>
+        </ows:HTTP>
+      </ows:DCP>
+      <ows:Parameter name="ElementSetName">
+        <ows:Value>brief</ows:Value>
+        <ows:Value>full</ows:Value>
+        <ows:Value>summary</ows:Value>
+      </ows:Parameter>
+      <ows:Parameter name="outputFormat">
+        <ows:Value>application/json</ows:Value>
+        <ows:Value>application/xml</ows:Value>
+      </ows:Parameter>
+      <ows:Parameter name="outputSchema">
+        <ows:Value>http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/</ows:Value>
+        <ows:Value>http://www.interlis.ch/INTERLIS2.3</ows:Value>
+        <ows:Value>http://www.opengis.net/cat/csw/2.0.2</ows:Value>
+        <ows:Value>http://www.opengis.net/cat/csw/csdgm</ows:Value>
+        <ows:Value>http://www.w3.org/2005/Atom</ows:Value>
+      </ows:Parameter>
+    </ows:Operation>
+    <ows:Operation name="GetRepositoryItem">
+      <ows:DCP>
+        <ows:HTTP>
+          <ows:Get xlink:type="simple" xlink:href="http://localhost/pycsw/csw.py?config=tests/suites/utf-8/default.cfg"/>
+        </ows:HTTP>
+      </ows:DCP>
+    </ows:Operation>
     <ows:Parameter name="service">
       <ows:Value>CSW</ows:Value>
     </ows:Parameter>
-    <ows:Constraint name="XPathQueryables">
-      <ows:Value>allowed</ows:Value>
+    <ows:Parameter name="version">
+      <ows:Value>2.0.2</ows:Value>
+      <ows:Value>3.0.0</ows:Value>
+    </ows:Parameter>
+    <ows:Constraint name="FederatedCatalogues">
+      <ows:Value>http://demo.pycsw.org/gisdata/csw</ows:Value>
     </ows:Constraint>
     <ows:Constraint name="MaxRecordDefault">
       <ows:Value>10</ows:Value>
@@ -198,8 +202,8 @@
       <ows:Value>XML</ows:Value>
       <ows:Value>SOAP</ows:Value>
     </ows:Constraint>
-    <ows:Constraint name="FederatedCatalogues">
-      <ows:Value>http://demo.pycsw.org/gisdata/csw</ows:Value>
+    <ows:Constraint name="XPathQueryables">
+      <ows:Value>allowed</ows:Value>
     </ows:Constraint>
   </ows:OperationsMetadata>
   <ogc:Filter_Capabilities>
@@ -229,11 +233,11 @@
       <ogc:ComparisonOperators>
         <ogc:ComparisonOperator>Between</ogc:ComparisonOperator>
         <ogc:ComparisonOperator>EqualTo</ogc:ComparisonOperator>
-        <ogc:ComparisonOperator>LessThanEqualTo</ogc:ComparisonOperator>
         <ogc:ComparisonOperator>GreaterThan</ogc:ComparisonOperator>
-        <ogc:ComparisonOperator>Like</ogc:ComparisonOperator>
-        <ogc:ComparisonOperator>LessThan</ogc:ComparisonOperator>
         <ogc:ComparisonOperator>GreaterThanEqualTo</ogc:ComparisonOperator>
+        <ogc:ComparisonOperator>LessThan</ogc:ComparisonOperator>
+        <ogc:ComparisonOperator>LessThanEqualTo</ogc:ComparisonOperator>
+        <ogc:ComparisonOperator>Like</ogc:ComparisonOperator>
         <ogc:ComparisonOperator>NotEqualTo</ogc:ComparisonOperator>
         <ogc:ComparisonOperator>NullCheck</ogc:ComparisonOperator>
       </ogc:ComparisonOperators>
diff --git a/tests/gen_html.py b/tests/gen_html.py
index e4be2cc..b8f4ebe 100644
--- a/tests/gen_html.py
+++ b/tests/gen_html.py
@@ -3,7 +3,7 @@
 #
 # Authors: Tom Kralidis <tomkralidis at gmail.com>
 #
-# Copyright (c) 2011 Tom Kralidis
+# Copyright (c) 2015 Tom Kralidis
 #
 # Permission is hereby granted, free of charge, to any person
 # obtaining a copy of this software and associated documentation
@@ -30,11 +30,11 @@
 
 import csv
 import os
-from urllib2 import quote
+from six.moves.urllib.parse import quote
 
 JQUERY_VERSION = '1.9.0'
 
-print '''
+print('''
 <!DOCTYPE html>
 <html lang="en">
     <head>
@@ -86,9 +86,9 @@ print '''
             });
         </script>
     </head>
-''' % JQUERY_VERSION
+''' % JQUERY_VERSION)
 
-print '''
+print('''
     <body>
         <h2 class="header">pycsw Tester</h2>
         <hr/>
@@ -102,15 +102,15 @@ print '''
                 <tr>
                     <td>
                         <select class="xml">
-                            <option value="none">Select a CSW Request</option>'''
+                            <option value="none">Select a CSW Request</option>''')
 
 for root, dirs, files in os.walk('suites'):
     if files:
         for sfile in files:
             if os.path.splitext(sfile)[1] in ['.xml']:  # it's a POST request
                 query = '%s%s%s' % (root.replace(os.sep, '/'), '/', sfile)
-                print '                            <option value="tests/suites/%s/default.cfg,%s">%s</option>' % (root.split(os.sep)[1], query, query)
-print '''
+                print('                            <option value="tests/suites/%s/default.cfg,%s">%s</option>' % (root.split(os.sep)[1], query, query))
+print('''
                         </select>
                         <input type="button" class="send" value="Send"/>
                     </td>
@@ -131,17 +131,19 @@ print '''
         <hr/>
         <h3 class="header">HTTP GET</h3>
             <ul>
-'''
+''')
+
 for root, dirs, files in os.walk('suites'):
     if files:
         for sfile in files:
             if sfile == 'requests.txt':  # it's a list of GET requests
-                gets = csv.reader(open('%s%s%s' % (root.replace(os.sep, '/'), '/', sfile)))
-                for row in gets:
-                    baseurl, query_string = row[1].split('?')
-                    query = '%s?%s' % (baseurl.replace('PYCSW_SERVER', '../csw.py'), query_string.replace('&', '&'))
-                    print '<li><a href="%s">%s</a></li>' % (query, row[0])
-print '''
+                with open('%s%s%s' % (root.replace(os.sep, '/'), '/', sfile)) as f:
+                    gets = csv.reader(f)
+                    for row in gets:
+                        baseurl, query_string = row[1].split('?')
+                        query = '%s?%s' % (baseurl.replace('PYCSW_SERVER', '../csw.py'), query_string.replace('&', '&'))
+                        print('<li><a href="%s">%s</a></li>' % (query, row[0]))
+print('''
             </ul>
         <hr/>
         <footer>
@@ -150,4 +152,4 @@ print '''
         </footer>
     </body>
 </html>
-'''
+''')
diff --git a/tests/index.html b/tests/index.html
index ded3c1e..8db0d2e 100644
--- a/tests/index.html
+++ b/tests/index.html
@@ -160,6 +160,17 @@
                             <option value="tests/suites/cite/default.cfg,suites/cite/post/f7d79701-f10b-4087-a33c-f62df0a04fd1.xml">suites/cite/post/f7d79701-f10b-4087-a33c-f62df0a04fd1.xml</option>
                             <option value="tests/suites/cite/default.cfg,suites/cite/post/fc1bc094-88f1-4851-bc2b-dfc56be9f3c7.xml">suites/cite/post/fc1bc094-88f1-4851-bc2b-dfc56be9f3c7.xml</option>
                             <option value="tests/suites/cite/default.cfg,suites/cite/post/fe20960f-a26c-4f13-852d-470a0d3233f9.xml">suites/cite/post/fe20960f-a26c-4f13-852d-470a0d3233f9.xml</option>
+                            <option value="tests/suites/csw30/default.cfg,suites/csw30/post/Exception-GetDomain-parametername-bad.xml">suites/csw30/post/Exception-GetDomain-parametername-bad.xml</option>
+                            <option value="tests/suites/csw30/default.cfg,suites/csw30/post/Exception-GetDomain-valuereference-bad.xml">suites/csw30/post/Exception-GetDomain-valuereference-bad.xml</option>
+                            <option value="tests/suites/csw30/default.cfg,suites/csw30/post/Exception-GetRecordById-404.xml">suites/csw30/post/Exception-GetRecordById-404.xml</option>
+                            <option value="tests/suites/csw30/default.cfg,suites/csw30/post/Exception-GetRecordById-bad-esn.xml">suites/csw30/post/Exception-GetRecordById-bad-esn.xml</option>
+                            <option value="tests/suites/csw30/default.cfg,suites/csw30/post/Exception-bad-xml.xml">suites/csw30/post/Exception-bad-xml.xml</option>
+                            <option value="tests/suites/csw30/default.cfg,suites/csw30/post/Exception-not-xml.xml">suites/csw30/post/Exception-not-xml.xml</option>
+                            <option value="tests/suites/csw30/default.cfg,suites/csw30/post/GetCapabilities.xml">suites/csw30/post/GetCapabilities.xml</option>
+                            <option value="tests/suites/csw30/default.cfg,suites/csw30/post/GetDomain-parametername.xml">suites/csw30/post/GetDomain-parametername.xml</option>
+                            <option value="tests/suites/csw30/default.cfg,suites/csw30/post/GetDomain-valuereference.xml">suites/csw30/post/GetDomain-valuereference.xml</option>
+                            <option value="tests/suites/csw30/default.cfg,suites/csw30/post/GetRecordById-dc-full.xml">suites/csw30/post/GetRecordById-dc-full.xml</option>
+                            <option value="tests/suites/csw30/default.cfg,suites/csw30/post/GetRecordById-dc.xml">suites/csw30/post/GetRecordById-dc.xml</option>
                             <option value="tests/suites/default/default.cfg,suites/default/post/DescribeRecord-json.xml">suites/default/post/DescribeRecord-json.xml</option>
                             <option value="tests/suites/default/default.cfg,suites/default/post/DescribeRecord.xml">suites/default/post/DescribeRecord.xml</option>
                             <option value="tests/suites/default/default.cfg,suites/default/post/Exception-GetRecords-badsrsname.xml">suites/default/post/Exception-GetRecords-badsrsname.xml</option>
@@ -217,6 +228,8 @@
                             <option value="tests/suites/fgdc/default.cfg,suites/fgdc/post/DescribeRecord.xml">suites/fgdc/post/DescribeRecord.xml</option>
                             <option value="tests/suites/fgdc/default.cfg,suites/fgdc/post/GetCapabilities.xml">suites/fgdc/post/GetCapabilities.xml</option>
                             <option value="tests/suites/fgdc/default.cfg,suites/fgdc/post/GetRecords-filter-bbox.xml">suites/fgdc/post/GetRecords-filter-bbox.xml</option>
+                            <option value="tests/suites/gm03/default.cfg,suites/gm03/post/GetCapabilities.xml">suites/gm03/post/GetCapabilities.xml</option>
+                            <option value="tests/suites/gm03/default.cfg,suites/gm03/post/GetRecords-filter-bbox.xml">suites/gm03/post/GetRecords-filter-bbox.xml</option>
                             <option value="tests/suites/harvesting/default.cfg,suites/harvesting/post/Clear-000-delete-all.xml">suites/harvesting/post/Clear-000-delete-all.xml</option>
                             <option value="tests/suites/harvesting/default.cfg,suites/harvesting/post/Exception-Havest-csw-404.xml">suites/harvesting/post/Exception-Havest-csw-404.xml</option>
                             <option value="tests/suites/harvesting/default.cfg,suites/harvesting/post/GetCapabilities.xml">suites/harvesting/post/GetCapabilities.xml</option>
@@ -235,6 +248,7 @@
                             <option value="tests/suites/harvesting/default.cfg,suites/harvesting/post/Harvest-wfs.xml">suites/harvesting/post/Harvest-wfs.xml</option>
                             <option value="tests/suites/harvesting/default.cfg,suites/harvesting/post/Harvest-wms-run1.xml">suites/harvesting/post/Harvest-wms-run1.xml</option>
                             <option value="tests/suites/harvesting/default.cfg,suites/harvesting/post/Harvest-wms-run2.xml">suites/harvesting/post/Harvest-wms-run2.xml</option>
+                            <option value="tests/suites/harvesting/default.cfg,suites/harvesting/post/Harvest-wmts.xml">suites/harvesting/post/Harvest-wmts.xml</option>
                             <option value="tests/suites/harvesting/default.cfg,suites/harvesting/post/Harvest-wps.xml">suites/harvesting/post/Harvest-wps.xml</option>
                             <option value="tests/suites/harvesting/default.cfg,suites/harvesting/post/Harvest-zzz-post-GetRecords-filter-ows-dc.xml">suites/harvesting/post/Harvest-zzz-post-GetRecords-filter-ows-dc.xml</option>
                             <option value="tests/suites/harvesting/default.cfg,suites/harvesting/post/Harvest-zzz-post-GetRecords-filter-sos-abstract-dc.xml">suites/harvesting/post/Harvest-zzz-post-GetRecords-filter-sos-abstract-dc.xml</option>
@@ -322,6 +336,88 @@
 <li><a href="../csw.py?config=tests/suites/cite/default.cfg&request=GetCapabilities">c4ea754f-c158-4d8d-8253-dc8f86021b52</a></li>
 <li><a href="../csw.py?config=tests/suites/cite/default.cfg&service=CSW&version=2.0.2&request=GetCapabilities">f4692ec5-9547-4a05-88ab-e6154af2640a</a></li>
 <li><a href="../csw.py?config=tests/suites/cite/default.cfg&service=CSW&version=2.0.2&request=GetRecordById&id=urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63">f997f25e-c865-4d53-a362-0ed1846337f2</a></li>
+<li><a href="../csw.py?config=tests/suites/csw30/default.cfg">GetCapabilities-base-url</a></li>
+<li><a href="../csw.py?config=tests/suites/csw30/default.cfg&service=CSW&request=GetCapabilities">GetCapabilities-no-version</a></li>
+<li><a href="../csw.py?config=tests/suites/csw30/default.cfg&service=CSW&version=3.0.0&request=GetCapabilities">GetCapabilities</a></li>
+<li><a href="../csw.py?config=tests/suites/csw30/default.cfg&service=CSW&version=3.0.0&request=GetCapabilities-foo">Exception-invalid-request</a></li>
+<li><a href="../csw.py?config=tests/suites/csw30/default.cfg&service=CSW&version=3.0.0&request=GetDomain">Exception-GetDomain</a></li>
+<li><a href="../csw.py?config=tests/suites/csw30/default.cfg&service=CSW&version=3.0.0&request=GetDomain&parametername=GetRecords.ElementSetName">GetDomain-parameter</a></li>
+<li><a href="../csw.py?config=tests/suites/csw30/default.cfg&service=CSW&version=3.0.0&request=GetDomain&valuereference=dc:title">GetDomain-value-reference</a></li>
+<li><a href="../csw.py?config=tests/suites/csw30/default.cfg&service=CSW&version=3.0.0&request=GetDomain&valuereference=dc:title2">Exception-GetDomain-value-reference</a></li>
+<li><a href="../csw.py?config=tests/suites/csw30/default.cfg&service=CSW&version=3.0.0&request=GetRecordById&id=urn:uuid:829babb0-b2f1-49e1-8cd5-7b489fe71a1e">Exception-GetRecordById-dc.xml</a></li>
+<li><a href="../csw.py?config=tests/suites/csw30/default.cfg&service=CSW&version=3.0.0&request=GetRecordById&id=does_not_exist2">Exception-GetRecordById-404</a></li>
+<li><a href="../csw.py?config=tests/suites/csw30/default.cfg&mode=opensearch&service=CSW&version=3.0.0&request=GetCapabilities">OpenSearch-description</a></li>
+<li><a href="../csw.py?config=tests/suites/csw30/default.cfg&service=CSW&version=3.0.0&request=GetRepositoryItem&id=urn:uuid:19887a8a-f6b0-4a63-ae56-7fba0e17801f">GetRepositoryItem</a></li>
+<li><a href="../csw.py?config=tests/suites/csw30/default.cfg&service=CSW&version=3.0.0&request=GetRepositoryItem&id=NOTFOUND">Exception-GetRepositoryItem-notfound</a></li>
+<li><a href="../csw.py?config=tests/suites/csw30/default.cfg&mode=opensearch&service=CSW&version=3.0.0&request=GetCapabilities">002258f0-627f-457f-b2ad-025777c77ac8</a></li>
+<li><a href="../csw.py?config=tests/suites/csw30/default.cfg&mode=opensearch&service=CSW&version=3.0.0&request=GetRecords&elementsetname=full&typenames=csw:Record&resulttype=results&q=Fusc%C3%A9%20Land&bbox=&time=/&outputformat=application/atom+xml&startposition=1&maxrecords=&recordids=">045c600d-973d-41eb-9f60-eba1b717b720</a></li>
+<li><a href="../csw.py?config=tests/suites/csw30/default.cfg&elementSetName=summary&outputFormat=application/atom%2Bxml&request=GetRecords&service=CSW&typeNames=Record&version=3.0.0">0bbcf862-5211-4351-9988-63f8bec49c98</a></li>
+<li><a href="../csw.py?config=tests/suites/csw30/default.cfg">0bdf8457-971e-4ed1-be4a-5feca4dcd8fa</a></li>
+<li><a href="../csw.py?config=tests/suites/csw30/default.cfg&elementName=tns:title&request=GetRecords&service=CSW&typeNames=Record&namespace=xmlns(tns%3Dhttp://purl.org/dc/elements/1.1/)&version=3.0.0">0d8bbdec-0846-42ca-8dc8-b7f4cba41d67</a></li>
+<li><a href="../csw.py?config=tests/suites/csw30/default.cfg&mode=opensearch&service=CSW&version=3.0.0&request=GetRecords&elementsetname=full&typenames=csw:Record&resulttype=results&q=lpppclq&bbox=&time=/&outputformat=application/atom+xml&startposition=1&maxrecords=&recordids=">0e1dca37-477a-4060-99fe-7799b52d656c</a></li>
+<li><a href="../csw.py?config=tests/suites/csw30/default.cfg&elementSetName=full&maxRecords=20&request=GetRecords&service=CSW&typeNames=Record&version=3.0.0">13c87956-51a4-4780-a8e9-6e0b5c0bb473</a></li>
+<li><a href="../csw.py?config=tests/suites/csw30/default.cfg&acceptFormats=model/x3d%2Bxml&acceptVersions=3.0.0&request=GetCapabilities&service=CSW">151d982f-ebd3-4cb2-b507-a667713a1e92</a></li>
+<li><a href="../csw.py?config=tests/suites/csw30/default.cfg&acceptVersions=3.0.0&request=GetCapabilities">1869e495-1a61-4713-8285-76d1336ee1a6</a></li>
+<li><a href="../csw.py?config=tests/suites/csw30/default.cfg&request=GetRecordById&service=CSW&version=3.0.0">1bcb42a9-538c-4f0a-9d4c-d6f10b720aa6</a></li>
+<li><a href="../csw.py?config=tests/suites/csw30/default.cfg">22f44168-2ccf-4801-ad96-204212566d56</a></li>
+<li><a href="../csw.py?config=tests/suites/csw30/default.cfg&acceptVersions=3.0.0&sections=All&request=GetCapabilities&service=CSW">2499a9c9-8d33-449c-bc92-d494adfcc84d</a></li>
+<li><a href="../csw.py?config=tests/suites/csw30/default.cfg&acceptFormats=application/xml&acceptVersions=3.0.0&request=GetCapabilities&service=CSW">27f4f39c-d92a-4e3c-b961-c6aa8c24e513</a></li>
+<li><a href="../csw.py?config=tests/suites/csw30/default.cfg&id=urn:uuid:a06af396-3105-442d-8b40-22b57a90d2f2&request=GetRecordById&service=CSW&version=3.0.0">28e569df-8596-4128-8d9a-29ad03138915</a></li>
+<li><a href="../csw.py?config=tests/suites/csw30/default.cfg">2b06a5c8-0df2-4af1-8d2e-a425de11c845</a></li>
+<li><a href="../csw.py?config=tests/suites/csw30/default.cfg&maxRecords=2&elementSetName=summary&outputFormat=application/atom%2Bxml&request=GetRecords&service=CSW&typeNames=csw3:Record&startPosition=3&namespace=xmlns(csw3%3Dhttp://www.opengis.net/cat/csw/3.0)&version=3.0.0">2ba1418a-444d-4cce-9cfe-4c94efcf8b55</a></li>
+<li><a href="../csw.py?config=tests/suites/csw30/default.cfg&service=CSW&version=3.0.0&request=GetRecords&elementsetname=full&typenames=csw:Record&resulttype=results&q=ipsum&bbox=&time=/&outputformat=application/xml&outputschema=http://www.opengis.net/cat/csw/3.0&startposition=1&maxrecords=&recordids=">397fe17a-d5b4-4f96-8cc4-4ce467ed4d0a</a></li>
+<li><a href="../csw.py?config=tests/suites/csw30/default.cfg&elementSetName=brief&request=GetRecords&service=CSW&typeNames=tns:Record&namespace=xmlns(tns%3Dhttp://www.opengis.net/cat/csw/3.0)&version=3.0.0">3dcd1b15-73d2-4b7d-a3e3-ff15bf14aae4</a></li>
+<li><a href="../csw.py?config=tests/suites/csw30/default.cfg&elementSetName=summary&recordIds=urn:uuid:19887a8a-f6b0-4a63-ae56-7fba0e17801f">405e1ff1-5c75-4846-a28b-cfaff2a6921a</a></li>
+<li><a href="../csw.py?config=tests/suites/csw30/default.cfg">43cd6471-6ac7-45bd-8ff9-148cb2de9a52</a></li>
+<li><a href="../csw.py?config=tests/suites/csw30/default.cfg&acceptVersions=3.0.0&sections=ServiceIdentification&request=GetCapabilities&service=CSW">4566d2ec-1283-4a02-baed-a74fc5b47e37</a></li>
+<li><a href="../csw.py?config=tests/suites/csw30/default.cfg&acceptVersions=3.0.0&sections=Filter_Capabilities&request=GetCapabilities&service=CSW">461bd4c5-6623-490d-9036-d91a2201e87b</a></li>
+<li><a href="../csw.py?config=tests/suites/csw30/default.cfg&service=CSW&version=3.0.0&request=GetRecords&elementsetname=full&typenames=csw:Record&resulttype=results&q=&bbox=514432">5496894a-3877-4f62-a20b-5d7126f94925</a></li>
+<li><a href="../csw.py?config=tests/suites/csw30/default.cfg&service=CSW&version=3.0.0&request=GetRecords&elementsetname=full&typenames=csw:Record&resulttype=results&q=&bbox=-6.17">5a015f6a-bf14-4977-b1e3-6577eb0223c8</a></li>
+<li><a href="../csw.py?config=tests/suites/csw30/default.cfg&id=urn:uuid:88247b56-4cbc-4df9-9860-db3f8042e357&outputFormat=model/vnd.collada%2Bxml&request=GetRecordById&service=CSW&version=3.0.0">5c3a2390-1fb9-43f0-b96c-f48c7a69c990</a></li>
+<li><a href="../csw.py?config=tests/suites/csw30/default.cfg&acceptVersions=3.0.0&sections=OperationsMetadata&request=GetCapabilities&service=CSW">5e9e67dc-18d6-4645-8111-c6263c88a61f</a></li>
+<li><a href="../csw.py?config=tests/suites/csw30/default.cfg&elementSetName=full&q=amet&request=GetRecords&service=CSW&typeNames=Record&version=3.0.0">604d9379-741c-42e5-b4cf-92e56c87fa64</a></li>
+<li><a href="../csw.py?config=tests/suites/csw30/default.cfg&request=GetRecords&service=CSW&typeNames=UnknownType&version=3.0.0">60e6af95-d5fc-465a-82e2-fd2e6d85e4af</a></li>
+<li><a href="../csw.py?config=tests/suites/csw30/default.cfg&mode=opensearch&service=CSW&version=3.0.0&request=GetRecords&elementsetname=full&typenames=csw:Record&resulttype=results&q=&bbox=&time=/&outputformat=application/atom+xml&startposition=1&maxrecords=&recordids=uid-bc5017e6-5cc8-4b03-aee7-d88f88caba0a">62ad94c2-b558-4265-a427-23d6677975d6</a></li>
+<li><a href="../csw.py?config=tests/suites/csw30/default.cfg&elementSetName=undefined-view&request=GetRecords&service=CSW&typeNames=Record&version=3.0.0">6a5e247b-0961-4b8a-a0d6-35a491d9cfe7</a></li>
+<li><a href="../csw.py?config=tests/suites/csw30/default.cfg">6a9d0558-9d87-495b-b999-b49a3ef1cf99</a></li>
+<li><a href="../csw.py?config=tests/suites/csw30/default.cfg&service=CSW&version=3.0.0&request=GetRecords&elementsetname=full&typenames=csw:Record&resulttype=results&q=Fusc%C3%A9%20Land&bbox=&time=/&outputformat=application/xml&outputschema=http://www.opengis.net/cat/csw/3.0&startposition=1&maxrecords=&recordids=">6bd790c9-6019-4652-9c91-330a894d6700</a></li>
+<li><a href="../csw.py?config=tests/suites/csw30/default.cfg&acceptVersions=3.0.0&request=GetCapabilities&service=CSW">6e9cba43-5e27-415d-adbd-a92851c2c173</a></li>
+<li><a href="../csw.py?config=tests/suites/csw30/default.cfg&id=urn:uuid:66ae76b7-54ba-489b-a582-0f0633d96493&request=GetRecordById&service=CSW&version=3.0.0">7630d230-e142-4a09-accf-f091000b90cd</a></li>
+<li><a href="../csw.py?config=tests/suites/csw30/default.cfg&acceptFormats=text/xml&acceptVersions=3.0.0&request=GetCapabilities&service=CSW">7e82446a-b5dc-43fe-9a73-4cc1f2f2f0bf</a></li>
+<li><a href="../csw.py?config=tests/suites/csw30/default.cfg">8025978e-1a35-4d70-80c2-e8329e0c7864</a></li>
+<li><a href="../csw.py?config=tests/suites/csw30/default.cfg&elementSetName=brief&bbox=44.79">8184ae4f-536d-4978-8b28-ad703be96967</a></li>
+<li><a href="../csw.py?config=tests/suites/csw30/default.cfg&maxRecords=15&elementSetName=summary&q=Mauris&bbox=-6.17">88f63a89-664f-4315-b4f8-04a0b33803a7</a></li>
+<li><a href="../csw.py?config=tests/suites/csw30/default.cfg&id=urn:example:1461546298217&request=GetRecordById&service=CSW&version=3.0.0">8987f8f0-4d93-4481-968c-a2ccbd6b8be2</a></li>
+<li><a href="../csw.py?config=tests/suites/csw30/default.cfg&mode=opensearch&service=CSW&version=3.0.0&request=GetRecords&elementsetname=full&typenames=csw:Record&resulttype=results&q=&bbox=-180">8e5fa0f6-3f29-4d1f-abe2-d9866f3def98</a></li>
+<li><a href="../csw.py?config=tests/suites/csw30/default.cfg&acceptVersions=9999.12.31&request=GetCapabilities&service=CSW">9000ec29-5649-474e-b2d6-55c00f8a52c0</a></li>
+<li><a href="../csw.py?config=tests/suites/csw30/default.cfg&elementSetName=summary&bbox=-6.17">91914d35-7bbf-45e6-9b37-5ef484869a4e</a></li>
+<li><a href="../csw.py?config=tests/suites/csw30/default.cfg&elementSetName=full&q=atkovxqmf&request=GetRecords&service=CSW&typeNames=Record&version=3.0.0">92d4844d-57d5-4cf3-8f47-ba50e369dc04</a></li>
+<li><a href="../csw.py?config=tests/suites/csw30/default.cfg&elementSetName=brief&outputSchema=urn:uuid:6a29d2a8-9651-47a6-9b14-f05d2b5644f0&request=GetRecords&service=CSW&typeNames=Record&version=3.0.0">9c0e2a4b-b4e6-41c0-b630-c8c99fc89ff3</a></li>
+<li><a href="../csw.py?config=tests/suites/csw30/default.cfg&id=urn:uuid:1ef30a8b-876d-4828-9246-c37ab4510bbd&outputSchema=http://www.example.org/ns/alpha&request=GetRecordById&service=CSW&version=3.0.0">9d7ffac8-9798-428d-8e27-3cd12497ee6b</a></li>
+<li><a href="../csw.py?config=tests/suites/csw30/default.cfg&id=urn:uuid:829babb0-b2f1-49e1-8cd5-7b489fe71a1e&outputFormat=application/atom%2Bxml&request=GetRecordById&service=CSW&version=3.0.0">a2f18643-e24e-4fa5-b780-6de4a2dbc814</a></li>
+<li><a href="../csw.py?config=tests/suites/csw30/default.cfg&mode=opensearch&service=CSW&version=3.0.0&request=GetRecords&elementsetname=full&typenames=csw:Record&resulttype=results&q=&bbox=514432">abc90c8c-5868-4405-a73e-64c849be3b2a</a></li>
+<li><a href="../csw.py?config=tests/suites/csw30/default.cfg&maxRecords=2&elementSetName=summary&request=GetRecords&service=CSW&typeNames=csw3:Record&startPosition=3&namespace=xmlns(csw3%3Dhttp://www.opengis.net/cat/csw/3.0)&version=3.0.0">ad0c0571-09ed-436a-9a4f-a5de744c88fe</a></li>
+<li><a href="../csw.py?config=tests/suites/csw30/default.cfg&service=CSW&version=3.0.0&request=GetRecords&elementsetname=full&typenames=csw:Record&resulttype=results&q=&bbox=-180">af502903-f4ee-47ee-b76e-af878d238bcc</a></li>
+<li><a href="../csw.py?config=tests/suites/csw30/default.cfg&mode=opensearch&service=CSW&version=3.0.0&request=GetRecords&elementsetname=full&typenames=csw:Record&resulttype=results&q=&bbox=-6.17">b2aafc3f-4f35-47bc-affd-08590972deae</a></li>
+<li><a href="../csw.py?config=tests/suites/csw30/default.cfg&mode=opensearch&service=CSW&version=3.0.0&request=GetRecords&elementsetname=full&typenames=csw:Record&resulttype=results&q=&bbox=&time=/&outputformat=application/atom+xml&startposition=3&maxrecords=4&recordids=">b6069623-f7d8-4021-8582-98f0aea0f763</a></li>
+<li><a href="../csw.py?config=tests/suites/csw30/default.cfg&elementSetName=brief&bbox=472944">b9a07a54-75a8-45bd-b341-2823600211e3</a></li>
+<li><a href="../csw.py?config=tests/suites/csw30/default.cfg&acceptVersions=3.0.0&request=getCapabilities&service=CSW">baa4a7d0-0c01-42b6-adc3-0d03e9949fa3</a></li>
+<li><a href="../csw.py?config=tests/suites/csw30/default.cfg&elementSetName=summary&q=Fusc%C3%A9%20Land&request=GetRecords&service=CSW&typeNames=Record&version=3.0.0">bfbe6409-f64a-4c89-acb3-50f260a5c743</a></li>
+<li><a href="../csw.py?config=tests/suites/csw30/default.cfg&service=CSW&version=3.0.0&request=GetRecords&elementsetname=full&typenames=csw:Record&resulttype=results&q=&bbox=&time=/&outputformat=application/xml&outputschema=http://www.opengis.net/cat/csw/3.0&startposition=3&maxrecords=4&recordids=">bfe20134-d1da-42ef-9c0f-8e1307bbf92b</a></li>
+<li><a href="../csw.py?config=tests/suites/csw30/default.cfg&SERVICE=CSW&Request=GetCapabilities&acceptversions=3.0.0">c03d173a-3f42-4956-89c8-1fe02c3a0873</a></li>
+<li><a href="../csw.py?config=tests/suites/csw30/default.cfg&elementName=undefined&request=GetRecords&service=CSW&typeNames=Record&version=3.0.0">cb43d8c3-e14c-4a9f-9231-4384b7dd21f3</a></li>
+<li><a href="../csw.py?config=tests/suites/csw30/default.cfg&acceptVersions=3.0.0&sections=ServiceProvider&request=GetCapabilities&service=CSW">d03c6fd3-e821-4a26-b62f-d20a474e25af</a></li>
+<li><a href="../csw.py?config=tests/suites/csw30/default.cfg&service=CSW&version=3.0.0&request=GetRecords&elementsetname=full&typenames=csw:Record&resulttype=results&q=&bbox=&time=/&outputformat=application/xml&outputschema=http://www.opengis.net/cat/csw/3.0&startposition=1&maxrecords=&recordids=uid-bc5017e6-5cc8-4b03-aee7-d88f88caba0a">d4ccbf96-a529-480e-a53d-5b88dc1dea7f</a></li>
+<li><a href="../csw.py?config=tests/suites/csw30/default.cfg&service=CSW&version=3.0.0&request=GetRecords&elementsetname=full&typenames=csw:Record&resulttype=results&q=lpppclq&bbox=&time=/&outputformat=application/xml&outputschema=http://www.opengis.net/cat/csw/3.0&startposition=1&maxrecords=&recordids=">d94c801a-1207-4897-b84a-53f3a192515b</a></li>
+<li><a href="../csw.py?config=tests/suites/csw30/default.cfg&id=urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63&elementSetName=full&request=GetRecordById&service=CSW&version=3.0.0">da859e34-91fc-495a-8c09-285a40c0900b</a></li>
+<li><a href="../csw.py?config=tests/suites/csw30/default.cfg&mode=opensearch&service=CSW&version=3.0.0&request=GetRecords&elementsetname=full&typenames=csw:Record&resulttype=results&q=ipsum&bbox=&time=/&outputformat=application/atom+xml&startposition=1&maxrecords=&recordids=">dc246fb8-5af5-4fda-82bb-c18b3ecd439c</a></li>
+<li><a href="../csw.py?config=tests/suites/csw30/default.cfg&mode=opensearch&service=CSW&version=3.0.0&request=GetRecords&elementsetname=full&typenames=csw:Record&resulttype=results&q=&bbox=&time=/&outputformat=application/atom+xml&startposition=1&maxrecords=&recordids=urn%3Auuid%3A94bc9c83-97f6-4b40-9eb8-a8e8787a5c63">de016645-6d5c-4855-943c-2db07ae9f49a</a></li>
+<li><a href="../csw.py?config=tests/suites/csw30/default.cfg&elementSetName=summary&request=GetRecords&service=CSW&typeNames=Record&version=3.0.0">dff3ec6b-bb2d-4887-bd17-8fcf15def042</a></li>
+<li><a href="../csw.py?config=tests/suites/csw30/default.cfg&id=urn:uuid:1ef30a8b-876d-4828-9246-c37ab4510bbd&elementSetName=brief&request=GetRecordById&service=CSW&version=3.0.0">e38e6bfb-8ac4-4ae4-8b87-0aafbc8d3c6b</a></li>
+<li><a href="../csw.py?config=tests/suites/csw30/default.cfg">e67ca935-d65d-4d8c-8302-1405333dded0</a></li>
+<li><a href="../csw.py?config=tests/suites/csw30/default.cfg&elementName=ns1:subject&elementSetName=brief&request=GetRecords&service=CSW&typeNames=Record&namespace=xmlns(ns1%3Dhttp://purl.org/dc/elements/1.1/)&version=3.0.0">e7704509-3441-458f-8ef0-e333c6b6043f</a></li>
+<li><a href="../csw.py?config=tests/suites/csw30/default.cfg&elementSetName=summary&maxRecords=0&q=titles&request=GetRecords&service=CSW&typeNames=Record&version=3.0.0">f1223a49-6d08-44ff-97fe-4c32cbbfad82</a></li>
+<li><a href="../csw.py?config=tests/suites/csw30/default.cfg&elementSetName=full&outputFormat=text/example&request=GetRecords&service=CSW&typeNames=Record&version=3.0.0">f89dd4e1-3a81-4433-afd2-a3fa1bdb1e18</a></li>
 <li><a href="../csw.py?config=tests/suites/default/default.cfg&service=CSW&version=2.0.2&request=GetCapabilities">GetCapabilities</a></li>
 <li><a href="../csw.py?config=tests/suites/default/default.cfg&service=CSW&version=2.0.2&request=GetCapabilitiese">GetCapabilities-invalid-request</a></li>
 <li><a href="../csw.py?config=tests/suites/default/default.cfg&service=CSW&version=2.0.2&request=GetRecords&typenames=csw:Record&elementsetname=full">GetRecords-all</a></li>
@@ -330,6 +426,9 @@
 <li><a href="../csw.py?config=tests/suites/default/default.cfg&service=CSW&version=2.0.2&request=GetRecords&typenames=csw:Record&elementsetname=full&resulttype=results&sortby=dc:titlei:A">GetRecords-sortby-invalid-propertyname</a></li>
 <li><a href="../csw.py?config=tests/suites/default/default.cfg&service=CSW&version=2.0.2&request=GetRecords&typenames=csw:Record&elementsetname=full&resulttype=results&sortby=dc:title:FOO">GetRecords-sortby-invalid-order</a></li>
 <li><a href="../csw.py?config=tests/suites/default/default.cfg&service=CSW&version=2.0.2&request=GetRecords&typenames=csw:Record&elementsetname=full&resulttype=results&constraintlanguage=FILTER&constraint=%3Cogc%3AFilter%20xmlns%3Aogc%3D%22http%3A%2F%2Fwww.opengis.net%2Fogc%22%3E%3Cogc%3APropertyIsEqualTo%3E%3Cogc%3APropertyName%3Edc%3Atitle%3C%2Fogc%3APropertyName%3E%3Cogc%3ALiteral%3ELorem%20ipsum%3C%2Fogc%3ALiteral%3E%3C%2Fogc%3APropertyIsEqualTo%3E%3C% [...]
+<li><a href="../csw.py?config=tests/suites/default/default.cfg&service=CSW&version=2.0.2&request=GetRecords&typenames=csw:Record&elementsetname=full&maxrecords=">GetRecords-empty-maxrecords</a></li>
+<li><a href="../csw.py?config=tests/suites/default/default.cfg&service=CSW&version=2.0.2&request=GetRepositoryItem&id=urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63">GetRepositoryItem</a></li>
+<li><a href="../csw.py?config=tests/suites/default/default.cfg&service=CSW&version=2.0.2&request=GetRepositoryItem&id=NOTFOUND">Exception-GetRepositoryItem-notfound</a></li>
 <li><a href="../csw.py?config=tests/suites/manager/default.cfg&service=CSW&version=2.0.2&request=Harvest">Exception-Harvest-missing-resourcetype</a></li>
 <li><a href="../csw.py?config=tests/suites/manager/default.cfg&service=CSW&version=2.0.2&request=Harvest&resourcetype=http://www.opengis.net/wms">Exception-Harvest-missing-source</a></li>
 <li><a href="../csw.py?config=tests/suites/manager/default.cfg&service=CSW&version=2.0.2&request=Harvest&resourcetype=http://www.opengis.net/wms1234&source=http://demo.pycsw.org/cite/csw">Exception-Harvest-invalid-resourcetype</a></li>
diff --git a/tests/run_tests.py b/tests/run_tests.py
index 16f18ec..f9467fc 100644
--- a/tests/run_tests.py
+++ b/tests/run_tests.py
@@ -2,8 +2,10 @@
 # =================================================================
 #
 # Authors: Tom Kralidis <tomkralidis at gmail.com>
+#          Ricardo Garcia Silva <ricardo.garcia.silva at gmail.com>
 #
-# Copyright (c) 2011 Tom Kralidis
+# Copyright (c) 2016 Tom Kralidis
+# Copyright (c) 2016 Ricardo Garcia Silva
 #
 # Permission is hereby granted, free of charge, to any person
 # obtaining a copy of this software and associated documentation
@@ -30,15 +32,24 @@
 
 # simple testing framework inspired by MapServer msautotest
 
+import codecs
 import csv
-import sys
-import os
+import filecmp
 import getopt
 import glob
-import filecmp
+from io import BytesIO
+import json
+import os
 import re
-from pycsw.util import http_request
+import sys
+import time
+
+from lxml import etree
+from lxml import objectify
+
+from pycsw.core.util import get_elapsed_time, http_request
 
+ENCODING = 'utf-8'
 
 def plural(num):
     """Determine plurality given an integer"""
@@ -48,28 +59,173 @@ def plural(num):
         return ''
 
 
-def get_validity(sexpected, sresult, soutfile, force_id_mask=False):
+def test_xml_result(result, expected, encoding=ENCODING):
+    """Compare the XML test results with an expected value.
+
+    This function compares the test result with the expected values by
+    performing XML canonicalization (c14n)[1]_.
+
+    Parameters
+    ----------
+    result: str
+        The result of running the test.
+    expected: str
+        The expected outcome.
+
+    Returns
+    -------
+    bool
+        Whether the result matches the expectations or not.
+
+    Raises
+    ------
+    etree.XMLSyntaxError
+        If any of the input parameters is not a valid XMl.
+    etree.C14NError
+        If any of the input parameters cannot be canonicalized. This may
+        happen if there are relative namespace URIs in any of the XML
+        documents, as they are explicitly not allowed when doing XML c14n
+
+    References
+    ----------
+    .. [1] http://www.w3.org/TR/xml-c14n
+
+    """
+
+    try:
+        result_element = etree.fromstring(result)
+        expected_element = etree.fromstring(expected.encode(encoding))
+        result_buffer = BytesIO()
+        result_tree = result_element.getroottree()
+        objectify.deannotate(result_tree, cleanup_namespaces=True)
+        result_tree.write_c14n(result_buffer)
+        expected_buffer = BytesIO()
+        expected_tree = expected_element.getroottree()
+        objectify.deannotate(expected_tree, cleanup_namespaces=True)
+        expected_tree.write_c14n(expected_buffer)
+        matches = result_buffer.getvalue() == expected_buffer.getvalue()
+        if not matches:
+            print("result:")
+            print(result_buffer.getvalue())
+            print("+++++++++++++++++++++++")
+            print("expected:")
+            print(expected_buffer.getvalue())
+
+    except etree.XMLSyntaxError:
+        matches = None
+    return matches
+
+
+def test_json_result(result, expected, encoding=ENCODING):
+    """Compare the JSON test results with an expected value.
+
+    Parameters
+    ----------
+    result: str
+        The result of running the test.
+    expected: str
+        The expected outcome.
+
+    Returns
+    -------
+    bool
+        Whether the result matches the expectations or not.
+
+    """
+
+    try:
+        result_dict = json.loads(result.decode(encoding), encoding=encoding)
+        expected_dict = json.loads(expected, encoding=encoding)
+    except ValueError:
+        matches = None
+    else:
+        matches = result_dict == expected_dict
+    return matches
+
+
+def get_validity(expected_path, result, output_file_name, force_id_mask=False):
+    """Test whether the test result matches the expected outcome.
+
+    This function deals with both XML and JSON results. It first tries to
+    parse the result and the expected outcome as XML and evaluates them using
+    XML canonicalization (c14n). If the result cannot be parsed as XML, it then
+    tries to load it as JSON and does a sorted comparison.
+
+    Parameters
+    ----------
+    expected_path: str
+        The path to the file that has the expected test outcome
+    result: str
+        The actual result that was generated by running the test code
+    output_file_name: str
+        Name of the file that will be written to disk with the contents of
+        the result
+    force_id_mask: bool, optional
+        Whether to apply result normalization to id fields
+
+    Returns
+    -------
+    int
+        One of three possible values:
+
+        * If the input `expected_path` could not be found, the results will
+          be used to generate a new expected file. In this case the return
+          value will be 0;
+        * If the result matches the expected outcome, the return value is 1;
+        * If the result does not match the expected outcome the return value is
+          -1.
+
+    """
+
+    normalized_result = normalize(result, force_id_mask=force_id_mask)
+    if not os.path.exists(expected_path):  # create expected file
+        with codecs.open(expected_path, 'w', encoding=ENCODING) as f:
+            f.write(normalized_result)
+        status = 0
+    else:  # compare result with expected
+        with codecs.open(expected_path, encoding=ENCODING) as expected_fh:
+            expected = expected_fh.read()
+            matches_expected = test_xml_result(normalized_result, expected)
+            if matches_expected is None:
+                # the file is either not XML (perhaps JSON?) or malformed
+                matches_expected = test_json_result(
+                    normalized_result, expected, encoding=ENCODING)
+        if matches_expected:  # pass
+            status = 1
+        else:  # failed
+            status = -1
+            if not os.path.exists('results'):
+                os.mkdir('results')
+            with open('results%s%s' % (os.sep, output_file_name), 'wb') as f:
+                f.write(normalized_result)
+    return status
+
+
+def pedantic_get_validity(sexpected, sresult, soutfile, force_id_mask=False):
     """Decipher whether the output passes, fails, or initializes"""
     if not os.path.exists(sexpected):  # create expected file
-        expectedfile = open(sexpected, 'w')
-        expectedfile.write(normalize(sresult, force_id_mask))
-        expectedfile.close()
+        with open(sexpected, 'w') as f:
+            f.write(normalize(sresult, force_id_mask))
         sstatus = 0
     else:  # compare result with expected
         if not os.path.exists('results'):
             os.mkdir('results')
-        resultfile = open('results%s%s' % (os.sep, soutfile), 'wb')
-        resultfile.write(normalize(sresult, force_id_mask))
-        resultfile.close()
+        with open('results%s%s' % (os.sep, soutfile), 'wb') as f:
+            f.write(normalize(sresult, force_id_mask))
         if filecmp.cmp(sexpected, 'results%s%s' % (os.sep, soutfile)):  # pass
             os.remove('results%s%s' % (os.sep, soutfile))
             sstatus = 1
         else:  # fail
             import difflib
-            diff = difflib.unified_diff(
-                open(sexpected).readlines(),
-                open('results%s%s' % (os.sep, soutfile)).readlines())
-            print '\n'.join(list(diff))
+            with codecs.open(sexpected, encoding=ENCODING) as a:
+                with codecs.open('results%s%s' % (os.sep, soutfile),
+                                 encoding=ENCODING) as b:
+                    a2 = a.readlines()
+                    b2 = b.readlines()
+                    diff = difflib.unified_diff(a2, b2)
+            print('\n'.join(list(diff)))
+            if len(a2) != len(b2):
+                print('LINE COUNT: expected: %d, result: %d' % (len(a2), len(b2)))
             sstatus = -1
     return sstatus
 
@@ -79,66 +235,77 @@ def normalize(sresult, force_id_mask=False):
     values"""
 
     # XML responses
-    version = re.search('<!-- (.*) -->', sresult)
-    updatesequence = re.search('updateSequence="(\S+)"', sresult)
-    timestamp = re.search('timestamp="(.*)"', sresult)
-    timestamp2 = re.search('timeStamp="(.*)"', sresult)
-    timestamp3 = re.search('<oai:responseDate>(.*)</oai:responseDate>', sresult)
-    timestamp4 = re.search('<oai:earliestDatestamp>(.*)</oai:earliestDatestamp>', sresult)
-    zrhost = re.search('<zr:host>(.*)</zr:host>', sresult)
-    zrport = re.search('<zr:port>(.*)</zr:port>', sresult)
+    version = re.search(b'<!-- (.*) -->', sresult)
+    updatesequence = re.search(b'updateSequence="(\S+)"', sresult)
+    timestamp = re.search(b'timestamp="(.*)"', sresult)
+    timestamp2 = re.search(b'timeStamp="(.*)"', sresult)
+    timestamp3 = re.search(b'<oai:responseDate>(.*)</oai:responseDate>', sresult)
+    timestamp4 = re.search(b'<oai:earliestDatestamp>(.*)</oai:earliestDatestamp>', sresult)
+    zrhost = re.search(b'<zr:host>(.*)</zr:host>', sresult)
+    zrport = re.search(b'<zr:port>(.*)</zr:port>', sresult)
+    elapsed_time = re.search(b'elapsedTime="(.*)"', sresult)
+    expires = re.search(b'expires="(.*?)"', sresult)
+    atom_updated = re.findall(b'<atom:updated>(.*)</atom:updated>', sresult)
 
     if version:
-        sresult = sresult.replace(version.group(0), '<!-- PYCSW_VERSION -->')
+        sresult = sresult.replace(version.group(0), b'<!-- PYCSW_VERSION -->')
     if updatesequence:
         sresult = sresult.replace(updatesequence.group(0),
-                                  'updateSequence="PYCSW_UPDATESEQUENCE"')
+                                  b'updateSequence="PYCSW_UPDATESEQUENCE"')
     if timestamp:
         sresult = sresult.replace(timestamp.group(0),
-                                  'timestamp="PYCSW_TIMESTAMP"')
+                                  b'timestamp="PYCSW_TIMESTAMP"')
     if timestamp2:
         sresult = sresult.replace(timestamp2.group(0),
-                                  'timeStamp="PYCSW_TIMESTAMP"')
+                                  b'timeStamp="PYCSW_TIMESTAMP"')
     if timestamp3:
         sresult = sresult.replace(timestamp3.group(0),
-                                  '<oai:responseDate>PYCSW_TIMESTAMP</oai:responseDate>')
+                                  b'<oai:responseDate>PYCSW_TIMESTAMP</oai:responseDate>')
     if timestamp4:
         sresult = sresult.replace(timestamp4.group(0),
-                                  '<oai:earliestDatestamp>PYCSW_TIMESTAMP</oai:earliestDatestamp>')
+                                  b'<oai:earliestDatestamp>PYCSW_TIMESTAMP</oai:earliestDatestamp>')
     if zrport:
         sresult = sresult.replace(zrport.group(0),
-                                  '<zr:port>PYCSW_PORT</zr:port>')
+                                  b'<zr:port>PYCSW_PORT</zr:port>')
     if zrhost:
         sresult = sresult.replace(zrhost.group(0),
-                                  '<zr:host>PYCSW_HOST</zr:host>')
+                                  b'<zr:host>PYCSW_HOST</zr:host>')
+    if elapsed_time:
+        sresult = sresult.replace(elapsed_time.group(0),
+                                  b'elapsedTime="PYCSW_ELAPSED_TIME"')
+    if expires:
+        sresult = sresult.replace(expires.group(0),
+                                  b'expires="PYCSW_EXPIRES"')
+    for au in atom_updated:
+        sresult = sresult.replace(au, b'PYCSW_TIMESTAMP')
 
     # for csw:HarvestResponse documents, mask identifiers
     # which are dynamically generated for OWS endpoints
-    if sresult.find('HarvestResponse') != -1:
-        identifier = re.findall('<dc:identifier>(\S+)</dc:identifier>',
+    if sresult.find(b'HarvestResponse') != -1:
+        identifier = re.findall(b'<dc:identifier>(\S+)</dc:identifier>',
                                 sresult)
         for i in identifier:
-            sresult = sresult.replace(i, 'PYCSW_IDENTIFIER')
+            sresult = sresult.replace(i, b'PYCSW_IDENTIFIER')
 
     # JSON responses
-    timestamp = re.search('"timestamp": "(.*?)"', sresult)
+    timestamp = re.search(b'"@timestamp": "(.*?)"', sresult)
 
     if timestamp:
         sresult = sresult.replace(timestamp.group(0),
-                                  '"timestamp": "PYCSW_TIMESTAMP"')
+                                  b'"@timestamp": "PYCSW_TIMESTAMP"')
 
     # harvesting-based GetRecords/GetRecordById responses
     if force_id_mask:
-        dcid = re.findall('<dc:identifier>(urn:uuid.*)</dc:identifier>', sresult)
-        isoid = re.findall('id="(urn:uuid.*)"', sresult)
-        isoid2 = re.findall('<gco:CharacterString>(urn:uuid.*)</gco', sresult)
-    
+        dcid = re.findall(b'<dc:identifier>(urn:uuid.*)</dc:identifier>', sresult)
+        isoid = re.findall(b'id="(urn:uuid.*)"', sresult)
+        isoid2 = re.findall(b'<gco:CharacterString>(urn:uuid.*)</gco', sresult)
+
         for d in dcid:
-            sresult = sresult.replace(d, 'PYCSW_IDENTIFIER')
+            sresult = sresult.replace(d, b'PYCSW_IDENTIFIER')
         for i in isoid:
-            sresult = sresult.replace(i, 'PYCSW_IDENTIFIER')
+            sresult = sresult.replace(i, b'PYCSW_IDENTIFIER')
         for i2 in isoid2:
-            sresult = sresult.replace(i2, 'PYCSW_IDENTIFIER')
+            sresult = sresult.replace(i2, b'PYCSW_IDENTIFIER')
 
     return sresult
 
@@ -163,6 +330,8 @@ SYNOPSIS
 
     -r    run tests which harvest remote resources (default off)
 
+    -t    time (milliseconds) in which requests should complete
+
 EXAMPLES
 
     1.) default test example
@@ -177,17 +346,21 @@ EXAMPLES
 
         run_tests.py -u http://localhost:8000/ -s default,apiso
 
-    3.) run tests including remote harvest tests
+    4.) run tests including remote harvest tests
 
         run_tests.py -u http://localhost:8000/ -s default,apiso -r
 
+    5.) default test example with 1000ms time benchmark
+
+        run_tests.py -u http://localhost:8000/ -t 1000
+
 
 '''
 
 # main
 
 if len(sys.argv) < 2:
-    print usage()
+    print(usage())
     sys.exit(1)
 
 URL = sys.argv[1]
@@ -204,12 +377,14 @@ INITED = 0
 LOGWRITER = None
 DATABASE = 'SQLite3'
 REMOTE = False
+PEDANTIC = False
+TIME = None
 
 try:
-    OPTS, ARGS = getopt.getopt(sys.argv[1:], 'u:l:s:d:rh')
+    OPTS, ARGS = getopt.getopt(sys.argv[1:], 'u:l:s:d:t:rhp')
 except getopt.GetoptError as err:
-    print '\nERROR: %s' % err
-    print usage()
+    print('\nERROR: %s' % err)
+    print(usage())
     sys.exit(2)
 
 for o, a in OPTS:
@@ -219,20 +394,27 @@ for o, a in OPTS:
         LOGFILE = a
     if o == '-d':
         DATABASE = a
+    if o == '-t':
+        TIME = int(a)
     if o == '-r':
         REMOTE = True
+    if o == '-p':
+        PEDANTIC = True
     if o == '-s':
         TESTSUITES = a.split(',')
     if o == '-h':  # dump help and exit
-        print usage()
+        print(usage())
         sys.exit(3)
 
-print '\nRunning tests against %s' % URL
+print('\nRunning tests against %s' % URL)
 
 if LOGFILE is not None:  # write detailed output to CSV
     LOGWRITER = csv.writer(open(LOGFILE, 'wb'))
     LOGWRITER.writerow(['url', 'configuration', 'testname', 'result'])
 
+if TIME is not None:  # perform benchmarking
+    print('Benchmark: %dms' % TIME)
+
 if TESTSUITES:
     if 'harvesting' in TESTSUITES:
         REMOTE = True
@@ -250,10 +432,10 @@ for testsuite in TESTSUITES_LIST:
     force_id_mask = False
     if testsuite in ['suites%smanager' % os.sep, 'suites%sharvesting' % os.sep]:
         force_id_mask = True
-   
+
     # get configuration
     for cfg in glob.glob('%s%s*.cfg' % (testsuite, os.sep)):
-        print '\nTesting configuration %s' % cfg
+        print('\nTesting configuration %s' % cfg)
 
         for root, dirs, files in os.walk(testsuite):
             if files:
@@ -263,37 +445,63 @@ for testsuite in TESTSUITES_LIST:
 
                     if sfile == 'requests.txt':  # GET requests
                         filename = '%s%s%s' % (root, os.sep, sfile)
-                        gets = csv.reader(open(filename))
-                        for row in gets:
-                            testfile = '%s%s%s' % (root, os.sep, sfile)
-                            request = ','.join(row[1:]).replace('PYCSW_SERVER',
-                                                                URL)
-                            outfile = '%s%s' % (root.replace(os.sep, '_'),
-                                                '_%s.xml' % row[0])
-                            expected = 'expected%s%s' % (os.sep, outfile)
-                            print '\n test %s:%s' % (testfile, row[0])
-
-                            result = http_request('GET', request)
-
-                            status = get_validity(expected, result, outfile,
-                                                  force_id_mask)
-
-                            if status == 1:
-                                print '  passed'
-                                PASSED += 1
-                            elif status == 0:
-                                print '  initialized'
-                                INITED += 1
-                            elif status == -1 and DATABASE == 'PostgreSQL':
-                                print '  warning: possible collation issue'
-                                WARNING += 1
-                            else:
-                                print '  FAILED'
-                                FAILED += 1
-
-                            if LOGWRITER is not None:
-                                LOGWRITER.writerow([URL, cfg,
-                                                    testfile, status])
+                        with open(filename) as f:
+                            gets = csv.reader(f)
+                            for row in gets:
+                                testfile = '%s%s%s' % (root, os.sep, sfile)
+                                request = ','.join(row[1:]).replace('PYCSW_SERVER',
+                                                                    URL)
+                                outfile = '%s%s' % (root.replace(os.sep, '_'),
+                                                    '_%s.xml' % row[0])
+                                expected = 'expected%s%s' % (os.sep, outfile)
+                                print('\n test %s:%s' % (testfile, row[0]))
+
+                                try:
+                                    begin = time.time()
+                                    result = http_request('GET', request)
+                                    end = time.time()
+                                    elapsed = get_elapsed_time(begin, end)
+                                    print('  completed in %dms' % elapsed)
+                                except Exception as err:
+                                    result = err.read()
+                                if PEDANTIC:
+                                    status = pedantic_get_validity(
+                                        expected, result, outfile,
+                                        force_id_mask
+                                    )
+                                else:
+                                    try:
+                                        status = get_validity(expected, result,
+                                                              outfile,
+                                                              force_id_mask)
+                                    except etree.C14NError:
+                                        print("Could not canonicalize {0}. "
+                                              "Using pedantic "
+                                              "mode".format(row[0]))
+                                        status = pedantic_get_validity(
+                                            expected, result, outfile,
+                                            force_id_mask
+                                        )
+
+                                if status == 1:
+                                    print('  passed')
+                                    PASSED += 1
+                                elif status == 0:
+                                    print('  initialized')
+                                    INITED += 1
+                                elif status == -1 and DATABASE == 'PostgreSQL':
+                                    print('  warning: possible collation issue')
+                                    WARNING += 1
+                                else:
+                                    print('  FAILED')
+                                    FAILED += 1
+
+                                if TIME and get_elapsed_time(begin, end) > TIME:
+                                    print('  FAILED BENCHMARK')
+
+                                if LOGWRITER is not None:
+                                    LOGWRITER.writerow([URL, cfg,
+                                                        testfile, status])
 
                     else:  # POST requests
                         testfile = '%s%s%s' % (root, os.sep, sfile)
@@ -302,43 +510,64 @@ for testsuite in TESTSUITES_LIST:
                         outfile = '%s%s' % (os.sep,
                                             testfile.replace(os.sep, '_'))
                         expected = 'expected%s%s' % (os.sep, outfile)
-                        print '\n test %s' % testfile
+                        print('\n test %s' % testfile)
 
                         # read test
-                        f = open(testfile)
-                        request = f.read()
-                        f.close()
+                        with codecs.open(testfile, encoding=ENCODING) as fh:
+                            request = fh.read().encode(ENCODING)
 
                         configkvp = 'config=tests%s%s' % (os.sep, cfg)
                         url2 = '%s?%s' % (URL, configkvp)
 
                         # invoke request
-                        result = http_request('POST', url2, request)
-
-                        status = get_validity(expected, result, outfile,
-                                              force_id_mask)
+                        try:
+                            begin = time.time()
+                            result = http_request('POST', url2, request)
+                            end = time.time()
+                            elapsed = get_elapsed_time(begin, end)
+                            print('  completed in %dms' % elapsed)
+                        except Exception as err:
+                            result = err.read()
+                        if PEDANTIC:
+                            status = pedantic_get_validity(
+                                expected, result, outfile, force_id_mask)
+                        else:
+                            try:
+                                status = get_validity(expected, result, outfile,
+                                                      force_id_mask)
+                            except etree.C14NError:
+                                print("Could not canonicalize {0}. Using "
+                                      "pedantic mode".format(sfile))
+                                status = pedantic_get_validity(
+                                    expected, result, outfile, force_id_mask)
 
                         if status == 1:
-                            print '  passed'
+                            print('  passed')
                             PASSED += 1
                         elif status == 0:
-                            print '  initialized'
+                            print('  initialized')
                             INITED += 1
                         elif status == -1 and DATABASE == 'PostgreSQL':
-                            print '  warning: possible sorting collation issue'
+                            print('  warning: possible sorting collation issue')
                             WARNING += 1
                         else:
-                            print '  FAILED'
+                            print('  FAILED')
                             FAILED += 1
 
+                        if TIME and get_elapsed_time(begin, end) > TIME:
+                            print('  FAILED BENCHMARK')
+
                         if LOGWRITER is not None:
                             LOGWRITER.writerow([URL, cfg, testfile, status])
 
-print '\nResults (%d/%d - %.2f%%)' % \
-    (PASSED, PASSED + FAILED, float(PASSED) / float(PASSED + FAILED) * 100)
-print '   %d test%s passed' % (PASSED, plural(PASSED))
-print '   %d test%s warnings' % (WARNING, plural(WARNING))
-print '   %d test%s failed' % (FAILED, plural(FAILED))
-print '   %d test%s initialized' % (INITED, plural(INITED))
+if LOGWRITER is not None:
+    LOGWRITER.close()
+
+print('\nResults (%d/%d - %.2f%%)' %
+      (PASSED, PASSED + FAILED, float(PASSED) / float(PASSED + FAILED) * 100))
+print('   %d test%s passed' % (PASSED, plural(PASSED)))
+print('   %d test%s warnings' % (WARNING, plural(WARNING)))
+print('   %d test%s failed' % (FAILED, plural(FAILED)))
+print('   %d test%s initialized' % (INITED, plural(INITED)))
 
 sys.exit(FAILED)
diff --git a/tests/suites/apiso/data/README.txt b/tests/suites/apiso/data/README.txt
new file mode 100644
index 0000000..3dd817c
--- /dev/null
+++ b/tests/suites/apiso/data/README.txt
@@ -0,0 +1,7 @@
+APISO Data
+==========
+
+This directory provides data used to check conformance against pycsw APISO support.
+
+- pacioos-NS06agg.xml: http://oos.soest.hawaii.edu/pacioos/metadata/NS06agg.html
+- all other *.xml files are from the Greek National Mapping Agency (metadata submitted to the INSPIRE geoportal)
diff --git a/tests/suites/cite/data/README.txt b/tests/suites/cite/data/README.txt
new file mode 100644
index 0000000..6799686
--- /dev/null
+++ b/tests/suites/cite/data/README.txt
@@ -0,0 +1,65 @@
+CITE Data
+=========
+
+This directory provides data used to check conformance against the
+Open Geospatial Consortium Compliance and Interoperability Testing Initiative (CITE).
+
+* http://cite.opengeospatial.org/teamengine/
+
+The CITE team engine does not offer a specific license for re-distribution, as such it falls
+under the general guidance provided by the OGC legal page (http://www.opengeospatial.org/legal/)
+and the following license:
+
+* http://www.opengeospatial.org/ogc/software
+
+DATA LICENSE
+------------
+
+The data directory includes information provided by the Open Geospatial Consortium::
+
+    Copyright © 2012 Open Geospatial Consortium, Inc.
+    All Rights Reserved. http://www.opengeospatial.org/ogc/legal
+
+The test data is available directly from the following link:
+
+* http://cite.opengeospatial.org/teamengine/about/csw/2.0.2/web/
+
+This content has been format shifted from CSW record format into a text based
+"property file" for release testing.
+
+Software Notice
+---------------
+
+This OGC work (including software, documents, or other related items) is being provided by the
+copyright holders under the following license. By obtaining, using and/or copying this work, you
+(the licensee) agree that you have read, understood, and will comply with the following terms and
+conditions:
+
+Permission to use, copy, and modify this software and its documentation, with or without
+modification, for any purpose and without fee or royalty is hereby granted, provided that you
+include the following on ALL copies of the software and documentation or portions thereof, including
+modifications, that you make:
+
+1. The full text of this NOTICE in a location viewable to users of the redistributed or derivative
+work.
+
+2. Any pre-existing intellectual property disclaimers, notices, or terms and conditions. If none exist,
+a short notice of the following form (hypertext is preferred, text is permitted) should be used
+within the body of any redistributed or derivative code: "Copyright © [$date-of-document] Open
+Geospatial Consortium, Inc. All Rights Reserved. http://www.opengeospatial.org/ogc/legal (Hypertext
+is preferred, but a textual representation is permitted.)
+
+3. Notice of any changes or modifications to the OGC files, including the date changes were made. (We
+recommend you provide URIs to the location from which the code is derived.)
+
+THIS SOFTWARE AND DOCUMENTATION IS PROVIDED "AS IS," AND COPYRIGHT HOLDERS MAKE NO REPRESENTATIONS
+OR WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO, WARRANTIES OF MERCHANTABILITY OR
+FITNESS FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF THE SOFTWARE OR DOCUMENTATION WILL NOT
+INFRINGE ANY THIRD PARTY PATENTS, COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS.
+
+COPYRIGHT HOLDERS WILL NOT BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES
+ARISING OUT OF ANY USE OF THE SOFTWARE OR DOCUMENTATION.
+
+The name and trademarks of copyright holders may NOT be used in advertising or publicity pertaining
+to the software without specific, written prior permission. Title to copyright in this software and
+any associated documentation will at all times remain with copyright holders.
diff --git a/tests/suites/cite/data/records.db b/tests/suites/cite/data/cite.db
similarity index 100%
rename from tests/suites/cite/data/records.db
rename to tests/suites/cite/data/cite.db
diff --git a/default-sample.cfg b/tests/suites/csw30/default.cfg
similarity index 65%
copy from default-sample.cfg
copy to tests/suites/csw30/default.cfg
index 5420a7f..328045b 100644
--- a/default-sample.cfg
+++ b/tests/suites/csw30/default.cfg
@@ -2,7 +2,7 @@
 #
 # Authors: Tom Kralidis <tomkralidis at gmail.com>
 #
-# Copyright (c) 2010 Tom Kralidis
+# Copyright (c) 2011 Tom Kralidis
 #
 # Permission is hereby granted, free of charge, to any person
 # obtaining a copy of this software and associated documentation
@@ -28,8 +28,8 @@
 # =================================================================
 
 [server]
-home=/var/www/pycsw
-url=http://localhost/pycsw/csw.py
+home=.
+url=http://localhost/pycsw/csw.py?config=tests/suites/csw30/default.cfg
 mimetype=application/xml; charset=UTF-8
 encoding=UTF-8
 language=en-US
@@ -37,62 +37,54 @@ maxrecords=10
 #loglevel=DEBUG
 #logfile=/tmp/pycsw.log
 #ogc_schemas_base=http://foo
-#federatedcatalogues=http://geo.data.gov/geoportal/csw/discovery
-#pretty_print=true
+federatedcatalogues=http://demo.pycsw.org/gisdata/csw
+pretty_print=true
 #gzip_compresslevel=8
-#domainquerytype=range
-#domaincounts=true
 #spatial_ranking=true
-profiles=apiso
 
 [manager]
 transactions=false
 allowed_ips=127.0.0.1
-#csw_harvest_pagesize=10
 
 [metadata:main]
 identification_title=pycsw Geospatial Catalogue
 identification_abstract=pycsw is an OGC CSW server implementation written in Python
-identification_keywords=catalogue,discovery,metadata
+identification_keywords=catalogue,discovery
 identification_keywords_type=theme
 identification_fees=None
 identification_accessconstraints=None
-provider_name=Organization Name
+provider_name=pycsw
 provider_url=http://pycsw.org/
-contact_name=Lastname, Firstname
-contact_position=Position Title
-contact_address=Mailing Address
-contact_city=City
-contact_stateorprovince=Administrative Area
-contact_postalcode=Zip or Postal Code
-contact_country=Country
-contact_phone=+xx-xxx-xxx-xxxx
-contact_fax=+xx-xxx-xxx-xxxx
-contact_email=Email Address
-contact_url=Contact URL
-contact_hours=Hours of Service
+contact_name=Kralidis, Tom
+contact_position=Senior Systems Scientist
+contact_address=TBA
+contact_city=Toronto
+contact_stateorprovince=Ontario
+contact_postalcode=M9C 3Z9
+contact_country=Canada
+contact_phone=+01-416-xxx-xxxx
+contact_fax=+01-416-xxx-xxxx
+contact_email=tomkralidis at gmail.com
+contact_url=http://kralidis.ca/
+contact_hours=0800h - 1600h EST
 contact_instructions=During hours of service.  Off on weekends.
 contact_role=pointOfContact
 
 [repository]
 # sqlite
-database=sqlite:////var/www/pycsw/tests/suites/cite/data/records.db
+database=sqlite:///tests/suites/cite/data/records.db
 # postgres
-#database=postgresql://username:password@localhost/pycsw
-# mysql
-#database=mysql://username:password@localhost/pycsw?charset=utf8
-#mappings=path/to/mappings.py
+#database=postgres://username:password@localhost/pycsw
 table=records
-#filter=type = 'http://purl.org/dc/dcmitype/Dataset'
 
 [metadata:inspire]
-enabled=true
+enabled=false
 languages_supported=eng,gre
 default_language=eng
-date=YYYY-MM-DD
+date=2011-03-29
 gemet_keywords=Utility and governmental services
 conformity_service=notEvaluated
-contact_name=Organization Name
-contact_email=Email Address
-temp_extent=YYYY-MM-DD/YYYY-MM-DD
+contact_name=National Technical University of Athens
+contact_email=tzotsos at gmail.com
+temp_extent=2011-02-01/2011-03-30
 
diff --git a/tests/suites/csw30/get/requests.txt b/tests/suites/csw30/get/requests.txt
new file mode 100644
index 0000000..a6df261
--- /dev/null
+++ b/tests/suites/csw30/get/requests.txt
@@ -0,0 +1,82 @@
+GetCapabilities-base-url,PYCSW_SERVER?config=tests/suites/csw30/default.cfg
+GetCapabilities-no-version,PYCSW_SERVER?config=tests/suites/csw30/default.cfg&service=CSW&request=GetCapabilities
+GetCapabilities,PYCSW_SERVER?config=tests/suites/csw30/default.cfg&service=CSW&version=3.0.0&request=GetCapabilities
+Exception-invalid-request,PYCSW_SERVER?config=tests/suites/csw30/default.cfg&service=CSW&version=3.0.0&request=GetCapabilities-foo
+Exception-GetDomain,PYCSW_SERVER?config=tests/suites/csw30/default.cfg&service=CSW&version=3.0.0&request=GetDomain
+GetDomain-parameter,PYCSW_SERVER?config=tests/suites/csw30/default.cfg&service=CSW&version=3.0.0&request=GetDomain&parametername=GetRecords.ElementSetName
+GetDomain-value-reference,PYCSW_SERVER?config=tests/suites/csw30/default.cfg&service=CSW&version=3.0.0&request=GetDomain&valuereference=dc:title
+Exception-GetDomain-value-reference,PYCSW_SERVER?config=tests/suites/csw30/default.cfg&service=CSW&version=3.0.0&request=GetDomain&valuereference=dc:title2
+Exception-GetRecordById-dc.xml,PYCSW_SERVER?config=tests/suites/csw30/default.cfg&service=CSW&version=3.0.0&request=GetRecordById&id=urn:uuid:829babb0-b2f1-49e1-8cd5-7b489fe71a1e
+Exception-GetRecordById-404,PYCSW_SERVER?config=tests/suites/csw30/default.cfg&service=CSW&version=3.0.0&request=GetRecordById&id=does_not_exist2
+OpenSearch-description,PYCSW_SERVER?config=tests/suites/csw30/default.cfg&mode=opensearch&service=CSW&version=3.0.0&request=GetCapabilities
+GetRepositoryItem,PYCSW_SERVER?config=tests/suites/csw30/default.cfg&service=CSW&version=3.0.0&request=GetRepositoryItem&id=urn:uuid:19887a8a-f6b0-4a63-ae56-7fba0e17801f
+Exception-GetRepositoryItem-notfound,PYCSW_SERVER?config=tests/suites/csw30/default.cfg&service=CSW&version=3.0.0&request=GetRepositoryItem&id=NOTFOUND
+002258f0-627f-457f-b2ad-025777c77ac8,PYCSW_SERVER?config=tests/suites/csw30/default.cfg&mode=opensearch&service=CSW&version=3.0.0&request=GetCapabilities
+045c600d-973d-41eb-9f60-eba1b717b720,PYCSW_SERVER?config=tests/suites/csw30/default.cfg&mode=opensearch&service=CSW&version=3.0.0&request=GetRecords&elementsetname=full&typenames=csw:Record&resulttype=results&q=Fusc%C3%A9%20Land&bbox=&time=/&outputformat=application/atom+xml&startposition=1&maxrecords=&recordids=
+0bbcf862-5211-4351-9988-63f8bec49c98,PYCSW_SERVER?config=tests/suites/csw30/default.cfg&elementSetName=summary&outputFormat=application/atom%2Bxml&request=GetRecords&service=CSW&typeNames=Record&version=3.0.0
+0bdf8457-971e-4ed1-be4a-5feca4dcd8fa,PYCSW_SERVER?config=tests/suites/csw30/default.cfg
+0d8bbdec-0846-42ca-8dc8-b7f4cba41d67,PYCSW_SERVER?config=tests/suites/csw30/default.cfg&elementName=tns:title&request=GetRecords&service=CSW&typeNames=Record&namespace=xmlns(tns%3Dhttp://purl.org/dc/elements/1.1/)&version=3.0.0
+0e1dca37-477a-4060-99fe-7799b52d656c,PYCSW_SERVER?config=tests/suites/csw30/default.cfg&mode=opensearch&service=CSW&version=3.0.0&request=GetRecords&elementsetname=full&typenames=csw:Record&resulttype=results&q=lpppclq&bbox=&time=/&outputformat=application/atom+xml&startposition=1&maxrecords=&recordids=
+13c87956-51a4-4780-a8e9-6e0b5c0bb473,PYCSW_SERVER?config=tests/suites/csw30/default.cfg&elementSetName=full&maxRecords=20&request=GetRecords&service=CSW&typeNames=Record&version=3.0.0
+151d982f-ebd3-4cb2-b507-a667713a1e92,PYCSW_SERVER?config=tests/suites/csw30/default.cfg&acceptFormats=model/x3d%2Bxml&acceptVersions=3.0.0&request=GetCapabilities&service=CSW
+1869e495-1a61-4713-8285-76d1336ee1a6,PYCSW_SERVER?config=tests/suites/csw30/default.cfg&acceptVersions=3.0.0&request=GetCapabilities
+1bcb42a9-538c-4f0a-9d4c-d6f10b720aa6,PYCSW_SERVER?config=tests/suites/csw30/default.cfg&request=GetRecordById&service=CSW&version=3.0.0
+22f44168-2ccf-4801-ad96-204212566d56,PYCSW_SERVER?config=tests/suites/csw30/default.cfg
+2499a9c9-8d33-449c-bc92-d494adfcc84d,PYCSW_SERVER?config=tests/suites/csw30/default.cfg&acceptVersions=3.0.0&sections=All&request=GetCapabilities&service=CSW
+27f4f39c-d92a-4e3c-b961-c6aa8c24e513,PYCSW_SERVER?config=tests/suites/csw30/default.cfg&acceptFormats=application/xml&acceptVersions=3.0.0&request=GetCapabilities&service=CSW
+28e569df-8596-4128-8d9a-29ad03138915,PYCSW_SERVER?config=tests/suites/csw30/default.cfg&id=urn:uuid:a06af396-3105-442d-8b40-22b57a90d2f2&request=GetRecordById&service=CSW&version=3.0.0
+2b06a5c8-0df2-4af1-8d2e-a425de11c845,PYCSW_SERVER?config=tests/suites/csw30/default.cfg
+2ba1418a-444d-4cce-9cfe-4c94efcf8b55,PYCSW_SERVER?config=tests/suites/csw30/default.cfg&maxRecords=2&elementSetName=summary&outputFormat=application/atom%2Bxml&request=GetRecords&service=CSW&typeNames=csw3:Record&startPosition=3&namespace=xmlns(csw3%3Dhttp://www.opengis.net/cat/csw/3.0)&version=3.0.0
+397fe17a-d5b4-4f96-8cc4-4ce467ed4d0a,PYCSW_SERVER?config=tests/suites/csw30/default.cfg&service=CSW&version=3.0.0&request=GetRecords&elementsetname=full&typenames=csw:Record&resulttype=results&q=ipsum&bbox=&time=/&outputformat=application/xml&outputschema=http://www.opengis.net/cat/csw/3.0&startposition=1&maxrecords=&recordids=
+3dcd1b15-73d2-4b7d-a3e3-ff15bf14aae4,PYCSW_SERVER?config=tests/suites/csw30/default.cfg&elementSetName=brief&request=GetRecords&service=CSW&typeNames=tns:Record&namespace=xmlns(tns%3Dhttp://www.opengis.net/cat/csw/3.0)&version=3.0.0
+405e1ff1-5c75-4846-a28b-cfaff2a6921a,PYCSW_SERVER?config=tests/suites/csw30/default.cfg&elementSetName=summary&recordIds=urn:uuid:19887a8a-f6b0-4a63-ae56-7fba0e17801f,urn:uuid:e9330592-0932-474b-be34-c3a3bb67c7db&request=GetRecords&service=CSW&typeNames=Record&version=3.0.0
+43cd6471-6ac7-45bd-8ff9-148cb2de9a52,PYCSW_SERVER?config=tests/suites/csw30/default.cfg
+4566d2ec-1283-4a02-baed-a74fc5b47e37,PYCSW_SERVER?config=tests/suites/csw30/default.cfg&acceptVersions=3.0.0&sections=ServiceIdentification&request=GetCapabilities&service=CSW
+461bd4c5-6623-490d-9036-d91a2201e87b,PYCSW_SERVER?config=tests/suites/csw30/default.cfg&acceptVersions=3.0.0&sections=Filter_Capabilities&request=GetCapabilities&service=CSW
+5496894a-3877-4f62-a20b-5d7126f94925,PYCSW_SERVER?config=tests/suites/csw30/default.cfg&service=CSW&version=3.0.0&request=GetRecords&elementsetname=full&typenames=csw:Record&resulttype=results&q=&bbox=514432,5429689,529130,5451619&time=/&outputformat=application/xml&outputschema=http://www.opengis.net/cat/csw/3.0&startposition=1&maxrecords=&recordids=
+5a015f6a-bf14-4977-b1e3-6577eb0223c8,PYCSW_SERVER?config=tests/suites/csw30/default.cfg&service=CSW&version=3.0.0&request=GetRecords&elementsetname=full&typenames=csw:Record&resulttype=results&q=&bbox=-6.17,44.79,17.92,68.41&time=/&outputformat=application/xml&outputschema=http://www.opengis.net/cat/csw/3.0&startposition=1&maxrecords=&recordids=
+5c3a2390-1fb9-43f0-b96c-f48c7a69c990,PYCSW_SERVER?config=tests/suites/csw30/default.cfg&id=urn:uuid:88247b56-4cbc-4df9-9860-db3f8042e357&outputFormat=model/vnd.collada%2Bxml&request=GetRecordById&service=CSW&version=3.0.0
+5e9e67dc-18d6-4645-8111-c6263c88a61f,PYCSW_SERVER?config=tests/suites/csw30/default.cfg&acceptVersions=3.0.0&sections=OperationsMetadata&request=GetCapabilities&service=CSW
+604d9379-741c-42e5-b4cf-92e56c87fa64,PYCSW_SERVER?config=tests/suites/csw30/default.cfg&elementSetName=full&q=amet&request=GetRecords&service=CSW&typeNames=Record&version=3.0.0
+60e6af95-d5fc-465a-82e2-fd2e6d85e4af,PYCSW_SERVER?config=tests/suites/csw30/default.cfg&request=GetRecords&service=CSW&typeNames=UnknownType&version=3.0.0
+62ad94c2-b558-4265-a427-23d6677975d6,PYCSW_SERVER?config=tests/suites/csw30/default.cfg&mode=opensearch&service=CSW&version=3.0.0&request=GetRecords&elementsetname=full&typenames=csw:Record&resulttype=results&q=&bbox=&time=/&outputformat=application/atom+xml&startposition=1&maxrecords=&recordids=uid-bc5017e6-5cc8-4b03-aee7-d88f88caba0a
+6a5e247b-0961-4b8a-a0d6-35a491d9cfe7,PYCSW_SERVER?config=tests/suites/csw30/default.cfg&elementSetName=undefined-view&request=GetRecords&service=CSW&typeNames=Record&version=3.0.0
+6a9d0558-9d87-495b-b999-b49a3ef1cf99,PYCSW_SERVER?config=tests/suites/csw30/default.cfg
+6bd790c9-6019-4652-9c91-330a894d6700,PYCSW_SERVER?config=tests/suites/csw30/default.cfg&service=CSW&version=3.0.0&request=GetRecords&elementsetname=full&typenames=csw:Record&resulttype=results&q=Fusc%C3%A9%20Land&bbox=&time=/&outputformat=application/xml&outputschema=http://www.opengis.net/cat/csw/3.0&startposition=1&maxrecords=&recordids=
+6e9cba43-5e27-415d-adbd-a92851c2c173,PYCSW_SERVER?config=tests/suites/csw30/default.cfg&acceptVersions=3.0.0&request=GetCapabilities&service=CSW
+7630d230-e142-4a09-accf-f091000b90cd,PYCSW_SERVER?config=tests/suites/csw30/default.cfg&id=urn:uuid:66ae76b7-54ba-489b-a582-0f0633d96493&request=GetRecordById&service=CSW&version=3.0.0
+7e82446a-b5dc-43fe-9a73-4cc1f2f2f0bf,PYCSW_SERVER?config=tests/suites/csw30/default.cfg&acceptFormats=text/xml&acceptVersions=3.0.0&request=GetCapabilities&service=CSW
+8025978e-1a35-4d70-80c2-e8329e0c7864,PYCSW_SERVER?config=tests/suites/csw30/default.cfg
+8184ae4f-536d-4978-8b28-ad703be96967,PYCSW_SERVER?config=tests/suites/csw30/default.cfg&elementSetName=brief&bbox=44.79,-6.17,68.41,17.92,urn:ogc:def:crs:EPSG::4326&request=GetRecords&service=CSW&typeNames=Record&version=3.0.0
+88f63a89-664f-4315-b4f8-04a0b33803a7,PYCSW_SERVER?config=tests/suites/csw30/default.cfg&maxRecords=15&elementSetName=summary&q=Mauris&bbox=-6.17,44.79,17.92,68.41&request=GetRecords&service=CSW&typeNames=Record&version=3.0.0
+8987f8f0-4d93-4481-968c-a2ccbd6b8be2,PYCSW_SERVER?config=tests/suites/csw30/default.cfg&id=urn:example:1461546298217&request=GetRecordById&service=CSW&version=3.0.0
+8e5fa0f6-3f29-4d1f-abe2-d9866f3def98,PYCSW_SERVER?config=tests/suites/csw30/default.cfg&mode=opensearch&service=CSW&version=3.0.0&request=GetRecords&elementsetname=full&typenames=csw:Record&resulttype=results&q=&bbox=-180,-90,180,90&time=/&outputformat=application/atom+xml&startposition=1&maxrecords=&recordids=
+9000ec29-5649-474e-b2d6-55c00f8a52c0,PYCSW_SERVER?config=tests/suites/csw30/default.cfg&acceptVersions=9999.12.31&request=GetCapabilities&service=CSW
+91914d35-7bbf-45e6-9b37-5ef484869a4e,PYCSW_SERVER?config=tests/suites/csw30/default.cfg&elementSetName=summary&bbox=-6.17,44.79,17.92,68.41&request=GetRecords&service=CSW&typeNames=Record&version=3.0.0
+92d4844d-57d5-4cf3-8f47-ba50e369dc04,PYCSW_SERVER?config=tests/suites/csw30/default.cfg&elementSetName=full&q=atkovxqmf&request=GetRecords&service=CSW&typeNames=Record&version=3.0.0
+9c0e2a4b-b4e6-41c0-b630-c8c99fc89ff3,PYCSW_SERVER?config=tests/suites/csw30/default.cfg&elementSetName=brief&outputSchema=urn:uuid:6a29d2a8-9651-47a6-9b14-f05d2b5644f0&request=GetRecords&service=CSW&typeNames=Record&version=3.0.0
+9d7ffac8-9798-428d-8e27-3cd12497ee6b,PYCSW_SERVER?config=tests/suites/csw30/default.cfg&id=urn:uuid:1ef30a8b-876d-4828-9246-c37ab4510bbd&outputSchema=http://www.example.org/ns/alpha&request=GetRecordById&service=CSW&version=3.0.0
+a2f18643-e24e-4fa5-b780-6de4a2dbc814,PYCSW_SERVER?config=tests/suites/csw30/default.cfg&id=urn:uuid:829babb0-b2f1-49e1-8cd5-7b489fe71a1e&outputFormat=application/atom%2Bxml&request=GetRecordById&service=CSW&version=3.0.0
+abc90c8c-5868-4405-a73e-64c849be3b2a,PYCSW_SERVER?config=tests/suites/csw30/default.cfg&mode=opensearch&service=CSW&version=3.0.0&request=GetRecords&elementsetname=full&typenames=csw:Record&resulttype=results&q=&bbox=514432,5429689,529130,5451619&time=/&outputformat=application/atom+xml&startposition=1&maxrecords=&recordids=
+ad0c0571-09ed-436a-9a4f-a5de744c88fe,PYCSW_SERVER?config=tests/suites/csw30/default.cfg&maxRecords=2&elementSetName=summary&request=GetRecords&service=CSW&typeNames=csw3:Record&startPosition=3&namespace=xmlns(csw3%3Dhttp://www.opengis.net/cat/csw/3.0)&version=3.0.0
+af502903-f4ee-47ee-b76e-af878d238bcc,PYCSW_SERVER?config=tests/suites/csw30/default.cfg&service=CSW&version=3.0.0&request=GetRecords&elementsetname=full&typenames=csw:Record&resulttype=results&q=&bbox=-180,-90,180,90&time=/&outputformat=application/xml&outputschema=http://www.opengis.net/cat/csw/3.0&startposition=1&maxrecords=&recordids=
+b2aafc3f-4f35-47bc-affd-08590972deae,PYCSW_SERVER?config=tests/suites/csw30/default.cfg&mode=opensearch&service=CSW&version=3.0.0&request=GetRecords&elementsetname=full&typenames=csw:Record&resulttype=results&q=&bbox=-6.17,44.79,17.92,68.41&time=/&outputformat=application/atom+xml&startposition=1&maxrecords=&recordids=
+b6069623-f7d8-4021-8582-98f0aea0f763,PYCSW_SERVER?config=tests/suites/csw30/default.cfg&mode=opensearch&service=CSW&version=3.0.0&request=GetRecords&elementsetname=full&typenames=csw:Record&resulttype=results&q=&bbox=&time=/&outputformat=application/atom+xml&startposition=3&maxrecords=4&recordids=
+b9a07a54-75a8-45bd-b341-2823600211e3,PYCSW_SERVER?config=tests/suites/csw30/default.cfg&elementSetName=brief&bbox=472944,5363287,492722,5455253,urn:ogc:def:crs:EPSG::0000&request=GetRecords&service=CSW&typeNames=Record&version=3.0.0
+baa4a7d0-0c01-42b6-adc3-0d03e9949fa3,PYCSW_SERVER?config=tests/suites/csw30/default.cfg&acceptVersions=3.0.0&request=getCapabilities&service=CSW
+bfbe6409-f64a-4c89-acb3-50f260a5c743,PYCSW_SERVER?config=tests/suites/csw30/default.cfg&elementSetName=summary&q=Fusc%C3%A9%20Land&request=GetRecords&service=CSW&typeNames=Record&version=3.0.0
+bfe20134-d1da-42ef-9c0f-8e1307bbf92b,PYCSW_SERVER?config=tests/suites/csw30/default.cfg&service=CSW&version=3.0.0&request=GetRecords&elementsetname=full&typenames=csw:Record&resulttype=results&q=&bbox=&time=/&outputformat=application/xml&outputschema=http://www.opengis.net/cat/csw/3.0&startposition=3&maxrecords=4&recordids=
+c03d173a-3f42-4956-89c8-1fe02c3a0873,PYCSW_SERVER?config=tests/suites/csw30/default.cfg&SERVICE=CSW&Request=GetCapabilities&acceptversions=3.0.0
+cb43d8c3-e14c-4a9f-9231-4384b7dd21f3,PYCSW_SERVER?config=tests/suites/csw30/default.cfg&elementName=undefined&request=GetRecords&service=CSW&typeNames=Record&version=3.0.0
+d03c6fd3-e821-4a26-b62f-d20a474e25af,PYCSW_SERVER?config=tests/suites/csw30/default.cfg&acceptVersions=3.0.0&sections=ServiceProvider&request=GetCapabilities&service=CSW
+d4ccbf96-a529-480e-a53d-5b88dc1dea7f,PYCSW_SERVER?config=tests/suites/csw30/default.cfg&service=CSW&version=3.0.0&request=GetRecords&elementsetname=full&typenames=csw:Record&resulttype=results&q=&bbox=&time=/&outputformat=application/xml&outputschema=http://www.opengis.net/cat/csw/3.0&startposition=1&maxrecords=&recordids=uid-bc5017e6-5cc8-4b03-aee7-d88f88caba0a
+d94c801a-1207-4897-b84a-53f3a192515b,PYCSW_SERVER?config=tests/suites/csw30/default.cfg&service=CSW&version=3.0.0&request=GetRecords&elementsetname=full&typenames=csw:Record&resulttype=results&q=lpppclq&bbox=&time=/&outputformat=application/xml&outputschema=http://www.opengis.net/cat/csw/3.0&startposition=1&maxrecords=&recordids=
+da859e34-91fc-495a-8c09-285a40c0900b,PYCSW_SERVER?config=tests/suites/csw30/default.cfg&id=urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63&elementSetName=full&request=GetRecordById&service=CSW&version=3.0.0
+dc246fb8-5af5-4fda-82bb-c18b3ecd439c,PYCSW_SERVER?config=tests/suites/csw30/default.cfg&mode=opensearch&service=CSW&version=3.0.0&request=GetRecords&elementsetname=full&typenames=csw:Record&resulttype=results&q=ipsum&bbox=&time=/&outputformat=application/atom+xml&startposition=1&maxrecords=&recordids=
+de016645-6d5c-4855-943c-2db07ae9f49a,PYCSW_SERVER?config=tests/suites/csw30/default.cfg&mode=opensearch&service=CSW&version=3.0.0&request=GetRecords&elementsetname=full&typenames=csw:Record&resulttype=results&q=&bbox=&time=/&outputformat=application/atom+xml&startposition=1&maxrecords=&recordids=urn%3Auuid%3A94bc9c83-97f6-4b40-9eb8-a8e8787a5c63
+dff3ec6b-bb2d-4887-bd17-8fcf15def042,PYCSW_SERVER?config=tests/suites/csw30/default.cfg&elementSetName=summary&request=GetRecords&service=CSW&typeNames=Record&version=3.0.0
+e38e6bfb-8ac4-4ae4-8b87-0aafbc8d3c6b,PYCSW_SERVER?config=tests/suites/csw30/default.cfg&id=urn:uuid:1ef30a8b-876d-4828-9246-c37ab4510bbd&elementSetName=brief&request=GetRecordById&service=CSW&version=3.0.0
+e67ca935-d65d-4d8c-8302-1405333dded0,PYCSW_SERVER?config=tests/suites/csw30/default.cfg
+e7704509-3441-458f-8ef0-e333c6b6043f,PYCSW_SERVER?config=tests/suites/csw30/default.cfg&elementName=ns1:subject&elementSetName=brief&request=GetRecords&service=CSW&typeNames=Record&namespace=xmlns(ns1%3Dhttp://purl.org/dc/elements/1.1/)&version=3.0.0
+f1223a49-6d08-44ff-97fe-4c32cbbfad82,PYCSW_SERVER?config=tests/suites/csw30/default.cfg&elementSetName=summary&maxRecords=0&q=titles&request=GetRecords&service=CSW&typeNames=Record&version=3.0.0
+f89dd4e1-3a81-4433-afd2-a3fa1bdb1e18,PYCSW_SERVER?config=tests/suites/csw30/default.cfg&elementSetName=full&outputFormat=text/example&request=GetRecords&service=CSW&typeNames=Record&version=3.0.0
diff --git a/tests/suites/csw30/post/Exception-GetDomain-parametername-bad.xml b/tests/suites/csw30/post/Exception-GetDomain-parametername-bad.xml
new file mode 100644
index 0000000..beeda82
--- /dev/null
+++ b/tests/suites/csw30/post/Exception-GetDomain-parametername-bad.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<csw30:GetDomain service="CSW" version="3.0.0" xmlns:csw30="http://www.opengis.net/cat/csw/3.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/cat/csw/3.0 http://schemas.opengis.net/csw/3.0/cswAll.xsd">
+   <csw30:ParameterName>GetRecords.outputFormat-something</csw30:ParameterName>
+</csw30:GetDomain>
diff --git a/tests/suites/csw30/post/Exception-GetDomain-valuereference-bad.xml b/tests/suites/csw30/post/Exception-GetDomain-valuereference-bad.xml
new file mode 100644
index 0000000..64184b6
--- /dev/null
+++ b/tests/suites/csw30/post/Exception-GetDomain-valuereference-bad.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<csw30:GetDomain service="CSW" version="3.0.0" xmlns:csw30="http://www.opengis.net/cat/csw/3.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/cat/csw/3.0 http://schemas.opengis.net/csw/3.0/cswAll.xsd">
+   <csw30:ValueReference>dc:titlena</csw30:ValueReference>
+</csw30:GetDomain>
diff --git a/tests/suites/csw30/post/Exception-GetRecordById-404.xml b/tests/suites/csw30/post/Exception-GetRecordById-404.xml
new file mode 100644
index 0000000..41528ed
--- /dev/null
+++ b/tests/suites/csw30/post/Exception-GetRecordById-404.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<csw30:GetRecordById service="CSW" version="3.0.0" xmlns:csw30="http://www.opengis.net/cat/csw/3.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/cat/csw/3.0 http://schemas.opengis.net/csw/3.0/cswAll.xsd">
+   <csw30:Id>does_not_exist</csw30:Id>
+</csw30:GetRecordById>
diff --git a/tests/suites/csw30/post/Exception-GetRecordById-bad-esn.xml b/tests/suites/csw30/post/Exception-GetRecordById-bad-esn.xml
new file mode 100644
index 0000000..2ab7127
--- /dev/null
+++ b/tests/suites/csw30/post/Exception-GetRecordById-bad-esn.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<csw30:GetRecordById service="CSW" version="3.0.0" xmlns:csw30="http://www.opengis.net/cat/csw/3.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/cat/csw/3.0 http://schemas.opengis.net/csw/3.0/cswAll.xsd">
+   <csw30:Id>urn:uuid:19887a8a-f6b0-4a63-ae56-7fba0e17801f</csw30:Id>
+   <csw30:ElementSetName>bad</csw30:ElementSetName>
+</csw30:GetRecordById>
diff --git a/tests/suites/csw30/post/Exception-bad-xml.xml b/tests/suites/csw30/post/Exception-bad-xml.xml
new file mode 100644
index 0000000..6ba741f
--- /dev/null
+++ b/tests/suites/csw30/post/Exception-bad-xml.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<csw30:GetCapabilities service="CSW" xmlns:ows20="http://www.opengis.net/ows/2.0" xmlns:csw30="http://www.opengis.net/cat/csw/3.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/cat/csw/3.0 http://schemas.opengis.net/csw/3.0/cswAll.xsd"> 
+   <ows20:AcceptVersions>
+      <ows20:Version>3.0.0</ows20:Version>
+   </ows20:AcceptVersions>
+   <ows20:AcceptFormats>
+      <ows20:OutputFormat>application/xml</ows20:OutputFormat>
+   </ows20:AcceptFormats>
+</csw30:GetCapabilities-bad>
diff --git a/tests/suites/csw30/post/Exception-not-xml.xml b/tests/suites/csw30/post/Exception-not-xml.xml
new file mode 100644
index 0000000..2b25300
--- /dev/null
+++ b/tests/suites/csw30/post/Exception-not-xml.xml
@@ -0,0 +1 @@
+not an XML payload
diff --git a/tests/suites/csw30/post/GetCapabilities.xml b/tests/suites/csw30/post/GetCapabilities.xml
new file mode 100644
index 0000000..3e80d5c
--- /dev/null
+++ b/tests/suites/csw30/post/GetCapabilities.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<csw30:GetCapabilities service="CSW" xmlns:ows20="http://www.opengis.net/ows/2.0" xmlns:csw30="http://www.opengis.net/cat/csw/3.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/cat/csw/3.0 http://schemas.opengis.net/csw/3.0/cswAll.xsd"> 
+   <ows20:AcceptVersions>
+      <ows20:Version>3.0.0</ows20:Version>
+   </ows20:AcceptVersions>
+   <ows20:AcceptFormats>
+      <ows20:OutputFormat>application/xml</ows20:OutputFormat>
+   </ows20:AcceptFormats>
+</csw30:GetCapabilities>
diff --git a/tests/suites/csw30/post/GetDomain-parametername.xml b/tests/suites/csw30/post/GetDomain-parametername.xml
new file mode 100644
index 0000000..00ca59f
--- /dev/null
+++ b/tests/suites/csw30/post/GetDomain-parametername.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<csw30:GetDomain service="CSW" version="3.0.0" xmlns:csw30="http://www.opengis.net/cat/csw/3.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/cat/csw/3.0 http://schemas.opengis.net/csw/3.0/cswAll.xsd">
+   <csw30:ParameterName>GetRecords.outputFormat</csw30:ParameterName>
+</csw30:GetDomain>
diff --git a/tests/suites/csw30/post/GetDomain-valuereference.xml b/tests/suites/csw30/post/GetDomain-valuereference.xml
new file mode 100644
index 0000000..7cfd0eb
--- /dev/null
+++ b/tests/suites/csw30/post/GetDomain-valuereference.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<csw30:GetDomain service="CSW" version="3.0.0" xmlns:csw30="http://www.opengis.net/cat/csw/3.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/cat/csw/3.0 http://schemas.opengis.net/csw/3.0/cswAll.xsd">
+   <csw30:ValueReference>dc:title</csw30:ValueReference>
+</csw30:GetDomain>
diff --git a/tests/suites/csw30/post/GetRecordById-dc-full.xml b/tests/suites/csw30/post/GetRecordById-dc-full.xml
new file mode 100644
index 0000000..9250490
--- /dev/null
+++ b/tests/suites/csw30/post/GetRecordById-dc-full.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<csw30:GetRecordById service="CSW" version="3.0.0" xmlns:csw30="http://www.opengis.net/cat/csw/3.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/cat/csw/3.0 http://schemas.opengis.net/csw/3.0/cswAll.xsd">
+   <csw30:Id>urn:uuid:19887a8a-f6b0-4a63-ae56-7fba0e17801f</csw30:Id>
+   <csw30:ElementSetName>full</csw30:ElementSetName>
+</csw30:GetRecordById>
diff --git a/tests/suites/csw30/post/GetRecordById-dc.xml b/tests/suites/csw30/post/GetRecordById-dc.xml
new file mode 100644
index 0000000..148f0e4
--- /dev/null
+++ b/tests/suites/csw30/post/GetRecordById-dc.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<csw30:GetRecordById service="CSW" version="3.0.0" xmlns:csw30="http://www.opengis.net/cat/csw/3.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/cat/csw/3.0 http://schemas.opengis.net/csw/3.0/cswAll.xsd">
+   <csw30:Id>urn:uuid:19887a8a-f6b0-4a63-ae56-7fba0e17801f</csw30:Id>
+</csw30:GetRecordById>
diff --git a/tests/suites/default/get/requests.txt b/tests/suites/default/get/requests.txt
index ad0fa8e..14f72e8 100644
--- a/tests/suites/default/get/requests.txt
+++ b/tests/suites/default/get/requests.txt
@@ -6,3 +6,6 @@ GetRecords-sortby-desc,PYCSW_SERVER?config=tests/suites/default/default.cfg&serv
 GetRecords-sortby-invalid-propertyname,PYCSW_SERVER?config=tests/suites/default/default.cfg&service=CSW&version=2.0.2&request=GetRecords&typenames=csw:Record&elementsetname=full&resulttype=results&sortby=dc:titlei:A
 GetRecords-sortby-invalid-order,PYCSW_SERVER?config=tests/suites/default/default.cfg&service=CSW&version=2.0.2&request=GetRecords&typenames=csw:Record&elementsetname=full&resulttype=results&sortby=dc:title:FOO
 GetRecords-filter,PYCSW_SERVER?config=tests/suites/default/default.cfg&service=CSW&version=2.0.2&request=GetRecords&typenames=csw:Record&elementsetname=full&resulttype=results&constraintlanguage=FILTER&constraint=%3Cogc%3AFilter%20xmlns%3Aogc%3D%22http%3A%2F%2Fwww.opengis.net%2Fogc%22%3E%3Cogc%3APropertyIsEqualTo%3E%3Cogc%3APropertyName%3Edc%3Atitle%3C%2Fogc%3APropertyName%3E%3Cogc%3ALiteral%3ELorem%20ipsum%3C%2Fogc%3ALiteral%3E%3C%2Fogc%3APropertyIsEqualTo%3E%3C%2Fogc%3AFilter%3E
+GetRecords-empty-maxrecords,PYCSW_SERVER?config=tests/suites/default/default.cfg&service=CSW&version=2.0.2&request=GetRecords&typenames=csw:Record&elementsetname=full&maxrecords=
+GetRepositoryItem,PYCSW_SERVER?config=tests/suites/default/default.cfg&service=CSW&version=2.0.2&request=GetRepositoryItem&id=urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63
+Exception-GetRepositoryItem-notfound,PYCSW_SERVER?config=tests/suites/default/default.cfg&service=CSW&version=2.0.2&request=GetRepositoryItem&id=NOTFOUND
diff --git a/default-sample.cfg b/tests/suites/gm03/default.cfg
similarity index 65%
copy from default-sample.cfg
copy to tests/suites/gm03/default.cfg
index 5420a7f..c673253 100644
--- a/default-sample.cfg
+++ b/tests/suites/gm03/default.cfg
@@ -2,7 +2,7 @@
 #
 # Authors: Tom Kralidis <tomkralidis at gmail.com>
 #
-# Copyright (c) 2010 Tom Kralidis
+# Copyright (c) 2011 Tom Kralidis
 #
 # Permission is hereby granted, free of charge, to any person
 # obtaining a copy of this software and associated documentation
@@ -28,8 +28,8 @@
 # =================================================================
 
 [server]
-home=/var/www/pycsw
-url=http://localhost/pycsw/csw.py
+home=.
+url=http://localhost/pycsw/csw.py?config=tests/suites/gm03/default.cfg
 mimetype=application/xml; charset=UTF-8
 encoding=UTF-8
 language=en-US
@@ -37,62 +37,54 @@ maxrecords=10
 #loglevel=DEBUG
 #logfile=/tmp/pycsw.log
 #ogc_schemas_base=http://foo
-#federatedcatalogues=http://geo.data.gov/geoportal/csw/discovery
-#pretty_print=true
+federatedcatalogues=http://geo.data.gov/geoportal/csw/discovery
+pretty_print=true
 #gzip_compresslevel=8
-#domainquerytype=range
-#domaincounts=true
 #spatial_ranking=true
-profiles=apiso
 
 [manager]
 transactions=false
 allowed_ips=127.0.0.1
-#csw_harvest_pagesize=10
 
 [metadata:main]
 identification_title=pycsw Geospatial Catalogue
 identification_abstract=pycsw is an OGC CSW server implementation written in Python
-identification_keywords=catalogue,discovery,metadata
+identification_keywords=catalogue,discovery
 identification_keywords_type=theme
 identification_fees=None
 identification_accessconstraints=None
-provider_name=Organization Name
+provider_name=pycsw
 provider_url=http://pycsw.org/
-contact_name=Lastname, Firstname
-contact_position=Position Title
-contact_address=Mailing Address
-contact_city=City
-contact_stateorprovince=Administrative Area
-contact_postalcode=Zip or Postal Code
-contact_country=Country
-contact_phone=+xx-xxx-xxx-xxxx
-contact_fax=+xx-xxx-xxx-xxxx
-contact_email=Email Address
-contact_url=Contact URL
-contact_hours=Hours of Service
+contact_name=Kralidis, Tom
+contact_position=Senior Systems Scientist
+contact_address=TBA
+contact_city=Toronto
+contact_stateorprovince=Ontario
+contact_postalcode=M9C 3Z9
+contact_country=Canada
+contact_phone=+01-416-xxx-xxxx
+contact_fax=+01-416-xxx-xxxx
+contact_email=tomkralidis at gmail.com
+contact_url=http://kralidis.ca/
+contact_hours=0800h - 1600h EST
 contact_instructions=During hours of service.  Off on weekends.
 contact_role=pointOfContact
 
 [repository]
 # sqlite
-database=sqlite:////var/www/pycsw/tests/suites/cite/data/records.db
+database=sqlite:///tests/suites/cite/data/records.db
 # postgres
-#database=postgresql://username:password@localhost/pycsw
-# mysql
-#database=mysql://username:password@localhost/pycsw?charset=utf8
-#mappings=path/to/mappings.py
+#database=postgres://username:password@localhost/pycsw
 table=records
-#filter=type = 'http://purl.org/dc/dcmitype/Dataset'
 
 [metadata:inspire]
-enabled=true
+enabled=false
 languages_supported=eng,gre
 default_language=eng
-date=YYYY-MM-DD
+date=2011-03-29
 gemet_keywords=Utility and governmental services
 conformity_service=notEvaluated
-contact_name=Organization Name
-contact_email=Email Address
-temp_extent=YYYY-MM-DD/YYYY-MM-DD
+contact_name=National Technical University of Athens
+contact_email=tzotsos at gmail.com
+temp_extent=2011-02-01/2011-03-30
 
diff --git a/tests/suites/gm03/post/GetCapabilities.xml b/tests/suites/gm03/post/GetCapabilities.xml
new file mode 100644
index 0000000..e4dc807
--- /dev/null
+++ b/tests/suites/gm03/post/GetCapabilities.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<GetCapabilities xmlns="http://www.opengis.net/cat/csw/2.0.2" xmlns:ows="http://www.opengis.net/ows" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/cat/csw/2.0.2 http://schemas.opengis.net/csw/2.0.2/CSW-discovery.xsd" service="CSW">
+   <ows:AcceptVersions>
+      <ows:Version>2.0.2</ows:Version>
+   </ows:AcceptVersions>
+   <ows:AcceptFormats>
+      <ows:OutputFormat>application/xml</ows:OutputFormat>
+   </ows:AcceptFormats>
+</GetCapabilities>
diff --git a/tests/suites/gm03/post/GetRecords-filter-bbox.xml b/tests/suites/gm03/post/GetRecords-filter-bbox.xml
new file mode 100644
index 0000000..4b23191
--- /dev/null
+++ b/tests/suites/gm03/post/GetRecords-filter-bbox.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="ISO-8859-1" standalone="no"?>
+<csw:GetRecords xmlns:fgdc="http://www.opengis.net/cat/csw/csdgm" xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:ogc="http://www.opengis.net/ogc" service="CSW" version="2.0.2" resultType="results" startPosition="1" maxRecords="5" outputFormat="application/xml" outputSchema="http://www.interlis.ch/INTERLIS2.3" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/cat/csw/2.0.2 http://schemas.opengis.net/csw/2.0.2/CSW-discovery.xsd" xmlns: [...]
+    <csw:Query typeNames="csw:Record">
+        <csw:ElementSetName>brief</csw:ElementSetName>
+        <csw:Constraint version="1.1.0">
+            <ogc:Filter>
+				<ogc:BBOX>
+					<ogc:PropertyName>ows:BoundingBox</ogc:PropertyName>
+					<gml:Envelope>
+						<gml:lowerCorner>47 -5</gml:lowerCorner>
+						<gml:upperCorner>55 20</gml:upperCorner>
+					</gml:Envelope>
+				</ogc:BBOX>
+            </ogc:Filter>
+        </csw:Constraint>
+    </csw:Query>
+</csw:GetRecords>
diff --git a/tests/suites/harvesting/post/Harvest-csw-iso.xml b/tests/suites/harvesting/post/Harvest-csw-iso.xml
index dd8d736..b5ce582 100644
--- a/tests/suites/harvesting/post/Harvest-csw-iso.xml
+++ b/tests/suites/harvesting/post/Harvest-csw-iso.xml
@@ -1,7 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<Harvest xmlns="http://www.opengis.net/cat/csw/2.0.2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/cat/csw/2.0.2 htt
-p://schemas.opengis.net/csw/2.0.2/CSW-publication.xsd" service="CSW" version="2.0.2">
-  <Source>http://sdi.georchestra.org/geoserver/ows</Source>
+<Harvest xmlns="http://www.opengis.net/cat/csw/2.0.2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/cat/csw/2.0.2 http://schemas.opengis.net/csw/2.0.2/CSW-publication.xsd" service="CSW" version="2.0.2">
+  <Source>http://demo.pycsw.org/services/csw</Source>
   <ResourceType>http://www.opengis.net/cat/csw/2.0.2</ResourceType>
   <ResourceFormat>application/xml</ResourceFormat>
 </Harvest>
diff --git a/tests/suites/harvesting/post/Harvest-wmts.xml b/tests/suites/harvesting/post/Harvest-wmts.xml
new file mode 100644
index 0000000..93e224f
--- /dev/null
+++ b/tests/suites/harvesting/post/Harvest-wmts.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Harvest xmlns="http://www.opengis.net/cat/csw/2.0.2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/cat/csw/2.0.2 http://schemas.opengis.net/csw/2.0.2/CSW-publication.xsd" service="CSW" version="2.0.2">
+  <Source>http://map1c.vis.earthdata.nasa.gov/wmts-geo/wmts.cgi</Source>
+  <ResourceType>http://www.opengis.net/wmts/1.0</ResourceType>
+  <ResourceFormat>application/xml</ResourceFormat>
+</Harvest>

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-grass/pycsw.git



More information about the Pkg-grass-devel mailing list