XSLT从组中删除重复项

时间:2017-03-28 03:37:58

标签: xml xslt distinct-values xslt-grouping workday-api

员工可以是经理,人力资源合作伙伴,或两者兼而有之。他们可以是任何数量的成本中心的经理。他们可以成为任何数量的成本中心的人力资源合作伙伴。

如果我从每条记录中提取我需要的组合,我会收到重复项。员工A和员工B向同一成本中心的同一经理报告,因此返回两行。一个用于员工A,一个用于员工B.因为我不提取他们的员工ID(仅限经理和员工合作伙伴),所以它们显示为重复行。我目前正在使用'[not(。= preceding ::'来消除重复项,但检查整个文件,只允许管理员属于一个成本中心而不是多个。如何才能对组进行检查(如何)成本中心)而不是整个文件(所有成本中心)?

我已经尝试了两个复合键(managerID,成本中心ID)和(hr合作伙伴,成本中心ID),但在它变得混乱并且无法工作之前一直在努力。遗憾的是,我将此代码保存在其上。因此,如果这是我唯一的选择,我将不得不重写它并从那里进行故障排除。

输入XML示例:

<wd:Report_Data>
    <wd:Report_Entry>
        <wd:Sub_Employee_ID>123345678</wd:Sub_Employee_ID>
        <wd:Cost_Center_ID>20000003</wd:Cost_Center_ID>
        <wd:HR_Partner>
            <wd:ID wd:type="Employee_ID">81025060</wd:ID>
        </wd:HR_Partner>
        <wd:HR_Partner>
            <wd:ID wd:type="Employee_ID">81452340</wd:ID>
        </wd:HR_Partner>
        <wd:Manager>
            <wd:Employee_ID>81055097</wd:Employee_ID>
        </wd:Manager>
        <wd:Role_ID>2005</wd:Role_ID>
    </wd:Report_Entry>
    <wd:Report_Entry>
        <wd:Sub_Employee_ID>22345123</wd:Sub_Employee_ID>
        <wd:Cost_Center_ID>20000003</wd:Cost_Center_ID>
        <wd:HR_Partner>
            <wd:ID wd:type="Employee_ID">81025060</wd:ID>
        </wd:HR_Partner>
        <wd:Manager>
            <wd:Employee_ID>81055097</wd:Employee_ID>
        </wd:Manager>
        <wd:Role_ID>2005</wd:Role_ID>
    </wd:Report_Entry>
    <wd:Report_Entry>
        <wd:Sub_Employee_ID>33424567</wd:Sub_Employee_ID>
        <wd:Cost_Center_ID>20000003</wd:Cost_Center_ID>
        <wd:HR_Partner>
            <wd:ID wd:type="Employee_ID">81022549</wd:ID>
        </wd:HR_Partner>
        <wd:Manager>
            <wd:Employee_ID>12312312</wd:Employee_ID>
        </wd:Manager>
        <wd:Role_ID>2005</wd:Role_ID>
    </wd:Report_Entry>
    <wd:Report_Entry>
        <wd:Sub_Employee_ID>72390123</wd:Sub_Employee_ID>
        <wd:Cost_Center_ID>40000006</wd:Cost_Center_ID>
        <wd:HR_Partner>
            <wd:ID wd:type="Employee_ID">81025060</wd:ID>
        </wd:HR_Partner>
        <wd:Manager>
            <wd:Employee_ID>81055097</wd:Employee_ID>
        </wd:Manager>
        <wd:Role_ID>2005</wd:Role_ID>
    </wd:Report_Entry>
</wd:Report_Data>

期望的输出:

81055097;
20000003;
2005;
Manager

81025060;
20000003;
2005;
HR Partner

81452340
20000003;
2005;
HR Partner

12312312
20000003;
2005;
Manager

81022549;
20000003;
2005;
HR Partner

81055097;
40000006;
2005;
Manager

81025060;
40000006;
2005;
HR_Partner

当前xslt:

