XSLT:转换 XML 使用组、重复检查和排序

XSLT: Transform XML Using Group, Duplicate Check and Sort

我现在有以下问题陈述。我将拥有以下 XML 文件,如下所示:

    <?xml version="1.0" encoding="UTF-8"?>
        <EmpD>
          <PR>
            <RType>02</RType>
            <Emp>888</Emp>
          </PR>
          <PR>
            <RType>02</RType>
            <Emp>889</Emp>
          </PR>
          <JR>
            <RType>01</RType>
            <Emp>888</Emp>
            <Type>C</Type>
            <EDate>2020-05-01</EDate>
            <HR>1210148900</HR>
            <JobC>Test</JobC>
          </JR> 
          <JR>
            <RType>01</RType>
            <Emp>888</Emp>
            <Type>NC</Type>
            <EDate>2020-05-01</EDate>
            <HR>1210148900</HR>
            <JobC>Test</JobC>
          </JR> 
          <JR>
            <RType>01</RType>
            <Emp>888</Emp>
            <Type>C</Type>
            <EDate>2020-05-02</EDate>
            <HR>1210148900</HR>
            <JobC>Test</JobC>
          </JR>
          <JR>
            <RType>01</RType>
            <Emp>889</Emp>
            <Type>C</Type>
            <EDate>2020-05-01</EDate>
            <HR>1210148900</HR>
            <JobC>Test</JobC>
          </JR> 
          <JR>
            <RType>01</RType>
            <Emp>889</Emp>
            <Type>NC</Type>
            <EDate>2020-05-01</EDate>
            <HR>1210148900</HR>
            <JobC>Test</JobC>
          </JR> 
          <JR>
            <RType>01</RType>
            <Emp>889</Emp>
            <Type>NC</Type>
            <EDate>2020-05-02</EDate>
            <HR>1210148900</HR>
            <JobC>Test</JobC>
          </JR>  
        </EmpD>        
  1. 所以,基本上这里的JR节点可以根据Emp和EDate进行复制。是否有可能根据 Emp 和 EDate 的组合检查重复项,然后删除它们?

  2. 我的最终输出 XML 应该如下所示,这意味着它应该按 Emp(对于 PR 和 JR)以及 EDate 排序。

     <?xml version="1.0" encoding="UTF-8"?>
     <EmpD>
       <PR>
         <RType>02</RType>
         <Emp>888</Emp>
       </PR>
       <JR>
         <RType>01</RType>
         <Emp>888</Emp>
         <EDate>2020-05-01</EffectiveDate>
         <HR>1210148900</HR>
         <JobC>Test</JobC>
       </JR>
       <JR>
         <RType>01</RType>
         <Emp>888</Emp>
         <EDate>2020-05-02</EffectiveDate>
         <HR>1210148900</HR>
         <JobC>Test</JobC>
       </JR>
       <JR>
         <RType>01</RType>
         <Emp>889</Emp>
         <EDate>2020-05-01</EffectiveDate>
         <HR>1210148900</HR>
         <JobC>Test</JobC>
       </JR> 
       <PR>
         <RType>02</RType>
         <Emp>889</Emp>
       </PR>
       <JR>
         <RType>01</RType>
         <Emp>889</Emp>
         <EDate>2020-05-01</EffectiveDate>
         <HR>1210148900</HR>
         <JobC>Test</JobC>
       </JR>
       <JR>
         <RType>01</RType>
         <Emp>889</Emp>
         <EDate>2020-05-02</EffectiveDate>
         <HR>1210148900</HR>
         <JobC>Test</JobC>
       </JR>  
     <EmpD>
    
  3. 此外,类型字段很重要。我们只需要考虑Type值为“C”的地方。

  4. 我最终需要创建一个 CSV 类型的内容。我们可以从这里生成吗?或者说,我需要先生成一个XML,然后再转换成CSV?

您可以使用 XSLT 3 中的复合键来消除重复项,使用 for-each-groupkey 函数:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    exclude-result-prefixes="#all"
    version="3.0">

  <xsl:strip-space elements="*"/>
  <xsl:output indent="yes"/>
    
  <xsl:key name="dups" match="JR" composite="yes" use="Emp, EDate"/>

  <xsl:mode on-no-match="shallow-copy"/>
  
  <xsl:template match="EmpD">
      <xsl:copy>
          <xsl:apply-templates select="*">
              <xsl:sort select="Emp"/>
          </xsl:apply-templates>
      </xsl:copy>
  </xsl:template>
  
  <xsl:template match="JR[not(. is key('dups', (Emp, EDate))[1])]"/>
  
</xsl:stylesheet>

https://xsltfiddle.liberty-development.net/jxDjimB