Reputation: 59
I am trying to filter and organize through a list of people with their attachments. People can have multiple attachments that have been attached or modified at different times or no attachments at all. I only want one attachment per person. If the person has an attachment that contains the word resume I want the latest modified. If the person does not have an attachment with resume in the name which ever attachment was modified last. And if there isn't a resume we still want to include the person but leave those elements blank.
Currently I am trying to sort by FileLastModDate but that's not working.
<?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>
I am applying a sort to the group, but I'm not getting the right filename
<?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>
I should be getting the following:
<?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>
Instead I get the following result
<?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>
Upvotes: 0
Views: 48
Reputation: 70648
Here is a potentially more "elegant" solution, that involves performing a sort on the records first, with the ones with resume coming out first.
Try this 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>
If nothing else, it demonstrates the use of the xsl:perform-sort
if you haven't seen that before. And, as a bonus, shows an alternative way to do the case-insensitive check on the name, using matches
instead.
Upvotes: 1
Reputation: 29042
You can replace your
<xsl:variable name="FileName" select="field[@name='FileName']"/>
variable with a more complex one. The first xsl:when
is for the Resumes, the second for the other attachements, and the third for the rest - it could be omitted, but I put it there in case you want some result other than ''
.
<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>
Disclaimer: There may be other, more elegant, solutions.
To make the 'Resume' comparisons case-insensitive, you can use the upper-case(...)
function.
and then replace all the contains(.,'Resume')
with
contains(upper-case(.),'RESUME')
Upvotes: 1