0

I need to rearrange HTML content using XSLT but I'm having trouble figuring out how.

First I need to add this new li:

<li class="ktp-question-set-meta">
                <section property="ktp:metadata" class="ktp-meta">
                    <span property="atom:content-item-name" class="ktp-meta" data-value="lsac810323"></span>
                </section>
                <section property="ktp:tags" class="ktp-meta">
                    <span class="ktp-meta" property="ktp:questionSetType">shared-stimulus</span>
                </section>
            </li>

The data-value="lsac810323 needs to be pulled from the <section class="ktp-question-meta"> in the the original HTML.

  1. The Stimulus section needs to be moved up and changed from <section> to an <li>

  2. the original <section class="ktp-question-meta"> need to show but the data value need to change from data-value="lsac810323" to data-value="lsac810323.01"

After that the <section class="ktp-question-stem">, <ol class="ktp-answer-set">, and <section property="ktp:explanation" typeof="ktp:Explanation" class="ktp-explanation"> remains the same.

This is my original HTML:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" designation="" enumeration="">
    <head>
        <meta charset="utf-8" />
        <link type="text/css" rel="stylesheet" title="default" href="../../assets/css/main.css" />
        <title>lsac820401</title>
    </head>
    <body>
        <ol class="ktp-question-set">
            <li typeof="ktp:Question" property="ktp:question" class="ktp-question">
                
                <section class="ktp-question-meta">
                    <section property="ktp:metadata" class="ktp-meta"><span property="atom:content-item-name" class="ktp-meta" data-value="lsac820401"></span></section>
                    <section property="ktp:tags" class="ktp-meta">
                        <span property="ktp:interactionType" class="ktp-meta">single-select</span>
                        <span property="ktp:questionType" class="ktp-meta">Point at Issue</span>
                        <span property="ktp:difficulty" class="ktp-meta">★</span>  
                    </section>
                </section>
                
                <section property="ktp:stimulus" typeof="ktp:Stimulus" class="ktp-stimulus">   
                    <p>stimulus content</p>    
                </section>
                
                <section class="ktp-question-stem">  
                    <p>stem content</p>   
                </section>
                
                <ol class="ktp-answer-set">   
                    <li property="ktp:answer" typeof="ktp:Answer">Answer Choice 1</li>
                    <li property="ktp:answer" typeof="ktp:AnswerCorrect">Answer Choice 2</li>
                    <li property="ktp:answer" typeof="ktp:Answer">Answer Choice 3</li>
                    <li property="ktp:answer" typeof="ktp:Answer">Answer Choice 4</li>
                    <li property="ktp:answer" typeof="ktp:Answer">Answer Choice 5</li>   
                </ol>
                
                <section property="ktp:explanation" typeof="ktp:Explanation" class="ktp-explanation">
                    <section property="ktp:explanation-section" typeof="ktp:feedback" data-title="Feedback" class="ktp-explanation-section">
                        <p>Explanation content</p>
                    </section>
                </section>  
            </li>
        </ol>
    </body>
</html>

And this is the rearranged output I need to get to:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" enumeration="" designation="">
    <head>
        <meta charset="utf-8" />
        <link href="../../assets/css/main.css" title="default" rel="stylesheet" type="text/css" />
        <title>lsac810323</title>
    </head>
    <body>
        <ol property="ktp:questionSet" typeof="ktp:QuestionSet" class="ktp-question-set">
            <li class="ktp-question-set-meta">
                <section property="ktp:metadata" class="ktp-meta">
                    <span property="atom:content-item-name" class="ktp-meta" data-value="lsac810323"></span>
                </section>
                <section property="ktp:tags" class="ktp-meta">
                    <span class="ktp-meta" property="ktp:questionSetType">shared-stimulus</span>
                </section>
            </li>
            <li class="ktp-stimulus" typeof="ktp:Stimulus" property="ktp:stimulus">
                <p>stimulus content</p>
                <p class="place-top atom-exclude">Stimulus End: Place content above this line</p>
            </li>
            <li class="ktp-question" typeof="ktp:Question" property="ktp:question">
                <section class="ktp-question-meta">
                    <section property="ktp:metadata" class="ktp-meta">
                        <span property="atom:content-item-name" class="ktp-meta" data-value="lsac810323.01"></span>
                    </section>
                    <section property="ktp:tags" class="ktp-meta">
                        <span class="ktp-meta" property="ktp:interactionType">single-select</span>
                        <span class="ktp-meta" property="ktp:questionType"><span class="glossterm">Flaw</span></span>
                        <span class="ktp-meta" property="ktp:difficulty">Check your online resources.</span>
                    </section>
                </section>
                <section class="ktp-question-stem">
                    <p>stem content</p>
                </section>
                <ol class="ktp-answer-set">
                    <li property="ktp:answer" typeof="ktp:Answer">Answer Choice 1</li>
                    <li property="ktp:answer" typeof="ktp:AnswerCorrect">Answer Choice 2</li>
                    <li property="ktp:answer" typeof="ktp:Answer">Answer Choice 3</li>
                    <li property="ktp:answer" typeof="ktp:Answer">Answer Choice 4</li>
                    <li property="ktp:answer" typeof="ktp:Answer">Answer Choice 5</li>
                </ol>
                <section property="ktp:explanation" typeof="ktp:Explanation" class="ktp-explanation">
                    <section property="ktp:explanation-section" typeof="ktp:feedback" data-title="Feedback" class="ktp-explanation-section">
                        <p>Explanation content</p>
                    </section>
                </section>
            </li>
        </ol>
    </body>
