XSLT-2.0条件语句/分组需求:XML转CSV补全出版物零值计数
用XSLT 2.0实现按年份统计出版物类型并生成CSV(含0值补全)
嘿,我来帮你搞定这个需求!作为刚接触XSLT和XML的新手,你遇到的按年份统计、补全无数据类型为0的场景,正好可以用XSLT 2.0的分组和值处理功能来解决。我给你拆解步骤,附上可复用的示例代码,你可以根据自己的实际XML结构调整。
先明确核心需求
我们要生成这样的CSV:
- 每行对应一个年份
- 每列对应一种出版物类型(书籍、期刊文章等)
- 某年份没有某类型数据时,强制显示
0
示例XML结构(你可以对应自己的结构修改)
假设你的数据大概是这样的:
<facultyPublications> <publication> <year>2020</year> <type>Book</type> <author>John Doe</author> </publication> <publication> <year>2020</year> <type>Journal Article</type> <author>Jane Smith</author> </publication> <publication> <year>2021</year> <type>Book Chapter</type> <author>John Doe</author> </publication> <publication> <year>2022</year> <type>Journal Article</type> <author>Jane Smith</author> </publication> <publication> <year>2022</year> <type>Journal Article</type> <author>John Doe</author> </publication> </facultyPublications>
XSLT 2.0解决方案代码
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="text" encoding="UTF-8"/> <!-- 1. 提取XML中所有唯一的出版物类型 --> <xsl:variable name="allTypes" select="distinct-values(/facultyPublications/publication/type)"/> <!-- 2. 获取所有唯一的年份并按升序排序 --> <xsl:variable name="allYears" select="distinct-values(/facultyPublications/publication/year)" order="ascending"/> <xsl:template match="/"> <!-- 生成CSV表头:年份 + 所有类型名称 --> <xsl:text>Year</xsl:text> <xsl:for-each select="$allTypes"> <xsl:text>,</xsl:text> <xsl:value-of select="."/> </xsl:for-each> <xsl:text> </xsl:text> <!-- 换行符 --> <!-- 遍历每个年份,生成统计行 --> <xsl:for-each select="$allYears"> <xsl:variable name="currentYear" select="."/> <!-- 输出当前年份 --> <xsl:value-of select="$currentYear"/> <!-- 遍历每个类型,统计数量 --> <xsl:for-each select="$allTypes"> <xsl:variable name="currentType" select="."/> <xsl:text>,</xsl:text> <!-- 统计当前年份下当前类型的出版物数量,无匹配时自动返回0 --> <xsl:value-of select="count(/facultyPublications/publication[year = $currentYear and type = $currentType])"/> </xsl:for-each> <xsl:text> </xsl:text> <!-- 换行符 --> </xsl:for-each> </xsl:template> </xsl:stylesheet>
关键代码解释
distinct-values():用来提取XML中唯一的年份和类型,确保我们覆盖所有需要统计的维度,不会遗漏任何年份或类型。order="ascending":对年份进行升序排序,让CSV的年份按时间顺序排列,更符合阅读习惯。count(...):直接统计符合年份和类型条件的出版物节点数量,如果没有匹配的节点,count()会自动返回0,完美满足我们补0的需求,不用额外写复杂的条件判断!- 文本输出配置:用
<xsl:output method="text"/>确保输出纯文本格式,配合逗号分隔符和换行符生成标准CSV。
输出的CSV示例
运行上面的XSLT后,会得到这样的结果:
Year,Book,Journal Article,Book Chapter 2020,1,1,0 2021,0,0,1 2022,0,2,0
你只需要把示例中的XML路径(比如/facultyPublications/publication)改成你自己的XML结构对应的路径就可以了。如果你的出版物类型是固定的(比如不会新增类型),也可以直接把$allTypes写成静态序列,比如('Book', 'Journal Article', 'Book Chapter'),这样运行效率会更高。
内容的提问来源于stack exchange,提问作者mks
相关产品推荐
相关产品推荐