<xsl:template match="wd:Report_Data/wd:Report_Entry">
    <xsl:for-each-group select="." group-by="wd:Cost_Center_ID">

        <!-- Manager Line -->
        <!-- Filter Duplicates -->
        <xsl:sort select="wd:Manager/wd:Employee_ID"/>
        <xsl:if test="wd:Manager/wd:Employee_ID[not(.=preceding::wd:Manager/wd:Employee_ID)]">
            <xsl:value-of select="wd:Manager/wd:Employee_ID"/>;
            <xsl:value-of select="wd:Cost_Center_ID"/>;
            <xsl:value-of select="wd:Role_ID"/>;
            <xsl:value-of>Manager</xsl:value-of>
            <xsl:value-of select="$linefeed"/>
        </xsl:if>

        <!-- HR Partner Line -->
        <!-- Filter Duplicates -->
        <xsl:for-each select="../wd:HR_Partner/wd:ID[@wd:type='Employee_ID']">
            <xsl:if test=".[not(.=preceding::wd:HR_Partner/wd:ID[@wd:type='Employee_ID'])]">
                <xsl:value-of select="wd:ID[@wd:type='Employee_ID']"/>;
                <xsl:value-of select="../wd:Cost_Center_ID"/>;
                <xsl:value-of select="../wd:Role_ID"/>;
                <xsl:value-of>HR Partner</xsl:value-of>
                <xsl:value-of select="$linefeed"/>
            </xsl:if>
        </xsl:for-each> 
    </xsl:for-each-group>
</xsl:template>

1 个答案:

答案 0 :(得分:0)

尝试下面给出的解决方案:

<?xml version="1.0" encoding="UTF-8" ?>
<xsl:transform version="2.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:wd="http://dummy.com"
  xpath-default-namespace="http://dummy.com"
  exclude-result-prefixes="#all">
  <xsl:output method="text" encoding="UTF-8" indent="yes" />
  <xsl:strip-space elements="*"/>

  <xsl:key name="Partners" match="//HR_Partner"
    use="concat(../Cost_Center_ID, '/', ID)"/>
  <xsl:key name="Managers" match="//Manager"
    use="concat(../Cost_Center_ID, '/', Employee_ID)"/>
  <xsl:variable name="lf" select="'&#xA;'"/>

  <xsl:template match="Report_Data">
    <xsl:for-each-group select="Report_Entry" group-by="Cost_Center_ID">
      <xsl:for-each select="current-group()">
        <xsl:sort select="Manager/Employee_ID"/>
        <xsl:for-each select="Manager">
          <xsl:variable name="kk" select="concat(../Cost_Center_ID, '/', Employee_ID)"/>
          <xsl:if test="generate-id()=generate-id(key('Managers', $kk)[1])">
            <xsl:value-of select="Employee_ID"/>
            <xsl:text>; </xsl:text>
            <xsl:value-of select="../Cost_Center_ID"/>
            <xsl:text>; </xsl:text>
            <xsl:value-of select="../Role_ID"/>
            <xsl:text>; Manager;</xsl:text>
            <xsl:value-of select="$lf"/>
          </xsl:if>
        </xsl:for-each>
        <xsl:for-each select="HR_Partner">
          <xsl:variable name="kk" select="concat(../Cost_Center_ID, '/', ID)"/>
          <xsl:if test="generate-id()=generate-id(key('Partners', $kk)[1])">
            <xsl:value-of select="ID"/>
            <xsl:text>; </xsl:text>
            <xsl:value-of select="../Cost_Center_ID"/>
            <xsl:text>; </xsl:text>
            <xsl:value-of select="../Role_ID"/>
            <xsl:text>; HR Partner;</xsl:text>
            <xsl:value-of select="$lf"/>
          </xsl:if>
        </xsl:for-each>
      </xsl:for-each>
    </xsl:for-each-group>
  </xsl:template>
</xsl:transform>

我使用在线XSLT验证程序对其进行了测试,输入XML如下所示:

<?xml version="1.0" encoding="UTF-8"?>
<wd:main xmlns:wd="http://dummy.com">
  <wd:Report_Data>
  <!-- Here your Report_Entry records -->
  </wd:Report_Data>
</wd:main>

请注意,排序顺序与您想要的输出不同,原因是 应用分类。