求助:基于XSLT 1.0实现XML转CSV并提取唯一代码
用XSLT 1.0实现唯一代码提取与CSV转换
核心思路:用<xsl:key>+generate-id()模拟分组去重
XSLT 1.0没有原生的分组去重功能,我们可以通过键值分组+节点唯一标识的组合来实现。具体逻辑:
- 定义一个键,把所有表格行(
<tr>)按第6个<td>的内容分组 - 遍历所有行,只保留每组的第一个节点(通过
generate-id()判断节点是否为组内首个),以此得到所有唯一代码
完整示例代码
假设你的XML结构如下:
<table> <tr> <td>数据1</td> <td>数据2</td> <td>数据3</td> <td>数据4</td> <td>数据5</td> <td>010E</td> <td>对应值1</td> </tr> <tr> <td>数据1</td> <td>数据2</td> <td>数据3</td> <td>数据4</td> <td>数据5</td> <td>049E</td> <td>对应值2</td> </tr> <tr> <td>数据1</td> <td>数据2</td> <td>数据3</td> <td>数据4</td> <td>数据5</td> <td>010E</td> <td>对应值3</td> </tr> </table>
对应的XSLT 1.0转换代码:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="text" encoding="UTF-8"/> <!-- 定义键:按第6个<td>的内容分组所有<tr> --> <xsl:key name="unique-code" match="tr" use="td[6]"/> <xsl:template match="/"> <!-- 生成CSV表头:先写固定列,再追加唯一代码 --> <xsl:text>列1,列2,列3,列4,列5,</xsl:text> <!-- 遍历所有唯一代码的组首节点 --> <xsl:for-each select="table/tr[generate-id() = generate-id(key('unique-code', td[6])[1])]"> <xsl:value-of select="td[6]"/> <!-- 最后一个代码后不输出逗号 --> <xsl:if test="position() != last()"> <xsl:text>,</xsl:text> </xsl:if> </xsl:for-each> <xsl:text> </xsl:text> <!-- 换行符 --> <!-- 生成CSV数据行 --> <xsl:for-each select="table/tr"> <!-- 输出前5列 --> <xsl:value-of select="concat(td[1], ',', td[2], ',', td[3], ',', td[4], ',', td[5])"/> <!-- 根据唯一代码列表,匹配对应的值(这里假设第7列是代码对应值,可按需调整) --> <xsl:for-each select="/table/tr[generate-id() = generate-id(key('unique-code', td[6])[1])]"> <xsl:text>,</xsl:text> <!-- 找到当前行中对应代码的值 --> <xsl:value-of select="key('unique-code', td[6])[current()/../td[6] = td[6]]/td[7]"/> </xsl:for-each> <xsl:text> </xsl:text> <!-- 换行符 --> </xsl:for-each> </xsl:template> </xsl:stylesheet>
关键细节说明
<xsl:key name="unique-code" match="tr" use="td[6]"/>:将所有行按第6个单元格的内容绑定到同一键值下,实现分组generate-id() = generate-id(key('unique-code', td[6])[1]):只保留每组的第一个节点,确保提取的代码唯一- 如果单元格内容包含逗号或双引号,需要额外添加模板用双引号包裹内容,避免CSV格式错乱
内容的提问来源于stack exchange,提问作者Shev
相关产品推荐
相关产品推荐

