Re: the "~" operator (was Re: [xsl] Add id to next element)

Subject: Re: the "~" operator (was Re: [xsl] Add id to next element)
From: "John Lumley john@xxxxxxxxxxxx" <xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx>
Date: Mon, 23 May 2022 13:40:58 -0000
On 23/05/2022 12:08, Chris Papademetrious christopher.papademetrious@xxxxxxxxxxxx wrote:
<body>
   <p/>
   <p outputclass="foo bar"/>
   <p outputclass="foo BAZ"/>
</body>
<xsl:template match="p">
     <xsl:copy>
       <xsl:attribute name="outputclass"
         select="tokenize(@outputclass, '\s+')
           => mine:add_value('BAZ')
           => distinct-values()
           => string-join(' ')"/>
       <xsl:apply-templates select="node()|(@* except @outputclass)"/>
     </xsl:copy>
   </xsl:template>

With XSLT/XPath 3 there is a far more elegant and efficient method. Just add the following template:


   <xsl:template match="p/@outputclass[not(contains-token(.,'BAZ'))]>
    B B B  <xsl:attribute name="{name(.)}" select=". || ' BAZ'"/>
   </xsl:template>

(see https://www.w3.org/TR/xpath-functions-31/#func-contains-token) and your template for p can merely be:

   <xsl:template match="p">
      <xsl:copy>
    B B B  <xsl:apply-templates select="@*,node()" mode="#current"/>
      </xsl:copy>
   </xsl:template>

and if you're using

<xsl:mode on-no-match="shallow-copy"/>

you won't even need the second template.

--
*John Lumley* MA PhD CEng FIEE
john@xxxxxxxxxxxx

Current Thread