Re: [xsl] Process map entries in defined order

Subject: Re: [xsl] Process map entries in defined order
From: "Imsieke, Gerrit, le-tex gerrit.imsieke@xxxxxxxxx" <xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx>
Date: Mon, 30 Jun 2025 08:01:28 -0000
Did you raise this before? [1]

In XPath 4.0, maps are ordered by default. [2]

BaseX has already rolled out sorted maps, I donC"BBt know when Saxon will follow.

In the meantime, maybe use an XML document instead of maps?

Gerrit

[1] https://github.com/qt4cg/qtspecs/issues/564

[2] https://qt4cg.org/specifications/xpath-datamodel-40/Overview.html#map-items

On 30.06.2025 08:58, Michael Mueller-Hillebrand michael.mueller-hillebrand@xxxxxxxxx wrote:
Dear all,

I have a scenario with a user-defined set of substitutions which should be applied to text nodes (a.k.a. strings). The XML is built like this:

 CB CB CB CB CB CB CB  <substitute search="car" replace="auto"/>
 CB CB CB CB CB CB CB  <substitute search="auto" replace="mobile"/>

As you can see from this little example the order of replacements is important. I started with creating a map(xs:string, xs:string) for the search and replace terms. Recursively applying the substitutions uses map:keys($subs). Next, I learned from the specification that this function C"BBReturns the set of keys found in an input map, in arbitrary order.C"BB

Since I want to honor the order given by the user, I think the only way out is to change my map to include an integer key and feature the search and replace string as the entry value: map(xs:integer, xs:string+) and always sort the list of keys by number.

Or is there another smoother way handling this challenge?

Best regards,

Michael

FYI, this is the current function I am using:

 CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB  <xsl:function name="dy:applySubstitutions" as="xs:string">
 CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB  <xsl:param name="text" as="xs:string"/>
 CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB  <xsl:param name="subs" as="map(xs:string, xs:string)"/>
 CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB  <xsl:choose>
 CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB  <xsl:when test="/map:size/(*$subs*) eq 0">
 CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB  <!-- no substitutions leftCB  -->
 CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB  <xsl:sequence select="*$text*"/>
 CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB  </xsl:when>
 CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB  <xsl:otherwise>
 CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB  <!-- process first, then do recursive call -->
 CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB  <xsl:variable name="key" select="/map:keys/(*$subs*)[1]" as="xs:string"/>

 CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB  <xsl:variable name="result" select="*$text* => /replace/(*$key*, /map:get/(*$subs*, *$key*))"/>
 CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB  <xsl:sequence select="/dy:applySubstitutions/(*$result*, /map:remove/(*$subs*, *$key*))"/>
 CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB  </xsl:otherwise>
 CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB  </xsl:choose>
 CB CB CB CB CB CB CB CB CB CB CB CB CB CB CB  </xsl:function>

XSL-List info and archive <http://www.mulberrytech.com/xsl/xsl-list>
EasyUnsubscribe <http://lists.mulberrytech.com/unsub/xsl-list/225679> (by email <>)

-- Gerrit Imsieke GeschCB$ftsfCB<hrer / Managing Director le-tex publishing services GmbH Weissenfelser Str. 84, 04229 Leipzig, Germany Phone +49 341 355356 110, Fax +49 341 355356 510 gerrit.imsieke@xxxxxxxxx, http://www.le-tex.de

Registergericht / Commercial Register: Amtsgericht Leipzig
Registernummer / Registration Number: HRB 24930

GeschCB$ftsfCB<hrer / Managing Directors:
Gerrit Imsieke, Svea Jelonek, Thomas Schmidt

Current Thread