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
--~--