我正在学习XML / XSLT / XPATH并且有一些特定的方法,但希望通过删除重复代码来提高效率。
XML示例
<student>
<scores>
<score scoreID="1" weight="10" mandatory="false">7</score>
<score scoreID="2" weight="10" mandatory="false">9</score>
<score scoreID="3" weight="30" mandatory="true">13</score>
</scores>
</student>
<student>
<scores>
<score scoreID="1" weight="10" mandatory="false">8</score>
<score scoreID="2" weight="10" mandatory="false">4</score>
<score scoreID="3" weight="30" mandatory="true">25</score>
</scores>
</student>
所以基本上我有一些XSL检查
这是通过以下表达式完成的
XSL
<xsl:when test="sum(scores/score) > 25 and scores/score[@mandatory='True' and .div @weight < 0.5]">
除了我有很多学生和很多分数外,这一切都很好,因为我在每个分数下都写了重量和强制值,所以效率并不高。
我想要做的是声明另一个具有权重和强制属性的结构,然后用键将它们引用到每个分数。
所以我的XML更喜欢这样(基本上没有每个分数下的权重和强制属性)
<quizDetails>
<quiz quizID="1" weight="10" mandatory="false" />
<quiz quizID="2" weight="10" mandatory="false" />
<quiz quizID="3" weight="30" mandatory="true" />
</quizDetails>
<student>
<scores>
<score scoreID="1">7</score>
<score scoreID="2">9</score>
<score scoreID="3">13</score>
</scores>
</student>
<student>
<scores>
<score scoreID="1">8</score>
<score scoreID="2">4</score>
<score scoreID="3">25</score>
</scores>
</student>
以下是我尝试这样做的
定义键
<xsl:key name ="quizKey" match="quizDetails" use="@quizID" />
<xsl:key name ="weightKey" match="quizDetails" use="@weight" />
<xsl:key name ="mandatoryKey" match="quizDetails" use="@mandatory" />
<xsl:key name ="scoreKey" match="scores" use="@scoreID" />
条件测试
<xsl:when test="sum(scores/score) > 25 and (key('quizKey', '@quizID') = key('scoreKey', '@scoreID')) and (key('mandatoryKey', 'true') .div (key('weightKey', '@weight') <0.5;">
条件测试相当有点
使用键功能基本上是我的主要问题。我想复制我以前的xml和xsl但没有重复代码的行为。
答案 0 :(得分:1)
如果我理解正确,你只需要一把钥匙:
<xsl:key name="quiz" match="quiz" use="@quizID" />
然后你可以看到 - 从student
的上下文 - 如果至少有一个分数是强制性的,那么通过测试:
key('quiz', scores/score/@scoreID)/@mandatory='true'
恐怕我不明白其他测试应该做什么。看起来它需要单独应用于每个分数?但这不是你原来的测试所做的。
另请注意,XML区分大小写:'True'不等于'true'。
为了更清晰,请考虑以下模板:
<xsl:template match="scores">
<xsl:variable name="total-score" select="sum(score)" />
<xsl:variable name="total-weight" select="sum(key('quiz', score/@scoreID)/@weight)" />
<xsl:copy>
<xsl:for-each select="score">
<xsl:variable name="quiz" select="key('quiz', @scoreID)" />
<xsl:if test="$total-score > $total-weight div 2 and $quiz/@mandatory='true' and . div $quiz/@weight > 0.5">
<xsl:copy-of select="."/>
</xsl:if>
</xsl:for-each>
</xsl:copy>
</xsl:template>
当满足以下所有条件时,这将输出个人分数:
答案 1 :(得分:1)
我认为你这里只需要一个密钥来查找 delete
from usernamepassword join faculty_admininfo
on (usernamepassword.username = faculty_admininfo.email_address)
where faculty_admininfo.employee_id IN ('SCM-021232');
元素
quiz
要查找当前分数元素的<xsl:key name="quizKey" match="quiz" use="@quizID" />
元素,使用密钥将是这样的
quiz
这意味着你的表达式需要如下所示:
key('quizKey', @scoreID)
你可以通过仅选择一个键中的强制性测验元素来实际改进。例如
<xsl:when test="sum(scores/score) > 25
and scores/score[number(.) div key('quizKey', @scoreID)[@mandatory='true']/@weight < 0.5]">
然后条件如下:
<xsl:key name="mandatoryKey" match="quiz[@mandatory='true']" use="@quizID" />