Skip to content

Commit e16ce57

Browse files
committed
Formatter / Full view missing/extra matching nodes
In #9000, we added a tentative fix for improving labels when translations contains labels with xpath context. eg. ```xml <element name="gmd:description" context="/gmd:MD_Metadata/gmd:identificationInfo/gmd:MD_DataIdentification/gmd:extent/gmd:EX_Extent/gmd:description"> <label>Beschrijving temporele dekking</label> <description>temporele dekking van de data, gespecificeerd als een periode.</description> </element> ``` This was not working due to the formatter reading the editor config, find matching field/section to render using saxon `evaluate` function. One drawback is that when using this function, the returned node does not have its context (eg. `..` to get its parent). So the logic to get label based on xpath can't work. To avoid this a check was made to retrieve the corresponding the original node in the document and `deep-equal` function was used for that. But we noticed some case not handled * #9163 2 sections matching the xpath of the editor config (due to wrong usage of deep-equal) * More than one node matching at different location in the document (eg. a DCAT-AP document with the same license in Catalog and Service will display the 2 license for the service). * No matching element when using a section with a forEach attribute. Note: In edit mode, unique ref in `gn:element` is used to retrieve original node which is more reliable but can't be used in view mode. Proposal is to find the original node using `deep-equal` and then checking using node xpath matching when the xpath does not make use of wildcard. If wildcard, then `evaluate` returned nodes are used (and may cause the label issue). Related * #9000 * #9163
1 parent de01d4b commit e16ce57

File tree

1 file changed

+25
-4
lines changed

1 file changed

+25
-4
lines changed

web/src/main/webapp/WEB-INF/data/data/formatter/xslt/render-layout.xsl

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -556,11 +556,13 @@
556556
<xsl:param name="collapsible" as="xs:boolean" select="true()" required="no"/>
557557
<xsl:param name="collapsed" as="xs:boolean" select="false()" required="no"/>
558558

559-
<!-- Matching nodes -->
559+
<xsl:variable name="xpath" select="."/>
560+
561+
<!-- Matching nodes (without context) -->
560562
<xsl:variable name="nodes">
561563
<saxon:call-template name="{concat('evaluate-', $schema)}">
562564
<xsl:with-param name="base" select="$base"/>
563-
<xsl:with-param name="in" select="concat('/../', .)"/>
565+
<xsl:with-param name="in" select="concat('/../', $xpath)"/>
564566
</saxon:call-template>
565567
</xsl:variable>
566568

@@ -570,8 +572,27 @@
570572
</xsl:if>
571573
</xsl:variable>
572574

573-
<!-- The matching nodes when using evaluate loose their context, re-calculate it -->
574-
<xsl:variable name="originalNodes" select="$metadata//*[deep-equal(., $nodes/*)]"/>
575+
<!--
576+
The matching nodes when using evaluate lose their context and the context may be used to get labels.
577+
The base can be the root (the metadata document) or a sub element if the field is in a section with forEach.
578+
579+
* Use deep-equal function to find nodes which are identical to the matching nodes.
580+
* Check that those identical nodes are located at the xpath location matching the requested xpath.
581+
-->
582+
<xsl:variable name="parentForEachSection"
583+
select="ancestor::section[@forEach][1]"/>
584+
585+
<xsl:variable name="fullXpath"
586+
select="if ($parentForEachSection) then concat($parentForEachSection/@forEach, '/', $xpath) else $xpath"/>
587+
588+
<!-- May return nodes which are identical but located at another xpath location. -->
589+
<xsl:variable name="equalNodes" as="node()*"
590+
select="$metadata//*[some $nodeWithNoContext in $nodes/* satisfies deep-equal(., $nodeWithNoContext)]"/>
591+
592+
<!-- XPath using * will never match path matching. Using node without context.
593+
This only happens if editor configuration is using *. -->
594+
<xsl:variable name="originalNodes"
595+
select="if (contains($xpath, '/*/')) then $nodes else $equalNodes[concat('/', string-join(ancestor-or-self::*/name()[. != 'root'], '/')) = $fullXpath]"/>
575596

576597
<xsl:for-each select="$originalNodes">
577598
<xsl:apply-templates mode="render-field">

0 commit comments

Comments
 (0)