Create an XML structure from attributes in a single node

I have the following XML source:

<element not-relevant="true" bold="true" superscript="true" subscript="false" text="stuff"/> 

In any order, I need to iterate over certain attributes (that is, only those associated with the HTML I created: bold / superscript / index, etc.), and where one of these attributes evaluates to β€œtrue”, output nested elements to get the following output:

 <strong> <sup> stuff </sup> </strong> 

I have a feeling that I need to use some kind of recursion, as it should (without an infinite loop, of course):

 <xsl:template match="element"> <xsl:call-template name="content"> <xsl:with-param name="text" select="@text"/> </xsl:call-template> </xsl:template> <xsl:template name="content"> <xsl:param name="text"/> <xsl:choose> <xsl:when test="@bold = 'true'"> <strong> <xsl:copy> <xsl:call-template name="content"> <xsl:with-param name="text" select="$text"/> </xsl:call-template> <xsl:copy> </strong> </xsl:when> <xsl:when test="@subscript = 'true'"> <sub> <xsl:copy> <xsl:call-template name="content"> <xsl:with-param name="text" select="$text"/> </xsl:call-template> <xsl:copy> </sub> </xsl:when> <xsl:when test="@superscript = 'true'"> <sup> <xsl:copy> <xsl:call-template name="content"> <xsl:with-param name="text" select="$text"/> </xsl:call-template> <xsl:copy> </sup> </xsl:when> <xsl:otherwise> <xsl:value-of select="$text" disable-output-escaping="yes"/> </xsl:otherwise> </xsl:choose> </xsl:template> 

Any ideas? I am looking for the purest XSLT 2.0 solution and appreciate the help.

Thanks,

+5
source share
1 answer

This is a good use case for <xsl:next-match/> :

 <xsl:template match="element" priority="1"> <xsl:value-of select="@text" /> </xsl:template> <xsl:template match="element[@superscript = 'true']" priority="2"> <sup><xsl:next-match/></sup> </xsl:template> <xsl:template match="element[@subscript = 'true']" priority="3"> <sub><xsl:next-match/></sub> </xsl:template> <xsl:template match="element[@bold = 'true']" priority="4"> <strong><xsl:next-match/></strong> </xsl:template> 

When you apply patterns to an element element , the match pattern with the highest priority is first run, and if this pattern uses next-match , it delegates the next priority, etc. Your element example in the question matches the first, second, and fourth patterns above, so the β€œbold” template that will delegate the β€œsuperscript” and finally the common element will be selected first, which will result in <strong><sup>stuff</sup></strong>

As you can see from this example, the priority numbers determine the nesting order - if the priorities of the second and fourth templates were canceled, instead you get <sup><strong>stuff</strong></sup> .

+6
source

Source: https://habr.com/ru/post/1203237/


All Articles