我有一个Source XML如下: -
<StudentSet>
<Student>
<StudentName>Kapil</StudentName>
<Subject>English</Subject>
<Subject>History</Subject>
<Subject>Mathematics</Subject>
<Subject>Economics</Subject>
</Student>
<Student>
<StudentName>Atul</StudentName>
<Subject>English</Subject>
<Subject>History</Subject>
<Subject>Economics</Subject>
</Student>
<Student>
<StudentName>Nisha</StudentName>
<Subject>English</Subject>
<Subject>History</Subject>
</Student>
<Student>
<StudentName>Manish</StudentName>
</Student>
</StudentSet>
要应用的规则如下。
1)如果学生已注册数学,则显示学生姓名和数学
2)如果一个学生注册了经济学但没有注册数学,那就显示学生姓名和经济学
3)如果学生既没有注册数学和经济学,请选择学生姓名和任何一个科目。
4)如果学生没有注册任何科目,请不要选择该学生。
我想获得以下输出: -
<StudentSet>
<Student>
<StudentName>Kapil</StudentName>
<Subject>Mathematics</Subject>
</Student>
<Student>
<StudentName>Atul</StudentName>
<Subject>Economics</Subject>
</Student>
<Student>
<StudentName>Nisha</StudentName>
<Subject>English</Subject>
</Student>
</StudentSet>
请问有人可以帮助XSLT使用吗?
答案 0 :(得分:4)
简单的方法就是使用带有谓词的模板,如下所示:
<xsl:template match="Student[Subject='Economics']">
<!-- Handle economics students -->
</xsl:template>
<xsl:template match="Student[Subject='Mathematics']">
<!-- Handle maths students -->
<!-- overrides maths+econ students, as it comes later -->
</xsl:template>
<xsl:template match="Student[not(Subject='Economics') and not(Subject='Mathematics')]">
<!-- Handle other students. Use 'Subject[1]' to refer to first subject -->
</xsl:template>
<!-- Handle students with no subject, outputting nothing. -->
<xsl:template match="Student[not(Subject)]" />
在每种情况下,您可能都想
<xsl:copy> <!-- copies the 'Student' element -->
<xsl:copy-of select="StudentName" />
<xsl:copy-of select="Subject[text()='subjectname']" />
<!-- or -->
<xsl:copy-of select="Subject[1]" /> <!-- first subject in list -->
</xsl:copy>
这是一种更短,更有效的方式,但对于初学者来说理解起来有点困难:
<xsl:template match="Student[Subject='Mathematics']/Subject[not(text()='Mathematics')]" />
<xsl:template match="Student[Subject='Economics' and not(Subject='Mathematics')]/Subject[not(text()='Economics')]" />
<xsl:template match="Student[not(Subject='Economics') and not(Subject='Mathematics')]/Subject[position() != 1]" />
<xsl:template match="Student[not(Subject)]" />
这些操作描述了不应输出的元素。例如,第一个找到具有数学主题的任何Student
元素,并且在其中找到没有“数学”文本的任何Subject
元素。模板匹配这些节点,并且不输出任何内容。您实际上可以使用一个大型模板规则执行此操作:
<xsl:template match="
Student[Subject='Mathematics']/Subject[not(text()='Mathematics')]
| Student[Subject='Economics' and not(Subject='Mathematics')]/Subject[not(text()='Economics')]
| Student[not(Subject='Economics') and not(Subject='Mathematics')]/Subject[position() != 1]
| Student[not(Subject)]
" />
虽然这样做开始变得不那么可读。
答案 1 :(得分:0)
这是一个更简单的解决方案,适用于任意数量的优先主题,并且只使用固定大小的单个模板它可以轻松用于更加困难的问题:“仅显示来自k
科目的优先级列表中的第一个N
科目:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:param name="vSubs" select="'x|Economics|Mathematics|'"/>
<xsl:template match="Student[Subject]">
<Student>
<xsl:copy-of select="StudentName"/>
<xsl:for-each select="Subject">
<xsl:sort
select="string-length(substring-before($vSubs,
concat('|',.,'|')
)
)"
data-type="number" order="descending"/>
<xsl:if test="position()=1">
<xsl:copy-of select="."/>
</xsl:if>
</xsl:for-each>
</Student>
</xsl:template>
<xsl:template match="text()"/>
</xsl:stylesheet>
应用于提供的XML文档:
<StudentSet>
<Student>
<StudentName>Kapil</StudentName>
<Subject>English</Subject>
<Subject>History</Subject>
<Subject>Mathematics</Subject>
<Subject>Economics</Subject>
</Student>
<Student>
<StudentName>Atul</StudentName>
<Subject>English</Subject>
<Subject>History</Subject>
<Subject>Economics</Subject>
</Student>
<Student>
<StudentName>Nisha</StudentName>
<Subject>English</Subject>
<Subject>History</Subject>
</Student>
<Student>
<StudentName>Manish</StudentName>
</Student>
</StudentSet>
产生了想要的正确结果:
<Student>
<StudentName>Kapil</StudentName>
<Subject>Mathematics</Subject>
</Student>
<Student>
<StudentName>Atul</StudentName>
<Subject>Economics</Subject>
</Student>
<Student>
<StudentName>Nisha</StudentName>
<Subject>English</Subject>
</Student>