如何使用XSLT 1.0将含工作日时间的XML转换为指定格式JSON
XSLT 1.0 营业时间XML转JSON简洁实现方案
核心思路
- 预定义星期名与编号的映射关系,避免为每个工作日单独编写匹配模板
- 单循环遍历7个工作日,动态读取对应开闭时间节点,复用逻辑代码
- 同步生成periods数组和weekday_text数组内容,避免重复遍历源数据
完整实现代码
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:exsl="http://exslt.org/common" exclude-result-prefixes="exsl"> <xsl:output method="text" encoding="UTF-8" omit-xml-declaration="yes" /> <!-- 预定义星期映射:名称对应输出的day编号 0-6 --> <xsl:variable name="weekdays-raw"> <day name="Monday" index="0" /> <day name="Tuesday" index="1" /> <day name="Wednesday" index="2" /> <day name="Thursday" index="3" /> <day name="Friday" index="4" /> <day name="Saturday" index="5" /> <day name="Sunday" index="6" /> </xsl:variable> <xsl:variable name="weekdays" select="exsl:node-set($weekdays-raw)/day" /> <xsl:template match="/OpeningTimes"> <xsl:text>{ "opening_hours": { "open_now": false, "periods": [</xsl:text> <!-- 生成periods数组 --> <xsl:for-each select="$weekdays"> <xsl:variable name="day-name" select="@name" /> <xsl:variable name="day-index" select="@index" /> <xsl:variable name="open-time" select="/*/*[local-name() = concat($day-name, 'Open')]" /> <xsl:variable name="close-time" select="/*/*[local-name() = concat($day-name, 'Closed')]" /> <xsl:if test="position() > 1"> <xsl:text>,</xsl:text> </xsl:if> <xsl:text> { "close": { "day": </xsl:text><xsl:value-of select="$day-index" /><xsl:text>, "time": "</xsl:text><xsl:value-of select="translate($close-time, ':', '')" /><xsl:text>" }, "open": { "day": </xsl:text><xsl:value-of select="$day-index" /><xsl:text>, "time": "</xsl:text><xsl:value-of select="translate($open-time, ':', '')" /><xsl:text>" } }</xsl:text> </xsl:for-each> <xsl:text> ], "weekday_text": [</xsl:text> <!-- 生成weekday_text数组 --> <xsl:for-each select="$weekdays"> <xsl:variable name="day-name" select="@name" /> <xsl:variable name="open-time" select="/*/*[local-name() = concat($day-name, 'Open')]" /> <xsl:variable name="close-time" select="/*/*[local-name() = concat($day-name, 'Closed')]" /> <xsl:if test="position() > 1"> <xsl:text>,</xsl:text> </xsl:if> <!-- 这里可以替换成你自己实现的24小时转12小时制逻辑 --> <xsl:text> "</xsl:text><xsl:value-of select="$day-name" /><xsl:text>: </xsl:text><xsl:value-of select="$open-time" /><xsl:text> – </xsl:text><xsl:value-of select="$close-time" /><xsl:text>"</xsl:text> </xsl:for-each> <xsl:text> ] } }</xsl:text> </xsl:template> </xsl:stylesheet>
兼容说明
如果运行环境不支持EXSLT的node-set扩展,可以将星期映射改为通过xsl:choose按循环位置判断星期名称,无需依赖扩展函数即可正常运行。若源节点带有au命名空间,将local-name()替换为name()即可匹配带前缀的节点。
内容的提问来源于stack exchange,提问作者Abjt G
相关产品推荐
相关产品推荐

