SEMICeu / iso-19139-to-dcat-ap

Reference XSLT-based implementation of GeoDCAT-AP
European Union Public License 1.2
15 stars 9 forks source link

Dev branch XSL fails under lxml and saxonche #47

Open streino opened 2 days ago

streino commented 2 days ago

https://github.com/SEMICeu/iso-19139-to-dcat-ap/pull/42 bumped the XSLT version to 2.0 to use a new XPath feature.

lxml (4.9.3) now fails to run iso-19139-to-dcat-ap.xsl, as it only supports XSLT and XPath 1.0:

Traceback (most recent call last):
  File "./xsl-apply.py", line 11, in <module>
    transform = etree.XSLT(xsl)
                ^^^^^^^^^^^^^^^
  File "src/lxml/xslt.pxi", line 413, in lxml.etree.XSLT.__init__
lxml.etree.XSLTParseError: XSLT-variable: Failed to compile the XPath expression 'if (gmd:codeSpace)                                 then concat(                                       gmd:codeSpace/(gco:CharacterString                                                      |gmx:Anchor/@xlink:href),                                       gmd:code/(gco:CharacterString                                                 |gmx:Anchor/@xlink:href))                                 else gmd:code/(gco:CharacterString/text()                                                |gmx:Anchor/@xlink:href)'.

Switching to saxonche (12.4.2), I get an error on some records (example):

Error in expression in xsl:when/@test on line 3979 column 218 of iso-19139-to-dcat-ap.xsl:
  FORG0001  Cannot convert string "RGF93 / Lambert-93 (EPSG:2154)" to double
  In template rule with match="gmd:referenceSystemInfo/gmd:MD_ReferenceSystem/gmd:referenceSystemIdentifier/gmd:RS_Identifier" on line 3898 of iso-19139-to-dcat-ap.xsl
     invoked by xsl:apply-templates at file:///tmp/iso-19139-to-dcat-ap.xsl#1279
  In template rule with match="//gmd:MD_Metadata" on line 429 of iso-19139-to-dcat-ap.xsl
     invoked by xsl:apply-templates at file:///tmp/iso-19139-to-dcat-ap.xsl#418
  In template rule with match="/" on line 416 of iso-19139-to-dcat-ap.xsl

Coming from the following test:

<xsl:when test="$code = number($code) ...">

This worked in XPath 1.0 but not in 2.0. Since 2.0 the type system fails when comparing incompatible types. Cf https://stackoverflow.com/questions/3854345/xpath-test-if-node-value-is-number.

Test code used to run the XSL: https://github.com/ecolabdata/ecospheres-scripts/blob/main/metadata/xsl-apply.py

streino commented 2 days ago

Possible fix: https://github.com/SEMICeu/iso-19139-to-dcat-ap/pull/48 Unless it is preferable to stick to version 1.0 for tooling compatibility?

streino commented 1 day ago

Ping @fxprunayre. You may have insights on this as #42 contributor?

fxprunayre commented 1 day ago

Unless it is preferable to stick to version 1.0 for tooling compatibility?

I don't know if there is any particular version to stick on.

FORG0001 Cannot convert string "RGF93 / Lambert-93 (EPSG:2154)" to double

Using check like $code castable as xs:double is probably an option.

eg. https://github.com/geonetwork/core-geonetwork/blob/fe54f4a17795924e8f1887db7c22bc7a7bd14a84/schemas/iso19139/src/main/plugin/iso19139/formatter/eu-geodcat-ap-semiceu/view.xsl#L4008

streino commented 1 day ago

Thanks for feedback @fxprunayre. Let's see what the maintainers say about version requirements.

The castable check would work too, and I believe you could remove $code = number($code) in the example you provide, since both tests check the same thing. I can update my PR if that solution is preferred.

jakubklimek commented 1 day ago

XSLT 2.0 is from 2007, so I think it is OK to require it. @uvoges can you see any problem of implementing XSLT 2.0 in data.europa.eu?