Is there an elegant way to add multiple HTML classes using XSLT?

Say I'm transforming a multiple-choice quiz from an arbitrary XML format to HTML. Each selection will be represented as an HTML <li> in the resulting document. For each choice, I want to add an HTML class from correct to <li> if that choice was the correct answer. Also, if this choice was chosen by the user, I want to add the submitted class to the <li> . Therefore, if the choice is correct as well as presented, the <li> must have a class of correct submitted .

As far as I know, attribute values โ€‹โ€‹separated from white space are not part of the XML data model and therefore cannot be directly created using XSLT. However, I have a feeling that there is a better way to do this than to clog the code with one condition for every possible combination of classes (which would be acceptable in this example, but cumbersome in more complex scenarios).

How can I solve this in an elegant way?

An example of the desired result:

 <p>Who trained Obi-Wan Kenobi?</p> <ul> <li>Mace Windu</li> <li class="correct submitted">Qui-Gon Jinn</li> <li>Ki-Adi-Mundi</li> <li>Yaddle</li> </ul> 
+6
html class xslt class-names
source share
3 answers

Firstly, there is nothing wrong with spaces in attribute values โ€‹โ€‹in XML: roughly speaking, normalizing an attribute value converts whitespace to spaces and folds adjacent spaces into a single space when the document is parsed, but the space is definitely resolved. EDIT: See below for more on this.

Matthew Wilson's approach does not include spaces between possible meanings, as you mentioned in your comments on it. However, his approach is fundamentally sound. The final piece of the puzzle is your dislike of redundant spaces: they can be eliminated using the normalize-space XPath function.

The following stylesheet combines all the bits - note that it does nothing with its source document, so for testing purposes you can run it against any XML document or even yourself to make sure that the result meets your requirements.

 <?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:variable name="foo0" select="false()"/> <xsl:variable name="bar0" select="true()"/> <xsl:variable name="foo1" select="true()"/> <xsl:variable name="bar1" select="false()"/> <xsl:variable name="foo2" select="true()"/> <xsl:variable name="bar2" select="true()"/> <xsl:template match="/"> <xsl:variable name="foobar0"> <xsl:if test="$foo0"> foo</xsl:if> <xsl:if test="$bar0"> bar</xsl:if> </xsl:variable> <xsl:variable name="foobar1"> <xsl:if test="$foo1"> foo</xsl:if> <xsl:if test="$bar1"> bar</xsl:if> </xsl:variable> <xsl:variable name="foobar2"> <xsl:if test="$foo2"> foo</xsl:if> <xsl:if test="$bar2"> bar</xsl:if> </xsl:variable> <li> <xsl:attribute name="class"> <xsl:value-of select="normalize-space($foobar0)"/> </xsl:attribute> </li> <li> <xsl:attribute name="class"> <xsl:value-of select="normalize-space($foobar1)"/> </xsl:attribute> </li> <li> <xsl:attribute name="class"> <xsl:value-of select="normalize-space($foobar2)"/> </xsl:attribute> </li> </xsl:template> </xsl:stylesheet> 

EDIT: In addition to the issue of spaces separating discrete components in an attribute value: XML Spec defines a number of possible valid constructs as attribute types , including IDREFS and NMTOKENS. The first case corresponds to Names , and the second case corresponds to NMTokens production; both of these settings are defined as containing several values โ€‹โ€‹of the corresponding type, limited by spaces. Thus, lists of values โ€‹โ€‹separated by spaces, as the value of a single attribute, are an integral component of the XML dataset.

+9
source share

On top of my head, you can create a list separated by spaces, with something like:

 <li> <xsl:attribute name="class"> <xsl:if cond="...">correct</xsl:if> <xsl:if cond="...">submitted</xsl:if> </xsl:attribute> </li> 
+5
source share

As far as I know, space-separated attribute values โ€‹โ€‹are not part of the XML data model and therefore cannot be directly created using XSLT

If you are not converting to XML (which HTML is missing, XHTML is), you should not worry about the correctness of the XSLT XML output. It can be anything and does not need to conform to XML!

+1
source share

All Articles