如何在XSLT中按员工分组并填充指定类型的职责XML元素?
问题描述
输入XML
<DATA_DS> <G_2> <INFORMATION_TYPE>A</INFORMATION_TYPE> <EMPLOYEE_NUMBER>101</EMPLOYEE_NUMBER> <FIRST_NAME>X</FIRST_NAME> <LAST_NAME>Y</LAST_NAME> <RESPONSIBILITY>Responsibility 1</RESPONSIBILITY> </G_2> <G_2> <INFORMATION_TYPE>A</INFORMATION_TYPE> <EMPLOYEE_NUMBER>101</EMPLOYEE_NUMBER> <FIRST_NAME>X</FIRST_NAME> <LAST_NAME>Y</LAST_NAME> <RESPONSIBILITY>Responsibility 2</RESPONSIBILITY> </G_2> <G_2> <INFORMATION_TYPE>A</INFORMATION_TYPE> <EMPLOYEE_NUMBER>101</EMPLOYEE_NUMBER> <FIRST_NAME>X</FIRST_NAME> <LAST_NAME>Y</LAST_NAME> <RESPONSIBILITY>Responsibility 3</RESPONSIBILITY> </G_2> <G_2> <INFORMATION_TYPE>B</INFORMATION_TYPE> <EMPLOYEE_NUMBER>101</EMPLOYEE_NUMBER> <FIRST_NAME>X</FIRST_NAME> <LAST_NAME>Y</LAST_NAME> <RESPONSIBILITY>Responsibility 1</RESPONSIBILITY> </G_2> <G_2> <INFORMATION_TYPE>A</INFORMATION_TYPE> <EMPLOYEE_NUMBER>102</EMPLOYEE_NUMBER> <FIRST_NAME>M</FIRST_NAME> <LAST_NAME>N</LAST_NAME> <RESPONSIBILITY>Responsibility 1</RESPONSIBILITY> </G_2> <G_2> <INFORMATION_TYPE>A</INFORMATION_TYPE> <EMPLOYEE_NUMBER>102</EMPLOYEE_NUMBER> <FIRST_NAME>M</FIRST_NAME> <LAST_NAME>N</LAST_NAME> <RESPONSIBILITY>Responsibility 2</RESPONSIBILITY> </G_2> <G_2> <INFORMATION_TYPE>A</INFORMATION_TYPE> <EMPLOYEE_NUMBER>102</EMPLOYEE_NUMBER> <FIRST_NAME>M</FIRST_NAME> <LAST_NAME>N</LAST_NAME> <RESPONSIBILITY>Responsibility 2</RESPONSIBILITY> </G_2> </DATA_DS>
需求
为每位员工生成如下格式的输出XML:仅提取INFORMATION_TYPE为A的RESPONSIBILITY值,依次填充到RESPONSIBILITY1至RESPONSIBILITY6标签,不足6个的标签留空:
<EMP> <EMPLOYEE_NUMBER>101</EMPLOYEE_NUMBER> <FIRST_NAME>X</FIRST_NAME> <LAST_NAME>Y</LAST_NAME> <RESPONSIBILITY1>Responsibility 1</RESPONSIBILITY1> <RESPONSIBILITY2>Responsibility 2</RESPONSIBILITY2> <RESPONSIBILITY3>Responsibility 3</RESPONSIBILITY3> <RESPONSIBILITY4></RESPONSIBILITY4> <RESPONSIBILITY5></RESPONSIBILITY5> <RESPONSIBILITY6></RESPONSIBILITY6> </EMP> <EMP> <EMPLOYEE_NUMBER>102</EMPLOYEE_NUMBER> <FIRST_NAME>M</FIRST_NAME> <LAST_NAME>N</LAST_NAME> <RESPONSIBILITY1>Responsibility 1</RESPONSIBILITY1> <RESPONSIBILITY2>Responsibility 2</RESPONSIBILITY2> <RESPONSIBILITY3>Responsibility 2</RESPONSIBILITY3> <RESPONSIBILITY4></RESPONSIBILITY4> <RESPONSIBILITY5></RESPONSIBILITY5> <RESPONSIBILITY6></RESPONSIBILITY6> </EMP>
现有问题
已通过group-by按员工编号分组,但无法正确填充RESPONSIBILITY1至RESPONSIBILITY6标签,现有XSLT代码如下:
<EMPLOYEES> <xsl:for-each-group select="DATA_DS/G_2" group-by="EMPLOYEE_NUMBER"> <EMP> <EMPLOYEE_NUMBER> <xsl:value-of select="EMPLOYEE_NUMBER"/> </EMPLOYEE_NUMBER> <FIRST_NAME> <xsl:value-of select="FIRST_NAME"/> </FIRST_NAME> <LAST_NAME> <xsl:value-of select="LAST_NAME"/> </LAST_NAME> <xsl:for-each select="current-group() [INFORMATION_TYPE ='A']"> <RESPONSIBILITY1> <xsl:value-of select="RESPONSIBILITY[1]"/> </RESPONSIBILITY1> <RESPONSIBILITY2> <xsl:value-of select="RESPONSIBILITY[2]"/> </RESPONSIBILITY2> <RESPONSIBILITY3> <xsl:value-of select="RESPONSIBILITY[3]"/> </RESPONSIBILITY3> <RESPONSIBILITY4> <xsl:value-of select="RESPONSIBILITY[4]"/> </RESPONSIBILITY4> <RESPONSIBILITY5> <xsl:value-of select="RESPONSIBILITY[4]"/> </RESPONSIBILITY5> <RESPONSIBILITY6> <xsl:value-of select="RESPONSIBILITY[4]"/> </RESPONSIBILITY6> </xsl:for-each> </EMP> </xsl:for-each-group> </EMPLOYEES>
解决方案
现有代码的核心问题:
- 遍历
current-group() [INFORMATION_TYPE='A']时,每条记录都会生成全部6个RESPONSIBILITY标签,导致重复输出; - 每条
G_2下只有一个RESPONSIBILITY节点,用RESPONSIBILITY[2]这类索引取值永远为空。
正确实现代码如下:
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="xml" indent="yes"/> <xsl:template match="/"> <EMPLOYEES> <xsl:for-each-group select="DATA_DS/G_2" group-by="EMPLOYEE_NUMBER"> <EMP> <EMPLOYEE_NUMBER> <xsl:value-of select="EMPLOYEE_NUMBER"/> </EMPLOYEE_NUMBER> <FIRST_NAME> <xsl:value-of select="FIRST_NAME"/> </FIRST_NAME> <LAST_NAME> <xsl:value-of select="LAST_NAME"/> </LAST_NAME> <!-- 筛选当前员工所有INFORMATION_TYPE为A的RESPONSIBILITY节点 --> <xsl:variable name="resp-list" select="current-group()[INFORMATION_TYPE='A']/RESPONSIBILITY"/> <!-- 循环生成1-6号RESPONSIBILITY标签 --> <xsl:for-each select="1 to 6"> <xsl:element name="RESPONSIBILITY{.}"> <!-- 取对应位置的责任值,无对应节点则输出空 --> <xsl:value-of select="$resp-list[position()=current()]"/> </xsl:element> </xsl:for-each> </EMP> </xsl:for-each-group> </EMPLOYEES> </xsl:template> </xsl:stylesheet>
代码说明
- 筛选责任列表:用变量
$resp-list存储当前员工所有符合条件的RESPONSIBILITY节点集合; - 动态生成标签:通过
1 to 6循环,用xsl:element动态拼接RESPONSIBILITY1到RESPONSIBILITY6的标签名; - 对应取值:循环中用
$resp-list[position()=current()]匹配对应位置的责任值,若该位置无节点则自动生成空标签。
此代码能精准生成需求结构:每个员工仅生成一组6个RESPONSIBILITY标签,有效数据依次填充,不足部分留空。
内容的提问来源于stack exchange,提问作者user3532220
相关产品推荐
相关产品推荐

