我有一个XML文档,其中列出了4个可能的答案,然后列出了多选/多答案问题的正确答案。在执行转换时,我需要列出正确的答案,并将一个不正确的答案拉入其自己的元素中。如何比较"列表"解析出一个不正确的输出答案?
SOURCE XML:
<assessment>
<div class="question" id="s1">
<div class="prompt" id="s2">
<p id="s3">SELECT ALL THAT APPLY. Which of the following colors do I like?</p>
</div>
<div class="answer" id="s4">
<div class="choice" id="s5">
<div class="list" id="s6">
<ul class="no-marker">
<li id="s7">Red</li>
<li id="s8">Blue</li>
<li id="s9">Green</li>
<li id="s10">Orange</li>
</ul>
</div>
</div>
</div>
<div class="response-processing" id="s11">
<div class="condition" id="s12">
<div class="correct" id="s13">
<div class="response" id="s14">
<p><a class="answer-ref" id="s15" href="#s5">s7</a></p>
<p><a class="answer-ref" id="s16" href="#s5">s9</a></p>
<p><a class="answer-ref" id="s17" href="#s5">s10</a></p>
</div>
</div>
</div>
</div>
</div>
</assessment>
使用XSLT:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs"
version="2.0">
<xsl:key name="answers" match="div[@class='response-processing']/div[@class='condition']/div[@class='correct']/div[@class='response']/p/a[@class='answer-ref']" use="text()"/>
<xsl:template match="*">
<xsl:call-template name="createItem"/>
</xsl:template>
<xsl:template name="createItem">
<xsl:for-each select="div[@class='question']">
<xsl:element name="item">
<xsl:attribute name="ident" select="@id"/>
<xsl:call-template name="createPresentation"/>
<xsl:call-template name="createReprocessing"/>
</xsl:element>
</xsl:for-each>
</xsl:template>
<xsl:template name="createPresentation">
<xsl:element name="presentation">
<xsl:element name="flow">
<xsl:attribute name="class" select="'Block'"/>
<xsl:element name="flow">
<xsl:attribute name="class" select="'QUESTION_BLOCK'"/>
<xsl:element name="flow">
<xsl:attribute name="class" select="'FORMATTED_TEXT_BLOCK'"/>
<xsl:element name="material">
<xsl:element name="mat_extension">
<xsl:element name="mat_formattedtext">
<xsl:attribute name="type" select="'SMART_TEXT'"/>
<xsl:value-of select="div[@class='prompt']/p"/>
</xsl:element>
</xsl:element>
</xsl:element>
</xsl:element>
</xsl:element>
<xsl:element name="flow">
<xsl:attribute name="class" select="'RESPONSE_BLOCK'"/>
<xsl:element name="response_lid">
<xsl:attribute name="ident" select="div[@class='answer']/div[@class='choice']/@id"/>
<xsl:element name="render_choice">
<xsl:apply-templates select="div[@class='answer']/div[@class='choice']"/>
</xsl:element>
</xsl:element>
</xsl:element>
</xsl:element>
</xsl:element>
</xsl:template>
<xsl:template name="createReprocessing">
<xsl:element name="respcondition">
<xsl:attribute name="title" select="'correct'"/>
<xsl:element name="conditionvar">
<xsl:choose>
<xsl:when test="count(div[@class='response-processing']/div[@class='condition']/div[@class='correct']/div[@class='response']/p/a[@class='answer-ref']) <= 1">
<!--Use for-each to output if there are multiple answers-->
<xsl:for-each select="div[@class='response-processing']/div[@class='condition']/div[@class='correct']/div[@class='response']/p/a[@class='answer-ref']">
<xsl:element name="varequal">
<xsl:attribute name="respident" select="@href"/>
<xsl:value-of select="."/>
</xsl:element>
</xsl:for-each>
</xsl:when>
<xsl:when test="count(div[@class='response-processing']/div[@class='condition']/div[@class='correct']/div[@class='response']/p/a[@class='answer-ref']) > 1">
<xsl:element name="and">
<xsl:if test="*[not(key('answers', ./div[@class='answer']/div[@class='choice']/div[@class='list']/ul/li/@id))]">
<xsl:for-each select=".">
<xsl:element name="not">
<xsl:element name="varequal">
<xsl:attribute name="respident" select="./@href"/>
<xsl:value-of select="key('answers',.)"/>
</xsl:element>
</xsl:element>
</xsl:for-each>
</xsl:if>
<!--Use for-each to output if there are multiple answers-->
<xsl:for-each select="div[@class='response-processing']/div[@class='condition']/div[@class='correct']/div[@class='response']/p/a[@class='answer-ref']">
<xsl:element name="varequal">
<xsl:attribute name="respident" select="@href"/>
<xsl:value-of select="."/>
</xsl:element>
</xsl:for-each>
</xsl:element>
</xsl:when>
</xsl:choose>
</xsl:element>
</xsl:element>
</xsl:template>
<xsl:template match="div[@class='choice']">
<xsl:for-each select="div[@class='list']//li">
<xsl:element name="flow_label">
<xsl:attribute name="class" select="'Block'"/>
<xsl:element name="response_label">
<xsl:attribute name="ident" select="@id"/>
<xsl:if test="@class='no-shuffle'">
<xsl:attribute name="rshuffle" select="'No'"/>
</xsl:if>
<xsl:element name="flow_mat">
<xsl:attribute name="class" select="'FORMATTED_TEXT_BLOCK'"/>
<xsl:element name="material">
<xsl:element name="mat_extension">
<xsl:element name="mat_formattedtext">
<xsl:attribute name="type" select="'SMART_TEXT'"/>
<xsl:apply-templates/>
</xsl:element>
</xsl:element>
</xsl:element>
</xsl:element>
</xsl:element>
</xsl:element>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
XML OUTPUT(注意元素中所需输出的注释):
<item ident="s1">
<presentation>
<flow class="Block">
<flow class="QUESTION_BLOCK">
<flow class="FORMATTED_TEXT_BLOCK">
<material>
<mat_extension>
<mat_formattedtext type="SMART_TEXT">SELECT ALL THAT APPLY. Which of the
following colors do I like?</mat_formattedtext>
</mat_extension>
</material>
</flow>
</flow>
<flow class="RESPONSE_BLOCK">
<response_lid ident="s5">
<render_choice>
<flow_label class="Block">
<response_label ident="s7">
<flow_mat class="FORMATTED_TEXT_BLOCK">
<material>
<mat_extension>
<mat_formattedtext type="SMART_TEXT"
>Red</mat_formattedtext>
</mat_extension>
</material>
</flow_mat>
</response_label>
</flow_label>
<flow_label class="Block">
<response_label ident="s8">
<flow_mat class="FORMATTED_TEXT_BLOCK">
<material>
<mat_extension>
<mat_formattedtext type="SMART_TEXT"
>Blue</mat_formattedtext>
</mat_extension>
</material>
</flow_mat>
</response_label>
</flow_label>
<flow_label class="Block">
<response_label ident="s9">
<flow_mat class="FORMATTED_TEXT_BLOCK">
<material>
<mat_extension>
<mat_formattedtext type="SMART_TEXT"
>Green</mat_formattedtext>
</mat_extension>
</material>
</flow_mat>
</response_label>
</flow_label>
<flow_label class="Block">
<response_label ident="s10">
<flow_mat class="FORMATTED_TEXT_BLOCK">
<material>
<mat_extension>
<mat_formattedtext type="SMART_TEXT"
>Orange</mat_formattedtext>
</mat_extension>
</material>
</flow_mat>
</response_label>
</flow_label>
</render_choice>
</response_lid>
</flow>
</flow>
</presentation>
<respcondition title="correct">
<conditionvar>
<and>
<not>
<!-- Instead of an empty varequal within <not> I want <varequal respident="#s5">s8</varequal> -->
<varequal respident=""/>
</not>
<varequal respident="#s5">s7</varequal>
<varequal respident="#s5">s9</varequal>
<varequal respident="#s5">s10</varequal>
</and>
</conditionvar>
</respcondition>
</item>
我认为 key()是要走的路,但我不确定如何让它发挥作用。提前谢谢。
答案 0 :(得分:1)
你的密钥(我会把它简化为
<xsl:key name="answers"
match="div[@class='response-processing']/div[@class='condition']/div[@class='correct']/div[@class='response']/p/a[@class='answer-ref']"
use="."/>
)
允许您检查答案li
是否有相应的响应,以便检查key
调用key('answers', @id)
是否提供空节点集或序列,然后您可以将答案视为:
<xsl:template match="div[@class = 'answer']//li[not(key('answers', @id))]">
<incorrect id="{@id}"></incorrect>
</xsl:template>