XSLT 3.0使用map函数实现Debtor字段值映射的方法
原有XSLT代码错误排查
原有代码存在4个核心问题,无法正常运行:
- 语法错误:
<xsl:stylesheet>开始标签未闭合,声明完命名空间属性后缺少闭合符号>,直接拼接了<xsl:output>标签,XML解析阶段就会失败。 - 语法错误:XSLT的
<xsl:template>属于顶层元素,必须作为<xsl:stylesheet>的直接子节点,不允许嵌套在<xsl:for-each>等逻辑块内部,原有代码将Debtor匹配模板写在MessageHeader模板的循环内,不符合语法规范。 - 逻辑错误:自定义的MessageHeader匹配模板完全覆盖了身份转换逻辑,既没有复制节点本身,也没有调用
<xsl:apply-templates>递归处理子节点,会导致MessageHeader下的所有内容丢失。 - 逻辑错误:调用
map:get取值时传入的是Debtor元素节点,不是字符串值,和JSON解析出的字符串类型key不匹配,无法命中映射规则。
额外注意:你提供的输入XML存在根标签不匹配的笔误,开头根节点为<JECreateRequest>,结尾闭合标签为</JournalEntryBulkCreateRequest>,运行前需要将两个标签修正一致,否则XML解析会报错。
可直接运行的正确实现
以下代码完全满足「仅替换Debtor字段值、其余节点结构/取值完全保留」的需求,兼容XSLT 3.0标准:
<xsl:stylesheet version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:map="http://www.w3.org/2005/xpath-functions/map"> <xsl:output method="xml" encoding="UTF-8" indent="yes"/> <xsl:strip-space elements="*"/> <!-- 映射参数,默认值为给定的映射规则,实际运行可通过外部传参覆盖 --> <xsl:param name="P_BPMapping" select="'{"BANK1":"1","BANK2":"2","BANK3":"3","BANK4":"4"}'" /> <xsl:param name="MapDebitor" as="map(*)" select="parse-json($P_BPMapping)" /> <!-- 身份转换模板:默认所有节点、属性原样复制 --> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply-templates select="@*|node()"/> </xsl:copy> </xsl:template> <!-- 全局匹配所有Debtor元素,执行值映射替换 --> <xsl:template match="Debtor"> <xsl:copy> <xsl:variable name="currentDebtor" select="normalize-space(.)"/> <xsl:choose> <xsl:when test="map:contains($MapDebitor, $currentDebtor)"> <xsl:value-of select="map:get($MapDebitor, $currentDebtor)" /> </xsl:when> <xsl:otherwise> <error> <xsl:text>Error in BusinessPartner mapping. Please maintain the mapping for the following debtor: </xsl:text> <xsl:value-of select="$currentDebtor"/> </error> </xsl:otherwise> </xsl:choose> </xsl:copy> </xsl:template> </xsl:stylesheet>
实现说明
- 基于标准身份转换逻辑实现,所有非Debtor节点、属性、结构完全和输入一致,不会产生额外改动。
- 全局匹配所有层级的Debtor元素,不需要写死节点路径,不管Debtor嵌套在什么位置都能正确替换。
- 用
normalize-space()处理Debtor值前后的空格、换行符,避免因为格式问题导致映射匹配失败。 - 用
map:contains()预先判断key是否存在,比直接判断返回值更严谨,避免映射值为空时误触发错误分支。
内容的提问来源于stack exchange,提问作者Roshan
相关产品推荐
相关产品推荐

