BizTalk:重复节点合并并输出为JSON数组的映射实现问题
我完全理解你现在的困扰——BizTalk映射器里的Loop Functoid没按预期工作,把多个<MIF_ACT_PER>拆成了独立的<Properties>节点,导致最终的JSON输出不符合目标系统要求。下面给你两种靠谱的解决方案,从Functoid配置调整到XSLT脚本实现都有,你可以根据自己的情况选择:
你当前的映射错误在于:用Loop Functoid遍历<MIF_ACT_PER>时,错误地触发了<Properties>节点的重复生成,每个<MIF_ACT_PER>都单独对应一个<Properties>。而我们的目标是:每个<Events>节点下只生成一个<Properties>,把该节点下所有的<MIF_ACT_PER>和对应的<ENT_SUB_TYP>都放在这个<Properties>里。
如果不想写XSLT,可以通过调整Functoid的连接逻辑来解决:
- 先确认目标架构配置:
- 目标的
<Properties>节点Max Occurs设为1(每个<Events>只生成一个) - 目标的
<MIF_ACT_PER>节点Max Occurs设为unbounded(允许多个值)
- 目标的
- 映射器连接逻辑:
- 把源的
<Events>直接连接到目标的<Events>,源的<Properties>直接连接到目标的<Properties>(这一步确保每个<Events>只生成一个<Properties>) - 处理
<ENT_SUB_TYP>:用Value Mapping Functoid,如果源节点为空则映射为NOT_APP,直接连接到目标的<ENT_SUB_TYP> - 处理
<MIF_ACT_PER>:- 添加一个Loop Functoid,输入源的所有
<MIF_ACT_PER>节点,输出连接到目标的<MIF_ACT_PER>(注意:不要连接到<Properties>) - 再用Value Mapping (Flattening) Functoid过滤有效值,把符合条件的
<MIF_ACT_PER>映射到目标节点
- 添加一个Loop Functoid,输入源的所有
- 把源的
这种配置的核心是:让<Properties>的生成只由源的<Properties>驱动一次,而<MIF_ACT_PER>的重复由Loop Functoid单独控制,不会触发<Properties>的重复。
如果Functoid配置搞不定,用XSLT脚本是更直接的方式,步骤如下:
- 在BizTalk映射器中添加一个Scripting Functoid,选择
Inline XSLT Call Template类型 - 把源的
<Transactions>节点连接到这个Scripting Functoid,再把Functoid连接到目标的<Transactions>节点 - 嵌入以下XSLT模板代码:
<xsl:template name="TransformTransactions"> <xsl:param name="TransactionsNode"/> <Transactions> <EntityType> <xsl:value-of select="$TransactionsNode/EntityType"/> </EntityType> <Events> <Properties> <!-- 处理ENT_SUB_TYP,为空则设为NOT_APP --> <ENT_SUB_TYP> <xsl:choose> <xsl:when test="$TransactionsNode/Events/Properties/ENT_SUB_TYP != ''"> <xsl:value-of select="$TransactionsNode/Events/Properties/ENT_SUB_TYP"/> </xsl:when> <xsl:otherwise>NOT_APP</xsl:otherwise> </xsl:choose> </ENT_SUB_TYP> <!-- 遍历所有MIF_ACT_PER节点,生成多个子节点 --> <xsl:for-each select="$TransactionsNode/Events/Properties/MIF_ACT_PER"> <MIF_ACT_PER> <xsl:value-of select="."/> </MIF_ACT_PER> </xsl:for-each> </Properties> </Events> </Transactions> </xsl:template>
这个模板会接收每个源<Transactions>节点作为参数,生成单个<Properties>节点,自动把所有<MIF_ACT_PER>合并进去,完美解决拆分问题。
用你提供的包含两个<MIF_ACT_PER>的源XML测试后,输出XML应该是:
<ns0:Masterdata xmlns:ns0="http://Masterdata"> <Transactions> <EntityType>CRD</EntityType> <Events> <Properties> <ENT_SUB_TYP>NOT_APP</ENT_SUB_TYP> <MIF_ACT_PER>3</MIF_ACT_PER> <MIF_ACT_PER>6</MIF_ACT_PER> </Properties> </Events> </Transactions> </ns0:Masterdata>
对应的JSON输出就会变成符合要求的结构:
{ "Transactions": [ { "EntityType": "CRD", "Events": [ { "Properties": [ { "ENT_SUB_TYP": [ "NOT_APP" ], "MIF_ACT_PER": [ "3", "6" ] } ] } ] } ] }
内容的提问来源于stack exchange,提问作者Emperor 2052

