Azure Logic Apps XML转换:嵌套数组子值不匹配问题排查
问题:Azure Logic App中XSLT转换嵌套数组时子值匹配错误
我需要在Azure Logic App中将复杂JSON转换为预期的JSON结构。已将输入JSON转换为XML并创建XSLT文件执行转换,通过Logic App的XML Transform操作尝试转换为预期XML格式再转回JSON,但遇到嵌套数组无法正确获取对应子值的问题,子值随机取自父数组项。目前正在尝试使用xsl:apply-templates,寻求错误解决方法。
输入XML(JSON格式表示)
{"?xml": {"@version": "1.0", "@encoding": "utf-8"}, "Model": {"EmpDetails": {"Emp": [{"EmpId": "32370", "Job": {"EmpJob": {"JobId": "2121470-2"}}}, {"EmpId": "30413", "Job": {"EmpJob": {"JobId": "2121470"}}}, {"EmpId": "32372", "Job": {"EmpJob": {"JobId": "2121470-4"}}}, {"EmpId": "32371", "Job": {"EmpJob": {"JobId": "2121470-3"}}}]}}}
当前使用的XSL文件
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> <xsl:template match="/"> <model> <employmentDetails> <xsl:for-each select="/Model/EmpDetails"> <employments> <employmentId> <xsl:value-of select="Emp/EmpId"/> </employmentId> <xsl:for-each select="Job"> <jobs> <jobUserId> <xsl:value-of select="EmpJob/JobId"/> </jobUserId> </jobs> </xsl:for-each> </employments> </xsl:for-each> </employmentDetails> </model> </xsl:template> </xsl:stylesheet>
当前输出结果(jobUserId值随机匹配错误)
{"employmentDetails": {"employments": [{"EmpId": "32370", "jobs": {"jobUserId": "2121470-2"}}, {"EmpId": "30413", "jobs": {"jobUserId": "2121470-2"}}, {"EmpId": "32372", "jobs": {"jobUserId": "2121470-4"}}, {"EmpId": "32371", "jobs": {"jobUserId": "2121470-4"}}}]}}
预期输出结果
{"employmentDetails": {"employments": [{"EmpId": "32370", "jobs": {"jobUserId": "2121470-2"}}, {"EmpId": "30413", "jobs": {"jobUserId": "2121470"}}, {"EmpId": "32372", "jobs": {"jobUserId": "2121470-4"}}, {"EmpId": "32371", "jobs": {"jobUserId": "2121470-3"}}}]}}
错误原因与解决方法
错误原因
原XSLT的核心问题是遍历层级错误:
- 外层
xsl:for-each选择的是/Model/EmpDetails,而每个EmpDetails下包含多个Emp节点(员工数组) - 在
EmpDetails上下文里,select="Emp/EmpId"会返回所有员工的EmpId,select="Job"会返回所有员工的Job节点,导致后续循环时无法将每个员工与其自身的Job对应,出现随机匹配的情况
修正后的XSLT
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> <xsl:template match="/"> <model> <employmentDetails> <!-- 直接遍历每个Emp节点,确保每个员工作为独立上下文 --> <xsl:for-each select="/Model/EmpDetails/Emp"> <employments> <EmpId> <!-- 取当前Emp节点下的EmpId --> <xsl:value-of select="EmpId"/> </EmpId> <!-- 遍历当前Emp节点下的Job/EmpJob --> <xsl:for-each select="Job/EmpJob"> <jobs> <jobUserId> <xsl:value-of select="JobId"/> </jobUserId> </jobs> </xsl:for-each> </employments> </xsl:for-each> </employmentDetails> </model> </xsl:template> </xsl:stylesheet>
关键修改点
- 将外层循环从
/Model/EmpDetails改为/Model/EmpDetails/Emp,直接遍历每个员工节点,确保后续操作的上下文是单个员工 - 取
EmpId时,直接使用select="EmpId"(基于当前Emp节点上下文),无需再通过Emp/EmpId - 遍历Job时,基于当前Emp节点上下文选择
Job/EmpJob,确保取到的是当前员工对应的Job信息
这样修改后,每个员工的EmpId会和自身的JobId正确绑定,转换后即可得到预期的JSON结构。
内容的提问来源于stack exchange,提问作者Sneha
相关产品推荐
相关产品推荐

