通过XSL组进行过滤和排序

时间:2019-02-06 21:07:10

标签: xml xslt

我正在尝试过滤和整理带有附件的人员列表。人们可以具有在不同时间被附加或修改的多个附件,或者根本没有附件。 我只想每人一个附件。如果此人的附件中包含“恢复”一词,则需要最新的修改。如果此人的姓名中没有带有简历的附件,则该附件最后被修改。而且,如果没有简历,我们仍然希望包括此人,但将这些元素留空。

当前,我正在尝试按FileLastModDate进行排序,但这不起作用。

    <?xml version="1.0" encoding="UTF-8"?>
    <ExportXML xmlns="http://www.taleo.com/ws/integration/toolkit/2005/07" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:ns1="http://www.taleo.com/ws/integration/toolkit/2005/07" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
        <record>
            <field name="FirstName">Olivia</field>
            <field name="LastName">Test</field>
            <field name="Number">1</field>
            <field name="FileName">Olivia Test 2017.pdf</field>
            <field name="FileLastModDate">2017-06-20T19:24:51-04:00</field>
        </record>
        <record>
            <field name="FirstName">Olivia</field>
            <field name="LastName">Tortolini</field>
            <field name="Number">1</field>
            <field name="FileName">Olivia Test 2018.pdf</field>
            <field name="FileLastModDate">2018-06-20T19:24:51-04:00</field>
        </record>
        <record>
            <field name="FirstName">Kevin</field>
            <field name="LastName">X</field>
            <field name="Number">2</field>
            <field name="FileName">cover letter 2018.docx</field>
            <field name="FileLastModDate">2018-10-04T13:32:30-04:00</field>
        </record>
        <record>
            <field name="FirstName">Kevin</field>
            <field name="LastName">X</field>
            <field name="Number">2</field>
            <field name="FileName">Resume 2018.docx</field>
            <field name="FileLastModDate">2018-09-04T13:32:30-04:00</field>
        </record>
        <record>
            <field name="FirstName">Kevin</field>
            <field name="LastName">X</field>
            <field name="Number">2</field>
            <field name="FileName">Resume 2017.docx</field>
            <field name="FileLastModDate">2017-12-26T15:47:54-05:00</field>
        </record>
        <record>
            <field name="FirstName">Michael</field>
            <field name="LastName">S</field>
            <field name="Number">3</field>
            <field name="FileName"></field>
            <field name="FileLastModDate"></field>
        </record>
    </ExportXML>

我正在对群组进行排序,但是没有得到正确的文件名

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
  xpath-default-namespace="http://www.taleo.com/ws/integration/toolkit/2005/07"  xmlns:ns="http://www.taleo.com/ws/integration/toolkit/2005/07"  xmlns:e="http://www.taleo.com/ws/tee800/2009/01" xmlns:fct="http://www.taleo.com/xsl_functions"  exclude-result-prefixes="e fct ns">
    <xsl:output indent="yes"/>
    <xsl:param name="OUTBOUND_FOLDER"/>
    <xsl:param name="NOW"/>
    <xsl:strip-space elements="*"/>
    <xsl:template match="/ExportXML">
        <Files>
            <xsl:for-each-group select="record" group-by="field[@name=('Number')]">
                <xsl:sort select="field[@name='FileLastModDate']"  order="descending"/>
                <xsl:variable name="FirstName" select="ns:field[@name='FirstName']"/>
                <xsl:variable name="LastName" select="ns:field[@name='LastName']"/>
                <xsl:variable name="LastModifiedDate" select="ns:field[@name='LastModifiedDate']"/>
                <xsl:variable name="Number" select="ns:field[@name='Number']"/>
                <xsl:variable name="FileName" select="field[@name='FileName']"/>
                    <file path="{$FileName}">
                        <FirstName>
                            <xsl:value-of select="$FirstName"/>
                        </FirstName>
                        <LastName>
                            <xsl:value-of select="$LastName"/>
                        </LastName>
                        <LastModifiedDate>
                            <xsl:value-of select="$LastModifiedDate"/>
                        </LastModifiedDate>
                        <Number>
                            <xsl:value-of select="$Number"/>
                        </Number>
                        <FileName>
                            <xsl:value-of select="$FileName"/>
                        </FileName>
                    </file>
            </xsl:for-each-group>      
        </Files>
    </xsl:template>
</xsl:stylesheet>

我应该得到以下信息:

<?xml version="1.0" encoding="UTF-8"?>
<Files>
   <file path="cover letter 2018.docx">
      <FirstName>Kevin</FirstName>
      <LastName>X</LastName>
      <LastModifiedDate/>
      <Number>2</Number>
      <FileName>Resume 2018.docx</FileName>
   </file>
   <file path="Olivia Test 2017.pdf">
      <FirstName>Olivia</FirstName>
      <LastName>Test</LastName>
      <LastModifiedDate/>
      <Number>1</Number>
      <FileName>Olivia Test 2018.pdf</FileName>
   </file>
   <file path="">
      <FirstName>Michael</FirstName>
      <LastName>S</LastName>
      <LastModifiedDate/>
      <Number>3</Number>
      <FileName/>
   </file>
