[xsl] storing the results of <xsl:analyze-string> in a map

Subject: [xsl] storing the results of <xsl:analyze-string> in a map
From: "Chris Papademetrious christopher.papademetrious@xxxxxxxxxxxx" <xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx>
Date: Wed, 22 Mar 2023 16:11:01 -0000
Given various DITA @href values:

test1.dita
test1.dita#test1_id
test1.dita#test1_id
test1.dita#test1_id/fig1_id
test1.dita#./fig1_id
test1.dita#test1_subtopic_id
test1.dita#test1_subtopic_id/fig2_id
#test1_id
#test1_id/fig1_id
#./fig1_id
#test1_subtopic_id
#test1_subtopic_id/fig2_id

I created a regular expression to parse a value into its file, topic ID, and
element ID components:

^([^#]*)(?:#([^/]+)(?:/(.+))?)?$

This pattern contains three capture groups. In XSLT, I needed a way to
persistently store the results for use in subsequent processing. I ended up
storing them in a map:

<xsl:variable name="href" as="map(*)">
  <xsl:analyze-string select="@href"
regex="^([^#]*)(?:#([^/]+)(?:/(.+))?)?$">
    <xsl:matching-substring>
      <xsl:sequence select="map{
        'file': regex-group(1),
        'topic_id': regex-group(2),
        'elt_id': regex-group(3)}"
    </xsl:matching-substring>
  </xsl:analyze-string>
</xsl:variable>

which allows the values to be queried as $href?file, $href?topic_id, and
$href?elt_id.

Actually for my application, I absorbed a bit of processing into the map
creation:

<xsl:variable name="href" as="map(*)">
  <xsl:analyze-string select="@href"
regex="^([^#]*)(?:#([^/]+)(?:/(.+))?)?$">
    <xsl:matching-substring>
      <xsl:sequence select="map{
        'file': if (regex-group(1) ne '') then resolve-uri(regex-group(1),
$current-uri) else $current-uri,
        'id': if (regex-group(3) ne '') then regex-group(3) else
regex-group(2)}"/>
    </xsl:matching-substring>
  </xsl:analyze-string>
</xsl:variable>

(I could have simplified these with predicate filtering and [1], but I was
going for clarity of intent instead of brevity.)

This seemed like a nice way to store capture group results by name in a way
that survives beyond the scope of <xsl:analyze-string>. Does anyone else have
another favorite way of saving <xsl:analyze-string> capture group values?


  *   Chris

-----
Chris Papademetrious
Tech Writer, Implementation Group
(610) 628-9718 home office
(570) 460-6078 cell

Current Thread