xsl-list
[Top] [All Lists]

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

2022-05-23 08:41:10
On 23/05/2022 12:08, Chris Papademetrious christopher(_dot_)papademetrious(_at_)synopsys(_dot_)com 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'))]>
        <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>
        <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(_at_)saxonica(_dot_)com
--~----------------------------------------------------------------
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
EasyUnsubscribe: http://lists.mulberrytech.com/unsub/xsl-list/1167547
or by email: xsl-list-unsub(_at_)lists(_dot_)mulberrytech(_dot_)com
--~--

<Prev in Thread] Current Thread [Next in Thread>