XSLT外层节点模板应用时维护sno连续编号及UUID生成问题
解决方案
核心问题修复点
1. 全局连续的<sno>编号
原实现的问题是在每个<author>内部单独计数,导致包含<otherbooks>的author下的<sno>重置为1。要实现全局连续编号,需要基于所有要生成的<authordetails>节点进行全局计数,而非每个author内部计数。
2. 为每个<author>生成UUID(适配SaxonC-HE)
SaxonC-HE支持XSLT 3.0标准的fn:random-uuid()函数,可直接生成符合RFC 4122的UUID,无需额外扩展库。
修改后的XSLT代码
<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="xml" indent="yes"/> <!-- 全局变量:预计算所有需要生成的authordetails总数(用于验证计数) --> <xsl:variable name="total-authordetails" as="xs:integer" select="sum(//author/(if (exists(otherbooks/book)) then count(otherbooks/book) else 1))"/> <!-- 匹配根节点 --> <xsl:template match="/"> <authors> <xsl:apply-templates select="authors/author"/> </authors> </xsl:template> <!-- 匹配无otherbooks的author --> <xsl:template match="author[not(otherbooks/book)]"> <authordetails> <sno> <!-- 全局计数:统计所有已生成的authordetails节点 + 当前节点 --> <xsl:number level="any" count="authordetails" from="/authors"/> </sno> <uuid><xsl:value-of select="random-uuid()"/></uuid> <name><xsl:value-of select="name"/></name> <mainbook><xsl:value-of select="mainbook"/></mainbook> </authordetails> </xsl:template> <!-- 匹配有otherbooks的author --> <xsl:template match="author[otherbooks/book]"> <xsl:variable name="current-author" select="."/> <!-- 循环每个otherbooks下的book,生成authordetails --> <xsl:for-each select="otherbooks/book"> <authordetails> <sno> <xsl:number level="any" count="authordetails" from="/authors"/> </sno> <uuid><xsl:value-of select="$current-author/uuid"/></uuid> <name><xsl:value-of select="$current-author/name"/></name> <mainbook><xsl:value-of select="$current-author/mainbook"/></mainbook> <otherbook><xsl:value-of select="."/></otherbook> </authordetails> </xsl:for-each> </xsl:template> </xsl:stylesheet>
关键改动说明
全局连续编号:
- 使用
<xsl:number level="any" count="authordetails" from="/authors"/>,基于整个输出树中的<authordetails>节点进行全局计数,确保编号从1开始连续递增,不会在每个author内部重置。 - 预定义的
total-authordetails变量可用于验证最终生成的节点总数是否符合预期。
- 使用
UUID生成:
- 直接调用XSLT 3.0标准函数
random-uuid(),SaxonC-HE原生支持该函数,无需额外配置。 - 对于包含
<otherbooks>的author,将UUID存储在变量中,确保同一author的所有<authordetails>使用同一个UUID。
- 直接调用XSLT 3.0标准函数
输入示例
<authors> <author> <name>Alice</name> <mainbook>Book A</mainbook> </author> <author> <name>Bob</name> <mainbook>Book B</mainbook> <otherbooks> <book>Book B1</book> <book>Book B2</book> </otherbooks> </author> <author> <name>Charlie</name> <mainbook>Book C</mainbook> </author> </authors>
期望输出示例
<authors> <authordetails> <sno>1</sno> <uuid>550e8400-e29b-41d4-a716-446655440000</uuid> <name>Alice</name> <mainbook>Book A</mainbook> </authordetails> <authordetails> <sno>2</sno> <uuid>550e8400-e29b-41d4-a716-446655440001</uuid> <name>Bob</name> <mainbook>Book B</mainbook> <otherbook>Book B1</otherbook> </authordetails> <authordetails> <sno>3</sno> <uuid>550e8400-e29b-41d4-a716-446655440001</uuid> <name>Bob</name> <mainbook>Book B</mainbook> <otherbook>Book B2</otherbook> </authordetails> <authordetails> <sno>4</sno> <uuid>550e8400-e29b-41d4-a716-446655440002</uuid> <name>Charlie</name> <mainbook>Book C</mainbook> </authordetails> </authors>
内容的提问来源于stack exchange,提问作者user24663487
相关产品推荐
相关产品推荐

