Skip to content

Fix PT_FreeText handling in eu-geodcat-ap-semiceu/view.xsl#9333

Open
laers wants to merge 3 commits into
geonetwork:mainfrom
laers:fix/eu-geodcat-ap-semiceu
Open

Fix PT_FreeText handling in eu-geodcat-ap-semiceu/view.xsl#9333
laers wants to merge 3 commits into
geonetwork:mainfrom
laers:fix/eu-geodcat-ap-semiceu

Conversation

@laers

@laers laers commented Jun 12, 2026

Copy link
Copy Markdown
Contributor

Attempt to serve ISO 19139 records via CSW with outputSchema=http://data.europa.eu/930/#semiceu fails with either:

•	Failed to compile stylesheet. 1 error detected. — at startup/first use
•	net.sf.saxon.trans.XPathException: A sequence of more than one item is not allowed as the first argument of normalize-space() — at runtime

The root cause is that many ISO 19139 records use xsi:type="gmd:PT_FreeText_PropertyType" on text fields such as individualName, name, description and electronicMailAddress. This means these elements have multiple child nodes — both a gco:CharacterString and a gmd:PT_FreeText element — rather than a single child.

Additionally, the LocalisedString template emitted duplicate language-tagged literals when a PT_FreeText locale value was identical to the primary gco:CharacterString value.

Changes:

  • Remove xmlns:xs namespace declaration — no longer needed after removing castable as xs:double
  • Remove as="node()*" type annotation on $uriIdentifiers variable — Saxon 9.1 Basic does not support type annotations on variables
  • Replace $code castable as xs:double with number($code) = number($code) — Saxon 9.1 Basic does not support the castable as operator
  • Fix normalize-space(gmd:individualName/) → normalize-space(gmd:individualName/[self::gco:CharacterString|self::gmx:Anchor]) — prevents XPTY0004 error when individualName has xsi:type="PT_FreeText_PropertyType" with multiple child nodes
  • Fix normalize-space(*) on gmd:name and gmd:description in distribution resources — same PT_FreeText issue
  • Fix electronicMailAddress/* → electronicMailAddress/gco:CharacterString — prevents email concatenation when PT_FreeText children are present
  • Fix LocalisedString template — added duplicate filtering so PT_FreeText localisations that are identical to the primary gco:CharacterString value are not emitted twice

Tested against https://data.europa.eu/mqa/shacl-validator-ui/data-provision

Response with current XSLT:
https://geodata-info.dk/srv/dan/csw?service=CSW&version=2.0.2&request=GetRecordById&outputSchema=http://data.europa.eu/930/%23semiceu&elementsetname=full&id=4aaf72e6-b4eb-4c4f-a472-d8639f60710f&resulttype=results&constraintlanguage=FILTER&constraint_language_version=1.1.0&namespace=xmlns(gmd=http%3A%2F%2Fwww.isotc211.org%2F2005%2Fgmd)&typenames=gmd:MD_Metadata&constraint=%3Cogc%3AFilter%20xmlns%3Acsw%3D%22http%3A%2F%2Fwww.opengis.net%2Fcat%2Fcsw%2F2.0.2%22%20xmlns%3Aogc%3D%22http%3A%2F%2Fwww.opengis.net%2Fogc%22%3E%3C%2Fogc%3AFilter%3E

Response with fixed XSLT:
https://test.geodata-info.dk/srv/dan/csw?service=CSW&version=2.0.2&request=GetRecordById&outputSchema=http://data.europa.eu/930/%23semiceu&elementsetname=full&id=4aaf72e6-b4eb-4c4f-a472-d8639f60710f&resulttype=results&constraintlanguage=FILTER&constraint_language_version=1.1.0&namespace=xmlns(gmd=http%3A%2F%2Fwww.isotc211.org%2F2005%2Fgmd)&typenames=gmd:MD_Metadata&constraint=%3Cogc%3AFilter%20xmlns%3Acsw%3D%22http%3A%2F%2Fwww.opengis.net%2Fcat%2Fcsw%2F2.0.2%22%20xmlns%3Aogc%3D%22http%3A%2F%2Fwww.opengis.net%2Fogc%22%3E%3C%2Fogc%3AFilter%3E

@laers laers changed the title Fix Saxon 9.1 Basic compatibility and PT_FreeText handling in eu-geodcat-ap-semiceu/view.xsl Fix PT_FreeText handling in eu-geodcat-ap-semiceu/view.xsl Jun 13, 2026
@fxprunayre

Copy link
Copy Markdown
Member

@laers is that change also in the SEMICeu repository? See https://github.com/SEMICeu/iso-19139-to-dcat-ap/commits/main/iso-19139-to-dcat-ap.xsl

In https://github.com/geonetwork/core-geonetwork/pull/9111/commits, SEMICeu conversion was aligned couple of times. Updated today.

Maybe you can check that PR and see if it resolve your case? and we can align GeoNetwork with latest version of the conversion.

@laers laers left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@fxprunayre

I tested the XLST (eu-geodcat-ap-semiceu/view.xsl) from #9111 but it did not work... I've updated my PR to build on top of the changes from #9111. The approach is the same, but with the following additional fixes required for Saxon 9.1 Basic compatibility:

  • xsl:function is not supported in Saxon 9.1 Basic — local:getTextContent and local:normalize-number have been replaced with inline XPath equivalents (normalize-space(*[self::gco:CharacterString|self::gmx:Anchor]) and format-number())
  • as="node()", as="xs:string" type annotations and xsl:sequence removed
  • *[self::gco:CharacterString|gmx:Anchor] → *[self::gco:CharacterString|self::gmx:Anchor] (missing self:: prefix caused runtime errors with PT_FreeText fields)
  • electronicMailAddress/* → electronicMailAddress/gco:CharacterString to prevent malformed mailto URIs

Tested on our Test-GeoNetwork instance (test.geodata-info.dk) with ISO 19139 records using xsi:type="PT_FreeText_PropertyType" and validated successfully against the data.europa.eu MQA SHACL Validator.

I have made a PR with the changes to #116

@laers
laers force-pushed the fix/eu-geodcat-ap-semiceu branch from 159468f to a366409 Compare June 17, 2026 13:09

@laers laers left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • Locale lookup root context: //gmd:PT_Locale[...] failed with The root of the tree containing the context item is not a document node when called from within a result-tree-fragment. Fixed by using root(.)//gmd:PT_Locale[...].
  • PT_Locale structure variance: records converted by GeoNetwork from ISO 19115-3.2018 use gmd:otherLocale/gmd:language, while native ISO 19139 records use gmd:locale/gmd:languageCode. The lookup now handles both.
  • Missing PT_Locale fallback: when GeoNetwork's 19115-3→19139 conversion drops defaultLocale, PT_FreeText values for that language had no matching PT_Locale and ended up with xml:lang="". Added a fallback that uses the locale-id itself (e.g. "DA"/"EN" from locale="#DA") when the PT_Locale lookup fails.
  • Duplicate prefLabel/keyword values: re-added deduplication so a PT_FreeText value identical to the primary gco:CharacterString isn't emitted twice.
  • Malformed language URIs: a data quality issue in source records (codeListValue="Dansk" instead of "dan") produced invalid URIs like .../language/DANSK. Added a normalization step for common full language names.
  • Text concatenation in online resource titles/descriptions: gmd:name/gmd:description for foaf:page links used an unrestricted * selector, causing PT_FreeText text to concatenate across languages. Restricted to gco:CharacterString/gmx:Anchor.

All fixes verified against multiple real production records (Saxon 9.1 Basic) with no remaining empty xml:lang attributes or duplicated content.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants