I am trying to convert QTI standard xml for Multiple choice question type to XHTML file using XSLT. I am finding difficulties in removing first 'p' tag from the 'simpleChoice' tag value.
Following is the QTI which i am trying to covert to XHTML
<?xml version="1.0" encoding="utf-8"?>
<assessmentItem xsi:schemaLocation="http://www.imsglobal.org/xsd/imsqti_v2p1 http://www.imsglobal.org/xsd/imsqti_v2p1.xsd" identifier="choice" title="Item Title will come here" adaptive="false" timeDependent="false" xmlns="http://www.imsglobal.org/xsd/imsqti_v2p1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<responseDeclaration identifier="RESPONSE" cardinality="single" baseType="identifier">
<correctResponse>
<value>ChoiceA</value>
</correctResponse>
</responseDeclaration>
<outcomeDeclaration identifier="SCORE" cardinality="single" baseType="integer">
<defaultValue>
<value>0</value>
</defaultValue>
</outcomeDeclaration>
<itemBody>
<div id="item">
<div id="instruction">Select the correct options</div>
<choiceInteraction responseIdentifier="RESPONSE" shuffle="false" maxChoices="1">
<prompt>
<div id="stem">
<p>Question will appear here</p>
</div>
</prompt>
<simpleChoice identifier="ChoiceA"><p> answer's first P tag</p> <p> answer's second P tag</p> <p> answer's third P tag</p> <p> answer's forth P tag</p> and text without p tag</simpleChoice>
<simpleChoice identifier="ChoiceB"><p> answer's first P tag</p> <p> answer's second P tag</p> <p> answer's third P tag</p> <p> answer's forth P tag</p> and text without p tag</simpleChoice>
<simpleChoice identifier="ChoiceC"><p> answer's first P tag</p> <p> answer's second P tag</p> <p> answer's third P tag</p> <p> answer's forth P tag</p> and text without p tag</simpleChoice>
<simpleChoice identifier="ChoiceD"><p> answer's first P tag</p> <p> answer's second P tag</p> <p> answer's third P tag</p> <p> answer's forth P tag</p> and text without p tag</simpleChoice>
<simpleChoice identifier="ChoiceE"><p> answer's first P tag</p> <p> answer's second P tag</p> <p> answer's third P tag</p> <p> answer's forth P tag</p> and text without p tag</simpleChoice>
</choiceInteraction>
</div>
</itemBody>
<responseProcessing template="http://www.imsglobal.org/question/qti_v2p1/rptemplates/match_correct" />
</assessmentItem>
I am looking at the following output for the options
<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
</head>
<body>
<div id="option1">
<label>A.</label>
<div class="optionContent">answer's first P tag<p> answer's second P tag</p> <p> answer's third P tag</p> <p> answer's forth P tag</p> and text without p tag</div>
</div>
<div id="option2">
<label>B.</label>
<div class="optionContent">answer's first P tag<p> answer's second P tag</p> <p> answer's third P tag</p> <p> answer's forth P tag</p> and text without p tag</div>
</div>
<div id="option3">
<label>C.</label>
<div class="optionContent">answer's first P tag<p> answer's second P tag</p> <p> answer's third P tag</p> <p> answer's forth P tag</p> and text without p tag</div>
</div>
<div id="option4">
<label>D.</label>
<div class="optionContent">answer's first P tag<p> answer's second P tag</p> <p> answer's third P tag</p> <p> answer's forth P tag</p> and text without p tag</div>
</div>
<div id="option5">
<label>E.</label>
<div class="optionContent">answer's first P tag<p> answer's second P tag</p> <p> answer's third P tag</p> <p> answer's forth P tag</p> and text without p tag</div>
</div>
</body>
</html>
The desire output i need is to remove first 'p' tag from the 'simpleChoice' tag.
I had tried doing that using following styles
<xsl:for-each select="//simpleChoice[$vCurrentIndex]/*">
<xsl:choose>
<xsl:when test="local-name() = 'p' and position() = 1">
<xsl:apply-templates select="node()|@*" mode="children" />
</xsl:when>
<xsl:otherwise>
<xsl:element name="{local-name()}">
<xsl:apply-templates select="node()|@*" mode="children" />
</xsl:element>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
After doing this i am getting following output. The output is not considering any values which are not within the P tag. Getting output for three P tags only.
<div class="optionContent">answer's second P tag<p> answer's third P tag</p> <p> answer's forth P tag</p></div>
Your help will really help me. Thanks in advance
Your approach to XSLT is wrong. Remove all the <xsl:for-each> in your entire stylesheet. You don't need them and should not use them. They indicate that you think procedurally and XSLT is not a procedural language.
This task is very simple if you use template matching instead of for-each. Also use proper namespace declarations in your XSL instead of using local-name() everywhere.
<xsl:stylesheet
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:qti="http://www.imsglobal.org/xsd/imsqti_v2p1"
exclude-result-prefixes="qti"
>
<xsl:output indent="yes" />
<xsl:template match="/*">
<root>
<xsl:apply-templates select="//qti:simpleChoice" />
</root>
</xsl:template>
<!-- identity template: this is the base of the entire process -->
<xsl:template match="node() | @*">
<xsl:copy>
<xsl:apply-templates select="node() | @*" />
</xsl:copy>
</xsl:template>
<!-- helper: elements in the qti namespace output their local name -->
<xsl:template match="qti:*">
<xsl:element name="{local-name()}">
<xsl:apply-templates select="node() | @*" />
</xsl:element>
</xsl:template>
<xsl:template match="qti:simpleChoice">
<div id="option{position()}">
<label>
<xsl:value-of select="concat(substring(@identifier, 7), '.')" />
</label>
<div class="optionContent">
<xsl:apply-templates />
</div>
</div>
</xsl:template>
<!-- the first p in a simpleChoice will just output its contents -->
<xsl:template match="qti:simpleChoice/qti:p[1]">
<xsl:apply-templates />
</xsl:template>
</xsl:stylesheet>
Output (see http://www.xmlplayground.com/IiKDkY)
<root>
<div id="option1">
<label>A.</label>
<div class="optionContent"> answer's first P tag <p> answer's second P tag</p> <p> answer's third P tag</p> <p> answer's forth P tag</p> and text without p tag</div>
</div>
<div id="option2">
<label>B.</label>
<div class="optionContent"> answer's first P tag <p> answer's second P tag</p> <p> answer's third P tag</p> <p> answer's forth P tag</p> and text without p tag</div>
</div>
<div id="option3">
<label>C.</label>
<div class="optionContent"> answer's first P tag <p> answer's second P tag</p> <p> answer's third P tag</p> <p> answer's forth P tag</p> and text without p tag</div>
</div>
<div id="option4">
<label>D.</label>
<div class="optionContent"> answer's first P tag <p> answer's second P tag</p> <p> answer's third P tag</p> <p> answer's forth P tag</p> and text without p tag</div>
</div>
<div id="option5">
<label>E.</label>
<div class="optionContent"> answer's first P tag <p> answer's second P tag</p> <p> answer's third P tag</p> <p> answer's forth P tag</p> and text without p tag</div>
</div>
</root>
The desire output i need is to remove first 'p' tag from the 'simpleChoice' tag.
I hope I understood your problem right - you want to show first P like a DIV or like a SPAN without any marging and etc., right?
Then I think the better way is to use content of <simpleChoice>...</simpleChoice> as is. But in your CSS file for <div class="optionContent"> to apply an additional style for first P tag. Something like this:
.optionContent > p
{
display: inline;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With