You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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>&#10;</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>&#10;</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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 06:22:53