XSLT日期格式转换求助:无法调用变量m实现日期格式转换
XSLT日期格式转换问题排查与修复
原始XML输入
<?xml version="1.0" encoding="UTF-8"?> <root> <CandidateId>863</CandidateId> <CaseId>2762833</CaseId> <Status>Completed</Status> <InitiatedDate>01 Dec 2022</InitiatedDate> <CompletionDate>15 Jan 2022</CompletionDate> <Comments /> </root>
原始XSLT代码
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" exclude-result-prefixes="xs"> <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/> <xsl:template match="node()"> <xsl:apply-templates/> </xsl:template> <xsl:template match="/"> <JobApplication> <xsl:for-each select="root"> <JobApplication> <xsl:variable name="month" select="substring(InitiatedDate,4,3)" /> <xsl:if test="$month = 'Dec'"> <xsl:variable name="m">12</xsl:variable> </xsl:if> <xsl:if test="$month = 'Nov'"> <xsl:variable name="m">11</xsl:variable> </xsl:if> <xsl:if test="$month = 'Oct'"> <xsl:variable name="m">10</xsl:variable> </xsl:if> <Bbgvdate><xsl:value-of select="concat(substring(InitiatedDate,8,4),'-',$m,'-',substring(InitiatedDate,1,2),'T00:00:00')"/></Bbgvdate> <applicationId><xsl:value-of select="CandidateID"/></applicationId> </JobApplication> </xsl:for-each> </JobApplication> </xsl:template> </xsl:stylesheet>
错误原因分析
- 变量作用域问题:每个
<xsl:if>内部定义的变量$m仅在该if块内有效,外部无法访问,导致编译时找不到$m变量。 - 节点名称大小写不匹配:XML中的节点是
<CandidateId>,但XSLT中使用了CandidateID,大小写不一致会导致无法获取对应值。 - 冗余节点嵌套:外层和
<xsl:for-each>内都定义了<JobApplication>,会生成嵌套的无效结构。 - 月份覆盖不全:仅处理了Oct/Nov/Dec三个月份,其他月份会导致
$m无值。
修正后的XSLT代码
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" exclude-result-prefixes="#default"> <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/> <xsl:template match="/"> <xsl:for-each select="root"> <JobApplication> <!-- 提取日期各部分 --> <xsl:variable name="day" select="substring(InitiatedDate, 1, 2)"/> <xsl:variable name="month-abbr" select="substring(InitiatedDate, 4, 3)"/> <xsl:variable name="year" select="substring(InitiatedDate, 8, 4)"/> <!-- 月份缩写转数字,覆盖所有12个月 --> <xsl:variable name="month-num"> <xsl:choose> <xsl:when test="$month-abbr = 'Jan'">01</xsl:when> <xsl:when test="$month-abbr = 'Feb'">02</xsl:when> <xsl:when test="$month-abbr = 'Mar'">03</xsl:when> <xsl:when test="$month-abbr = 'Apr'">04</xsl:when> <xsl:when test="$month-abbr = 'May'">05</xsl:when> <xsl:when test="$month-abbr = 'Jun'">06</xsl:when> <xsl:when test="$month-abbr = 'Jul'">07</xsl:when> <xsl:when test="$month-abbr = 'Aug'">08</xsl:when> <xsl:when test="$month-abbr = 'Sep'">09</xsl:when> <xsl:when test="$month-abbr = 'Oct'">10</xsl:when> <xsl:when test="$month-abbr = 'Nov'">11</xsl:when> <xsl:when test="$month-abbr = 'Dec'">12</xsl:when> </xsl:choose> </xsl:variable> <!-- 生成标准格式日期 --> <Bbgvdate> <xsl:value-of select="concat($year, '-', $month-num, '-', $day, 'T00:00:00')"/> </Bbgvdate> <!-- 修正节点名称大小写 --> <applicationId> <xsl:value-of select="CandidateId"/> </applicationId> </JobApplication> </xsl:for-each> </xsl:template> </xsl:stylesheet>
修正说明
- 统一变量作用域:用
<xsl:choose>在同一作用域内定义$month-num,确保后续代码可正常访问。 - 全月份覆盖:补充所有12个月份的映射,避免因月份未定义导致的空值问题。
- 修正节点名称:将
CandidateID改为CandidateId,匹配XML中的节点名称。 - 移除冗余嵌套:删除外层多余的
<JobApplication>,生成结构正确的XML。 - 代码可读性优化:拆分日期各部分为单独变量,逻辑更清晰。
内容的提问来源于stack exchange,提问作者megrao1811
相关产品推荐
相关产品推荐

