Subject: Re: [xsl] Add element at the end of a variable group of elements From: "Liam R. E. Quin liam@xxxxxxxxxxxxxxxx" <xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx> Date: Wed, 3 Mar 2021 05:25:33 -0000 |
On Wed, 2021-03-03 at 00:01 +0000, Charles O'Connor coconnor@xxxxxxxxxxxx wrote: > Hi all, > > Using XSLT 2.0, I'd like to add an element at the end of a group of > elements that may vary whether they exist. First, some XSLT 3 approaches... The following works fine: <?xml version="1.0" encoding="UTF-8" ?> <xsl:stylesheet version="3.0" expand-text="yes" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" exclude-result-prefixes="#all" > <xsl:output indent="yes" /> <!--* enable identity transform: *--> <xsl:mode on-no-match="shallow-copy" /> <xsl:template match="(foo|bar|mercury|venus)[last()]"> <xsl:next-match/> <!--* built-in template copies the element *--> <moon>Now with more craters!</moon> </xsl:template> </xsl:stylesheet> So maybe that's a reason to upgrade :) You could also define two substitution groups and use predicate patterns to match them. You could even put (foo|bar|mergcury|venus)" in a variable, as Wendell did, and use that in a predicate pattern, e.g.: <xsl:variable name="first-group" as="xs:string*" select='("foo", "bar", "mercury", "venus")' /> <xsl:template match=".[ name() = $first-group ][ not(following-sibling::*[1]/name() = $first-group) ]"> <xsl:next-match/> <!--* built-in template copies the element *--> <moon>Now with more craters!</moon> </xsl:template> However, this is getting obscure, may be slow, and is not the XSLT 2 you asked for. You may find this works: <xsl:template match="*[name() = ('foo', 'bar', 'mercury', 'venus')][last()]"> So here is a working XSLT 2 version: <?xml version="1.0" encoding="UTF-8" ?> <xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" exclude-result-prefixes="#all" > <xsl:output indent="yes" /> <xsl:template match="*"> <xsl:copy> <xsl:apply-templates select="@*|node()" /> </xsl:copy> </xsl:template> <xsl:variable name="first-group" as="xs:string*" select="('foo', 'bar', 'mercury', 'venus')" /> <xsl:template match="*[name() = $first-group][last()]" priority="10"> <xsl:next-match/> <!--* built-in template copies the element *--> <moon>Now with more craters!</moon> </xsl:template> </xsl:stylesheet> Liam -- Liam Quin,B https://www.delightfulcomputing.com/ Available for XML/Document/Information Architecture/XSLT/ XSL/XQuery/Web/Text Processing/A11Y training, work & consulting. Barefoot Web-slave, antique illustrations: B http://www.fromoldbooks.org
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
Re: [xsl] Add element at the end of, Wendell Piez wapiez@ | Thread | [xsl] Re: Add element at the end of, Michele R Combs mrro |
Re: [xsl] Re: Add element at the en, G. Ken Holman g.ken. | Date | [xsl] Re: Add element at the end of, Michele R Combs mrro |
Month |