如何在XSLT中实现正确迭代,从Workday XML生成指定格式输出
问题原因
- 循环层级错误:现有逻辑先创建单条
<Worker_Experience>记录,再在内部遍历所有<wd:Experiencia_profesional_group>节点,导致多个Skill_Reference_ID被塞到同一条记录的不同字段中,最终输出合并为一行。 - 全局变量上下文错误:你定义的
$HASHTAG是全局变量,上下文为XML根节点,无法正确获取循环内部单个技能组的Skill_Reference_ID值,判断逻辑完全失效。 - 字段定位错误:你在
<wd:Report_Data>模板层判断wd:ID_de_empleado的长度,但该节点实际是<wd:Report_Entry>的子节点,判断条件不会生效。
修正方案
调换循环层级:每遍历到一个<wd:Experiencia_profesional_group>节点,就单独生成一整条完整的输出记录,员工ID、公司ID、国家这类固定字段直接复用当前<wd:Report_Entry>下的公共值即可。
修改后的完整XSLT代码
<xsl:stylesheet xmlns:wd="urn:com.workday.report/INT0254_JDDATIO_039_Workday_to_Datio_Worker-Work_Experience_Outbound_RD" version="2.0" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xtt="urn:com.workday/xtt" xmlns:etv="urn:com.workday/etv"> <xsl:output method="xml" indent="yes"/> <xsl:variable name="Linefeed" select="'
'"/> <xsl:variable name="EMPTY" select="''"/> <xsl:template match="/"> <File xtt:separator="
"> <Header xtt:separator="," xtt:truncate="true" xtt:quotes="always"> <Title1>g_worker_id</Title1> <Title2>g_employee_work_experience_id</Title2> <Title3>g_internal_company_id</Title3> <Title4>g_country_id</Title4> </Header> <xsl:apply-templates select="wd:Report_Data"/> </File> </xsl:template> <xsl:template match="wd:Report_Data"> <Record xtt:separator="
" xtt:quotes="always" xtt:truncate="true"> <xsl:for-each select="wd:Report_Entry"> <!-- 提前存储当前员工的公共不变字段,循环技能组时直接复用 --> <xsl:variable name="employeeId" select="wd:ID_de_empleado"/> <xsl:variable name="companyId" select="wd:Empresa_group/wd:Reference_ID_Value"/> <xsl:variable name="countryCode" select="wd:location_group/wd:country/wd:ID[@wd:type='ISO_3166-1_Alpha-2_Code']"/> <!-- 仅处理员工ID长度符合要求的记录 --> <xsl:if test="string-length($employeeId) <= 11"> <!-- 循环每个技能组,每个技能组生成一条独立的输出记录 --> <xsl:for-each select="wd:Experiencia_profesional_group"> <xsl:variable name="skillId" select="wd:Skill_Reference_ID"/> <xsl:variable name="hashtagPart" select="substring-after($skillId, '#')"/> <xsl:if test="normalize-space($skillId) != ''"> <Worker_Experience xtt:separator="," xtt:quotes="always" xtt:truncate="true"> <!-- 员工ID --> <Employee_ID xtt:required="true" xtt:maxLength="11"> <xsl:value-of select="$employeeId"/> </Employee_ID> <!-- 技能ID逻辑判断 --> <xsl:choose> <xsl:when test="string-length($hashtagPart) > 3 or string-length($skillId) > 3"> <Work_experience_ID xtt:required="true" xtt:maxLength="3"> <xsl:value-of select="$EMPTY"/> </Work_experience_ID> <errormessage xtt:omit="true" xtt:severity="error" xtt:target="ID Experiencia" xtt:message="El registro supera los 3 caracteres - ID Experiencia"/> </xsl:when> <xsl:otherwise> <Work_experience_ID> <xsl:value-of select="$skillId"/> </Work_experience_ID> </xsl:otherwise> </xsl:choose> <!-- 公司ID逻辑判断 --> <xsl:choose> <xsl:when test="string-length($companyId) > 3"> <Company xtt:required="true" xtt:maxLength="3"> <xsl:value-of select="$EMPTY"/> </Company> <errormessage xtt:omit="true" xtt:severity="error" xtt:target="Compañia" xtt:message="El registro supera los 3 caracteres - ID Compañia"/> </xsl:when> <xsl:otherwise> <Company> <xsl:value-of select="$companyId"/> </Company> </xsl:otherwise> </xsl:choose> <!-- 国家代码 --> <Country xtt:required="true" xtt:maxLength="2"> <xsl:value-of select="$countryCode"/> </Country> </Worker_Experience> </xsl:if> </xsl:for-each> </xsl:if> </xsl:for-each> </Record> </xsl:template> </xsl:stylesheet>
修改后运行就会得到你预期的两条独立输出记录:
"00003500294","046","001","ES" "00003500294","125","001","ES"
内容的提问来源于stack exchange,提问作者Cristian
相关产品推荐
相关产品推荐