</html>

This is the XSLT I have so far. I have the structure pulling in correctly and the original content placed in its correct new location but it's not bringing over the

tags or

  • tags, etc. Please see the section labeled .
    <?xml version="1.0" encoding="UTF-8"?>
    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
        xmlns:xs="http://www.w3.org/2001/XMLSchema"
        xmlns:math="http://exslt.org/math"
        xmlns:xd="http://www.oxygenxml.com/ns/doc/xsl"
        xmlns:xhtml="http://www.w3.org/1999/xhtml"
        xmlns:mml="http://www.w3.org/1998/Math/MathML"
        xmlns="http://www.w3.org/1999/xhtml"
        exclude-result-prefixes="xs math xd xhtml mml"
        version="3.0">
        
        <xsl:output encoding="UTF-8" include-content-type="no" indent="no" method="xhtml" omit-xml-declaration="yes"/>
        
        
        <!-- attributes, commments, processing instructions, text: copy as is -->
        <xsl:template match="@*|comment()|processing-instruction()|text()">
            <xsl:copy-of select="."/>
        </xsl:template>
        
        <!-- elements: create a new element with the same name, but no namespace -->
        <xsl:template match="*">
            <xsl:param name="content-item-name"/>
            <xsl:element name="{local-name()}">
                <xsl:apply-templates select="@*|node()">
                    <xsl:with-param name="content-item-name" select="$content-item-name"/>
                </xsl:apply-templates>
            </xsl:element>
        </xsl:template>
        
        <!-- process root -->
        <xsl:template match="xhtml:html">
            <xsl:text disable-output-escaping="yes">&lt;!DOCTYPE html&gt;</xsl:text>
            <xsl:sequence select="'&#x0a;'"/>
            <html>
                <xsl:apply-templates select="@* | node()"/>
            </html>
        </xsl:template>
        
        <!-- process item, pass content item name variable -->
        <xsl:template match="xhtml:li[@property='ktp:question']">
            <li>
                <xsl:apply-templates select="@*|node()">
                    <xsl:with-param name="content-item-name" select="descendant::xhtml:span[@property='atom:content-item-name']/@data-value"/>
                </xsl:apply-templates>
            </li>
        </xsl:template>
        
        <!-- branching point for any interaction type-based updates -->
        <xsl:template match="xhtml:li[@property='ktp:question']">
            <li>
                <xsl:apply-templates select="@*|node()">
                    <xsl:with-param name="interactionType" select="//xhtml:span[@property='ktp:interactionType']"/>
                </xsl:apply-templates>
            </li>
        </xsl:template>
        
        
            
        
        
        
        <!-- Change content -->
        <xsl:template match="xhtml:ol[@class='ktp-question-set']">
        
            <xsl:variable name="content-item-name" select="xhtml:span[@property='atom:content-item-name']/@data-value"/>
            <xsl:variable name="feedbackPara"
                select="xhtml:section[@property = 'ktp:stimulus']"/>
                <ol property="ktp:questionSet" typeof="ktp:QuestionSet" class="ktp-question-set">
                    <li class="ktp-question-set-meta">
                        <section property="ktp:metadata" class="ktp-meta">
                            <span property="atom:content-item-name" class="ktp-meta" data-value="{$content-item-name}"/>
                        </section>
                        <section property="ktp:tags" class="ktp-meta">
                            <span class="ktp-meta" property="ktp:questionSetType">shared-stimulus</span>
                        </section>
                    </li>
                    <li class="ktp-stimulus" typeof="ktp:Stimulus" property="ktp:stimulus">  
                        
                            
                            <xsl:apply-templates
                                select="descendant::xhtml:section[@property = 'ktp:stimulus']" mode="key"/>
                        
                        <p class="place-top atom-exclude">Stimulus End: Place content above this line</p>
                    </li>
                    <li class="ktp-question" typeof="ktp:Question" property="ktp:question">
                        <section class="ktp-question-meta">
                            <xsl:apply-templates
                                select="descendant::xhtml:section[@class = 'ktp-question-meta']" mode="key"/>
                            
                        </section>
                        <section class="ktp-question-stem">
                            <xsl:apply-templates
                                select="descendant::xhtml:section[@class = 'ktp-question-stem']" mode="key"/>
                            
                        </section>
                        <ol class="ktp-answer-set">
                            <xsl:apply-templates
                                select="descendant::xhtml:ol[@class = 'ktp-answer-set']" mode="key"/>
                            
                        </ol>
                        <section property="ktp:explanation" typeof="ktp:Explanation" class="ktp-explanation">
                            <xsl:apply-templates
                                select="descendant::xhtml:section[@property = 'ktp:explanation']" mode="key"/>
                            
                        </section>
                    </li>                
                </ol>   
        </xsl:template>
        
        
        
        
    
        <!-- process mathml -->
        <xsl:template match="mml:*">
            <xsl:copy>
                <xsl:apply-templates select="@*|node()"/>
            </xsl:copy>
        </xsl:template>
        
        <!-- generate data-uuid -->
        <xsl:template name="assignID">
            <xsl:param name="partial"/>
            <xsl:param name="count" select="string-length(partial)"/>
            
            <xsl:variable name="character">abcdef0123456789</xsl:variable>
            <xsl:variable name="characterLength" select="string-length($character)"/>
            <xsl:variable name="position" select="floor(math:random() * 16) + 1"/>
            
            <xsl:choose>
                <xsl:when test="$count &lt; 32">
                    <xsl:call-template name="assignID">
                        <xsl:with-param name="count" select="$count + 1"/>
                        <xsl:with-param name="partial">
                            <xsl:value-of select="$partial"/>
                            <xsl:value-of select="substring($character,$position,1)"/>
                        </xsl:with-param>
                    </xsl:call-template>
                </xsl:when>
                <xsl:when test="$count = 32">
                    <xsl:value-of select="$partial"/>
                </xsl:when>
            </xsl:choose>
        </xsl:template>
        
    </xsl:stylesheet>
    

    Thanks in advance for any help!

  • mjwolff1
    • 39
    • 7
    • Why don't you post your attempt so we can fix it, instead of having to write your code for you from scratch. – michael.hor257k Jan 22 '21 at 14:42
    • I added my attempt at the XSLT script but it's not working very well at all as my XSLT knowledge is very limited. – mjwolff1 Jan 22 '21 at 14:49
    • In case you did not know, usually HTML is not as rules compliant like XML to be usable in XSLT. Fortunately, your posted HTML is well-formed. See [Is HTML5 valid XML?](https://stackoverflow.com/q/5558502/1422451) – Parfait Jan 22 '21 at 15:09
    • I suggest you reduce your example to the minimum required to demonstrate the problem - and reduce the problem to a single one instead of three. – michael.hor257k Jan 22 '21 at 21:28

    1 Answers1

    0
    <?xml version="1.0" encoding="UTF-8"?>
    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
        xmlns:xs="http://www.w3.org/2001/XMLSchema"
        xmlns:math="http://exslt.org/math"
        xmlns:xd="http://www.oxygenxml.com/ns/doc/xsl"
        xmlns:xhtml="http://www.w3.org/1999/xhtml"
        xmlns:mml="http://www.w3.org/1998/Math/MathML"
        xmlns="http://www.w3.org/1999/xhtml"
        exclude-result-prefixes="xs math xd xhtml mml"
        version="3.0">
        
        <xsl:output encoding="UTF-8" include-content-type="no" indent="no" method="xhtml" omit-xml-declaration="yes"/>
        
        
        <!-- attributes, commments, processing instructions, text: copy as is -->
        <xsl:template match="@*|comment()|processing-instruction()|text()">
            <xsl:copy-of select="."/>
        </xsl:template>
        
        <!-- elements: create a new element with the same name, but no namespace -->
        <xsl:template match="*">
            <xsl:param name="content-item-name"/>
            <xsl:element name="{local-name()}">
                <xsl:apply-templates select="@*|node()">
                    <xsl:with-param name="content-item-name" select="$content-item-name"/>
                </xsl:apply-templates>
            </xsl:element>
        </xsl:template>
        
        <!-- process root -->
        <xsl:template match="xhtml:html">
            <xsl:text disable-output-escaping="yes">&lt;!DOCTYPE html&gt;</xsl:text>
            <xsl:sequence select="'&#x0a;'"/>
            <html>
                <xsl:apply-templates select="@* | node()"/>
            </html>
        </xsl:template>
        
        <!-- process item, pass content item name variable -->
        <xsl:template match="xhtml:li[@property='ktp:question']">
            <li>
                <xsl:apply-templates select="@*|node()">
                    <xsl:with-param name="content-item-name" select="descendant::xhtml:span[@property='atom:content-item-name']/@data-value"/>
                </xsl:apply-templates>
            </li>
        </xsl:template>
        
        <!-- branching point for any interaction type-based updates -->
        <xsl:template match="xhtml:li[@property='ktp:question']">
            <li>
                <xsl:apply-templates select="@*|node()">
                    <xsl:with-param name="interactionType" select="//xhtml:span[@property='ktp:interactionType']"/>
                </xsl:apply-templates>
            </li>
        </xsl:template>
        
        
            
        
        
        
        <!-- Change content -->
        <xsl:template match="xhtml:ol[@class='ktp-question-set']">
        
            <xsl:variable name="content-item-name" select="xhtml:span[@property='atom:content-item-name']/@data-value"/>
            <xsl:variable name="feedbackPara"
                select="xhtml:section[@property = 'ktp:stimulus']"/>
                <ol property="ktp:questionSet" typeof="ktp:QuestionSet" class="ktp-question-set">
                    <li class="ktp-question-set-meta">
                        <section property="ktp:metadata" class="ktp-meta">
                            <xsl:apply-templates
                                select="descendant::xhtml:span[@property = 'atom:content-item-name']"/>
                        </section>
                        <section property="ktp:tags" class="ktp-meta">
                            <span class="ktp-meta" property="ktp:questionSetType">shared-stimulus</span>
                        </section>
                    </li>
                    <li class="ktp-stimulus" typeof="ktp:Stimulus" property="ktp:stimulus">  
                                               
                            <xsl:apply-templates 
                                select="descendant::xhtml:section[@property = 'ktp:stimulus']"/>
                        
                        <p class="place-top atom-exclude">Stimulus End: Place content above this line</p>
                    </li>
                    <li class="ktp-question" typeof="ktp:Question" property="ktp:question">
                        
                        <section class="ktp-question-meta">
                            <section property="ktp:metadata" class="ktp-meta">   
                        <xsl:apply-templates
                            select="descendant::xhtml:span[@property = 'atom:content-item-name']"/>.01
                            </section>
                            <xsl:apply-templates
                                select="descendant::xhtml:section[@property = 'ktp:tags']"/>
                        </section>   
                                           
                            <xsl:apply-templates
                                select="descendant::xhtml:section[@class = 'ktp-question-stem']"/>
             
                            <xsl:apply-templates
                                select="descendant::xhtml:ol[@class = 'ktp-answer-set']"/>
                
                            <xsl:apply-templates
                                select="descendant::xhtml:section[@property = 'ktp:explanation']"/>
               
                    </li>                
                </ol>   
        </xsl:template>
        
        
        
        
    
        <!-- process mathml -->
        <xsl:template match="mml:*">
            <xsl:copy>
                <xsl:apply-templates select="@*|node()"/>
            </xsl:copy>
        </xsl:template>
        
        <!-- generate data-uuid -->
        <xsl:template name="assignID">
            <xsl:param name="partial"/>
            <xsl:param name="count" select="string-length(partial)"/>
            
            <xsl:variable name="character">abcdef0123456789</xsl:variable>
            <xsl:variable name="characterLength" select="string-length($character)"/>
            <xsl:variable name="position" select="floor(math:random() * 16) + 1"/>
            
            <xsl:choose>
                <xsl:when test="$count &lt; 32">
                    <xsl:call-template name="assignID">
                        <xsl:with-param name="count" select="$count + 1"/>
                        <xsl:with-param name="partial">
                            <xsl:value-of select="$partial"/>
                            <xsl:value-of select="substring($character,$position,1)"/>
                        </xsl:with-param>
                    </xsl:call-template>
                </xsl:when>
                <xsl:when test="$count = 32">
                    <xsl:value-of select="$partial"/>
                </xsl:when>
            </xsl:choose>
        </xsl:template>
        
    </xsl:stylesheet>
    
    mjwolff1
    • 39
    • 7