如何在XSLT转换为JSON后重命名整个JSON文件的键
使用XSLT转换JSON后批量重命名所有键
假设你已经通过XSLT将源数据转为JSON格式,现在需要对JSON中所有层级的键进行批量重命名。以下是基于XSLT 3.0的解决方案,支持处理嵌套对象和数组结构。
示例输入JSON
{ "squadName": "Super hero squad", "homeTown": "Metro City", "formed": 2016, "secretBase": "Super tower", "active": true, "members": [ { "name": "Molecule Man", "age": 29, "secretIdentity": "Dan Jukes", "powers": ["Radiation resistance", "Turning tiny", "Radiation blast"] }, { "name": "Madame Uppercut", "age": 39, "secretIdentity": "Jane Wilson", "powers": [ "Million tonne punch", "Damage resistance", "Superhuman reflexes" ] } ] }
解决方案步骤
定义键名映射表
先明确所有需要替换的原键和目标键,示例映射如下:squadName→战队名称homeTown→所在地formed→成立年份secretBase→秘密基地active→是否活跃members→成员列表name→姓名age→年龄secretIdentity→真实身份powers→超能力
编写XSLT处理代码
利用XSLT 3.0的JSON处理函数和递归模板处理嵌套结构:
<xsl:stylesheet version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="text" encoding="UTF-8"/> <!-- 定义键名映射 --> <xsl:variable name="key-mapping" as="map(xs:string, xs:string)"> <xsl:map> <xsl:map-entry key="'squadName'" select="'战队名称'"/> <xsl:map-entry key="'homeTown'" select="'所在地'"/> <xsl:map-entry key="'formed'" select="'成立年份'"/> <xsl:map-entry key="'secretBase'" select="'秘密基地'"/> <xsl:map-entry key="'active'" select="'是否活跃'"/> <xsl:map-entry key="'members'" select="'成员列表'"/> <xsl:map-entry key="'name'" select="'姓名'"/> <xsl:map-entry key="'age'" select="'年龄'"/> <xsl:map-entry key="'secretIdentity'" select="'真实身份'"/> <xsl:map-entry key="'powers'" select="'超能力'"/> </xsl:map> </xsl:variable> <!-- 主模板:解析JSON并处理 --> <xsl:template match="/"> <xsl:variable name="input-json" select="parse-json(unparsed-text('input.json'))"/> <xsl:variable name="processed-data" select="process-node($input-json)"/> <xsl:value-of select="serialize($processed-data, map{'method':'json', 'indent':true()})"/> </xsl:template> <!-- 递归处理节点:区分对象、数组、普通值 --> <xsl:function name="process-node" as="item()*"> <xsl:param name="node" as="item()"/> <!-- 处理JSON对象(map) --> <xsl:if test="$node instance of map(*)"> <xsl:map> <xsl:for-each select="map:keys($node)"> <xsl:variable name="new-key" select="$key-mapping(.)"/> <!-- 有映射则替换键名,无映射保留原键 --> <xsl:map-entry key="if ($new-key) then $new-key else ." select="process-node($node(.))"/> </xsl:for-each> </xsl:map> </xsl:if> <!-- 处理JSON数组(sequence) --> <xsl:if test="$node instance of item()* and not($node instance of map(*))"> <xsl:sequence select="for $item in $node return process-node($item)"/> </xsl:if> <!-- 处理普通值(字符串、数字、布尔值等) --> <xsl:if test="$node instance of xs:anyAtomicType"> <xsl:sequence select="$node"/> </xsl:if> </xsl:function> </xsl:stylesheet>
- 代码核心说明
parse-json:将输入JSON文件解析为XSLT可处理的map/sequence结构process-node递归函数:遍历所有节点,对象替换键名,数组递归处理元素,普通值直接返回serialize:将处理后的结构重新序列化为格式化的JSON字符串- 未在映射表定义的键会保留原名称,避免遗漏
转换后的输出JSON
{ "战队名称": "Super hero squad", "所在地": "Metro City", "成立年份": 2016, "秘密基地": "Super tower", "是否活跃": true, "成员列表": [ { "姓名": "Molecule Man", "年龄": 29, "真实身份": "Dan Jukes", "超能力": ["Radiation resistance", "Turning tiny", "Radiation blast"] }, { "姓名": "Madame Uppercut", "年龄": 39, "真实身份": "Jane Wilson", "超能力": [ "Million tonne punch", "Damage resistance", "Superhuman reflexes" ] } ] }
内容的提问来源于stack exchange,提问作者Ram Prasad
相关产品推荐
相关产品推荐

