所以我的XML如下:
<Classes>
<Classes_Per_Term>
<Course>ENC1101</Course>
<Ref_Code>111111</Ref_Code>
<Days_of_Week>M</Days_of_Week>
</Classes_Per_Term>
<Classes_Per_Term>
<Course>ENC1101</Course>
<Ref_Code>111222</Ref_Code>
<Days_of_Week>M W F</Days_of_Week>
</Classes_Per_Term>
</Classes>
我需要输出看起来像这样
ENC1101 111111 M ENC1101 111222 M ENC1101 111222 W ENC1101 111222 F
我正在使用<Course>
调用打印<Ref_Code>
和<xsl:value-of>
并使用换行符跳转到下一行。我不确定如何在<Days_of_Week>
节点内设置循环。
有各种各样的日组合 - 我需要每天特定参考符合一行。
感谢任何帮助。谢谢!
答案 0 :(得分:2)
首先,您必须为输入XML设置一个根元素,否则它的格式不正确:
<?xml version="1.0" encoding="UTF-8"?>
<Classes>
<Classes_Per_Term>
<Course>ENC1101</Course>
<Ref_Code>111111</Ref_Code>
<Days_of_Week>M</Days_of_Week>
</Classes_Per_Term>
<Classes_Per_Term>
<Course>ENC1101</Course>
<Ref_Code>111222</Ref_Code>
<Days_of_Week>M W F</Days_of_Week>
</Classes_Per_Term>
</Classes>
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:strip-space elements="*"/>
<xsl:template match="/Classes/Classes_Per_Term">
<xsl:variable name="course" select="Course"/>
<xsl:variable name="refcode" select="Ref_Code"/>
<xsl:for-each select="tokenize(Days_of_Week, ' ')">
<xsl:value-of select="concat($course, ' ', $refcode, ' ', ., '
')"/>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
<强>产量强>
ENC1101 111111 M
ENC1101 111222 M
ENC1101 111222 W
ENC1101 111222 F
根据要求。
答案 1 :(得分:0)
对于XSLT 1.0解决方案,必须生成不带tokenize()
的序列。此解决方案不使用递归,并使用文档的节点作为生成器来提供位置值和过滤器的字符串长度。
对于一周中不同长度的日期,或者对于令牌数量可能超过文档中节点总数的应用程序,解决方案不健壮。在这种情况下,递归结构中更全面的解析器可能更合适。
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" indent="no" />
<xsl:template match="Classes_Per_Term">
<xsl:variable name="Classes" select="." />
<xsl:variable name="Days" select="Days_of_Week" />
<xsl:for-each select="//*">
<xsl:variable name="Day" select="substring($Classes/Days_of_Week, position() * 2 - 1, 1)" />
<xsl:if test="position() <= (string-length($Days) + 1) div 2">
<xsl:value-of select="$Classes/Course" />
<xsl:text> </xsl:text>
<xsl:value-of select="$Classes/Ref_Code" />
<xsl:text> </xsl:text>
<xsl:value-of select="$Day" />
<xsl:text>
</xsl:text>
</xsl:if>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
要求在文档中包含顶级节点。
答案 2 :(得分:0)
对于XSLT 1.0,这几乎可以通过递归来解决。
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" />
<xsl:strip-space elements="*" />
<xsl:template match="Classes_Per_Term">
<xsl:param name="days" select="Days_of_Week" />
<xsl:variable name="day" select="substring-before(concat($days, ' '), ' ')" />
<xsl:if test="$day">
<xsl:value-of select="concat(Course, ' ', Ref_Code, ' ', $day, '
')" />
<xsl:apply-templates select=".">
<xsl:with-param name="days" select="substring-after($days, ' ')" />
</xsl:apply-templates>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
根据需要输出
ENC1101 111111 M ENC1101 111222 M ENC1101 111222 W ENC1101 111222 F
此模板会一直调用自己,直到用完$days
,每次调用打印一个$day
。