</Files>

相反,我得到以下结果

<?xml version="1.0" encoding="UTF-8"?>
<Files>
   <file path="cover letter 2018.docx">
      <FirstName>Kevin</FirstName>
      <LastName>X</LastName>
      <LastModifiedDate/>
      <Number>2</Number>
      <FileName>cover letter 2018.docx</FileName>
   </file>
   <file path="Olivia Test 2017.pdf">
      <FirstName>Olivia</FirstName>
      <LastName>Test</LastName>
      <LastModifiedDate/>
      <Number>1</Number>
      <FileName>Olivia Test 2017.pdf</FileName>
   </file>
   <file path="">
      <FirstName>Michael</FirstName>
      <LastName>S</LastName>
      <LastModifiedDate/>
      <Number>3</Number>
      <FileName/>
   </file>
</Files>

2 个答案:

答案 0 :(得分:1)

您可以替换

<xsl:variable name="FileName" select="field[@name='FileName']"/>

更复杂的变量。第一个xsl:when用于简历,第二个用于其他附件,第三个用于其余附件-可以省略,但是如果您想要除''以外的其他结果,我可以将其放在此处。

<xsl:variable name="FileName">
    <xsl:choose>
        <xsl:when test="current-group()/field[@name='FileName'][contains(.,'Resume')]">
            <xsl:for-each select="current-group()/field[@name='FileName']">
                <xsl:sort select="contains(.,'Resume')" order="descending" />
                <xsl:if test="position() = 1">
                    <xsl:value-of select="."/>
                </xsl:if>
            </xsl:for-each>
        </xsl:when>
        <xsl:when test="current-group()/field[@name='FileName']">
            <xsl:for-each select="current-group()/field[@name='FileLastModDate']">
                <xsl:sort select="."  order="descending" />
                <xsl:if test="position() = 1">
                    <xsl:value-of select="../field[@name='FileName']"/>
                </xsl:if>
            </xsl:for-each>
        </xsl:when>
        <xsl:otherwise>
            <xsl:value-of select="''"/>
        </xsl:otherwise>
    </xsl:choose>
</xsl:variable>

免责声明:可能还有其他更优雅的解决方案。


要使“继续”比较不区分大小写,可以使用upper-case(...)函数。 然后将所有contains(.,'Resume')替换为

contains(upper-case(.),'RESUME')

答案 1 :(得分:1)

这是一个可能更“优雅”的解决方案,其中涉及首先对记录执行排序,而对简历进行排序则排在首位。

尝试使用此XSLT

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
  xpath-default-namespace="http://www.taleo.com/ws/integration/toolkit/2005/07"
  xmlns:ns="http://www.taleo.com/ws/integration/toolkit/2005/07"
  xmlns:e="http://www.taleo.com/ws/tee800/2009/01"
  xmlns:fct="http://www.taleo.com/xsl_functions"
  exclude-result-prefixes="e fct ns">

  <xsl:output indent="yes"/>
  <xsl:param name="OUTBOUND_FOLDER"/>
  <xsl:param name="NOW"/>
  <xsl:strip-space elements="*"/>

  <xsl:template match="/ExportXML">
    <xsl:variable name="records">
      <xsl:perform-sort select="record">
        <xsl:sort select="matches(field[@name='FileName'], 'Resume', 'i')" order="descending"/>
        <xsl:sort select="field[@name='FileLastModDate']" order="descending"/>
      </xsl:perform-sort>
    </xsl:variable>

    <Files>
      <xsl:for-each-group select="$records/record" group-by="field[@name='Number']">
        <xsl:sort select="field[@name='FileLastModDate']" order="descending"/>

        <xsl:variable name="FirstName" select="field[@name='FirstName']"/>
        <xsl:variable name="LastName" select="field[@name='LastName']"/>
        <xsl:variable name="LastModifiedDate" select="field[@name='FileLastModDate']"/>
        <xsl:variable name="Number" select="field[@name='Number']"/>
        <xsl:variable name="FileName" select="field[@name='FileName']"/>

        <file path="{$FileName}">
          <FirstName>
            <xsl:value-of select="$FirstName"/>
          </FirstName>
          <LastName>
            <xsl:value-of select="$LastName"/>
          </LastName>
          <LastModifiedDate>
            <xsl:value-of select="$LastModifiedDate"/>
          </LastModifiedDate>
          <Number>
            <xsl:value-of select="$Number"/>
          </Number>
          <FileName>
            <xsl:value-of select="$FileName"/>
          </FileName>
        </file>
      </xsl:for-each-group>      
    </Files>
  </xsl:template>
</xsl:stylesheet>

如果没有其他内容,它会演示xsl:perform-sort的用法(如果您以前从未见过的话)。而且,作为奖励,它显示了一种替代方法,可以使用matches来对名称进行不区分大小写的检查。