基于已有数据在XSLT 2.0中新增<sequence>元素的实现方法
XSLT 2.0实现基于ID时间序列的元素添加方案
核心思路
利用XSLT 2.0的分组功能(xsl:for-each-group)按ID聚合节点,结合节点在组内的位置判断,为不同情况的节点添加对应的<sequence>元素:
- 同ID的两个节点中,排在前面的旧数据节点添加
<sequence>first</sequence> - 同ID的第二个新数据节点、以及唯一ID的节点,统一添加
<sequence>second</sequence>
简化版XML示例
<root> <item> <id>1001</id> <time>2023-01-01</time> <data>旧数据</data> </item> <item> <id>1001</id> <time>2023-02-01</time> <data>新数据</data> </item> <item> <id>1002</id> <time>2023-01-05</time> <data>唯一数据</data> </item> </root>
实现代码
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <!-- 默认复制规则:保留所有原有节点、属性和文本 --> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply-templates select="@*|node()"/> </xsl:copy> </xsl:template> <!-- 处理目标节点(此处为item,复杂版替换为实际节点名) --> <xsl:template match="item"> <xsl:copy> <!-- 复制原有内容 --> <xsl:apply-templates select="@*|node()"/> <!-- 插入sequence元素 --> <sequence> <xsl:choose> <!-- 组内有2个节点且当前是第一个(旧数据) --> <xsl:when test="count(current-group()) = 2 and position() = 1">first</xsl:when> <!-- 其余情况:唯一ID节点或组内第二个节点 --> <xsl:otherwise>second</xsl:otherwise> </xsl:choose> </sequence> </xsl:copy> </xsl:template> <!-- 按ID分组处理节点 --> <xsl:template match="root"> <xsl:copy> <xsl:for-each-group select="item" group-by="id"> <xsl:apply-templates select="current-group()"/> </xsl:for-each-group> </xsl:copy> </xsl:template> </xsl:stylesheet>
代码说明
- 默认复制模板:确保原有XML结构和数据完全保留,不影响现有复杂规则集的逻辑
- 分组处理:通过
xsl:for-each-group按id值聚合节点,current-group()可获取同ID的所有节点 - 序列判断:
- 当组内节点数为2且当前节点是组内第一个时,输出
first - 其他情况(组内仅1个节点,或组内第二个节点)输出
second,符合题目要求的唯一ID节点规则
- 当组内节点数为2且当前节点是组内第一个时,输出
适配复杂版XML的调整方法
- 节点匹配调整:如果复杂版中需要添加
<sequence>的不是item节点,将模板中的match="item"替换为实际节点名称(如record) - ID路径调整:如果ID不是直接的子节点(如
metadata/id),修改group-by和判断逻辑中的路径,例如group-by="metadata/id" - 容器节点调整:如果根节点或节点容器不是
root,修改match="root"为实际的容器节点路径
转换后简化版结果
<root> <item> <id>1001</id> <time>2023-01-01</time> <data>旧数据</data> <sequence>first</sequence> </item> <item> <id>1001</id> <time>2023-02-01</time> <data>新数据</data> <sequence>second</sequence> </item> <item> <id>1002</id> <time>2023-01-05</time> <data>唯一数据</data> <sequence>second</sequence> </item> </root>
内容的提问来源于stack exchange,提问作者tm1701
相关产品推荐
相关产品推荐

