Reputation: 11
I have aggregated 2 xml data sources (Report data and Qualification Equivalence Rules) into a root node and used XSLT 3.0 accumulator & map function. I am unable to get the accumulator map value returned in the output. The 'QER' and 'QCert' values are coming out blank. Not sure if it is a template issue. Any help is highly appreciated.
INPUT XML ->
<?xml version="1.0" encoding="utf-8"?>
<root>
<Qualifications>
<wd:Qualification_Equivalence_Rule xmlns:wd="urn:com.workday/bsvc"
xmlns:env="http://schemas.xmlsoap.org/soap/envelope/">
<wd:Qualification_Equivalence_Rule_Reference>
<wd:ID wd:type="WID">f67d472cae9501e32555411f04061766</wd:ID>
<wd:ID wd:type="Qualification_Equivalence_Rule">QUALIFICATION_EQUIVALENCE_RULE-6-411</wd:ID>
</wd:Qualification_Equivalence_Rule_Reference>
<wd:Qualification_Equivalence_Rule_Data>
<wd:ID>QUALIFICATION_EQUIVALENCE_RULE-6-411</wd:ID>
<wd:Qualification_Equivalence_Rule_Inactive>0</wd:Qualification_Equivalence_Rule_Inactive>
<wd:Job_Profile_Reference>
<wd:ID wd:type="WID">1117412e168001250ea7f14c41031293</wd:ID>
<wd:ID wd:type="Job_Profile_ID">51227</wd:ID>
</wd:Job_Profile_Reference>
<wd:Condition_Rule_Data>
<wd:Condition_Rule_ID>CONDITION_RULE-6-1097</wd:Condition_Rule_ID>
<wd:Rule_Description>51227</wd:Rule_Description>
<wd:Condition_Item_Data>
<wd:Order>a</wd:Order>
<wd:And_Or_Operator_Reference>
<wd:ID wd:type="WID">da4e1c34446c11de98360015c5e6daf6</wd:ID>
<wd:ID wd:type="And_Or_Operator_Name">And</wd:ID>
</wd:And_Or_Operator_Reference>
<wd:Relational_Operator_Reference>
<wd:ID wd:type="WID">d5227566446c11de98360015c5e6daf6</wd:ID>
<wd:ID wd:type="Relational_Operator_Name">any in the selection list</wd:ID>
</wd:Relational_Operator_Reference>
<wd:Condition_Entry_Option_Reference>
<wd:ID wd:type="WID">da59516c446c11de98360015c5e6daf6</wd:ID>
<wd:ID wd:type="Condition_Entry_Option_Name">Value specified in this filter</wd:ID>
</wd:Condition_Entry_Option_Reference>
<wd:Source_External_Field_Reference>
<wd:ID wd:type="WID">2da3447d0426100005f7c3e752840110</wd:ID>
</wd:Source_External_Field_Reference>
<wd:Target_Instance_Reference>
<wd:ID wd:type="WID">f67d472cae95016d99f7feeb7a05f065</wd:ID>
<wd:ID wd:type="Certification_ID">BCBA</wd:ID>
</wd:Target_Instance_Reference>
</wd:Condition_Item_Data>
</wd:Condition_Rule_Data>
</wd:Qualification_Equivalence_Rule_Data>
</wd:Qualification_Equivalence_Rule>
<wd:Qualification_Equivalence_Rule xmlns:wd="urn:com.workday/bsvc"
xmlns:env="http://schemas.xmlsoap.org/soap/envelope/">
<wd:Qualification_Equivalence_Rule_Reference>
<wd:ID wd:type="WID">f67d472cae95013dc439f7fc0306ba60</wd:ID>
<wd:ID wd:type="Qualification_Equivalence_Rule">QUALIFICATION_EQUIVALENCE_RULE-6-2</wd:ID>
</wd:Qualification_Equivalence_Rule_Reference>
<wd:Qualification_Equivalence_Rule_Data>
<wd:ID>QUALIFICATION_EQUIVALENCE_RULE-6-2</wd:ID>
<wd:Qualification_Equivalence_Rule_Inactive>0</wd:Qualification_Equivalence_Rule_Inactive>
<wd:Job_Profile_Reference>
<wd:ID wd:type="WID">1117412e168001d24f02c14c41030c92</wd:ID>
<wd:ID wd:type="Job_Profile_ID">48082</wd:ID>
</wd:Job_Profile_Reference>
<wd:Condition_Rule_Data>
<wd:Condition_Rule_ID>CONDITION_RULE-6-f67d472cae9501a42c52f7fc0306bb60</wd:Condition_Rule_ID>
<wd:Rule_Description>48082</wd:Rule_Description>
<wd:Condition_Item_Data>
<wd:Order>a</wd:Order>
<wd:And_Or_Operator_Reference>
<wd:ID wd:type="WID">da4e1c34446c11de98360015c5e6daf6</wd:ID>
<wd:ID wd:type="And_Or_Operator_Name">And</wd:ID>
</wd:And_Or_Operator_Reference>
<wd:Relational_Operator_Reference>
<wd:ID wd:type="WID">d5227566446c11de98360015c5e6daf6</wd:ID>
<wd:ID wd:type="Relational_Operator_Name">any in the selection list</wd:ID>
</wd:Relational_Operator_Reference>
<wd:Condition_Entry_Option_Reference>
<wd:ID wd:type="WID">da59516c446c11de98360015c5e6daf6</wd:ID>
<wd:ID wd:type="Condition_Entry_Option_Name">Value specified in this filter</wd:ID>
</wd:Condition_Entry_Option_Reference>
<wd:Source_External_Field_Reference>
<wd:ID wd:type="WID">2da3447d0426100005f7c3e752840110</wd:ID>
</wd:Source_External_Field_Reference>
<wd:Target_Instance_Reference>
<wd:ID wd:type="WID">f67d472cae9501f92ccd15ec7a053966</wd:ID>
<wd:ID wd:type="Certification_ID">CBAP</wd:ID>
</wd:Target_Instance_Reference>
<wd:Target_Instance_Reference>
<wd:ID wd:type="WID">f67d472cae9501f92ccd15ec7a053967</wd:ID>
<wd:ID wd:type="Certification_ID">PMI-PBA</wd:ID>
</wd:Target_Instance_Reference>
</wd:Condition_Item_Data>
</wd:Condition_Rule_Data>
</wd:Qualification_Equivalence_Rule_Data>
</wd:Qualification_Equivalence_Rule>
</Qualifications>
<wd:Report_Data xmlns:wd="urn:com.workday.report/Worker_Certs">
<wd:Report_Entry>
<wd:Worker wd:Descriptor="Tom Hanks">
<wd:ID wd:type="WID">b0d4df2a9611018f7b47c85f110d8230</wd:ID>
<wd:ID wd:type="Employee_ID">770077</wd:ID>
</wd:Worker>
<wd:Job_Profile wd:Descriptor="48082 - Business Analyst">
<wd:ID wd:type="WID">1117412e168001d24f02c14c41030c92</wd:ID>
<wd:ID wd:type="Job_Profile_ID">48082</wd:ID>
</wd:Job_Profile>
<wd:Certification wd:Descriptor="CBAP - Certified Business Analyst Professional">
<wd:ID wd:type="WID">b0d4df2a96110179f7d634a5310de855</wd:ID>
</wd:Certification>
<wd:Certification_-_Selected_group>
<wd:referenceID>CBAP</wd:referenceID>
</wd:Certification_-_Selected_group>
<wd:Cert_Number>2100</wd:Cert_Number>
<wd:Issuer>IIBA</wd:Issuer>
<wd:Expiration_Date>2023-12-31-08:00</wd:Expiration_Date>
</wd:Report_Entry>
<wd:Report_Entry>
<wd:Worker wd:Descriptor="Russel Crowe">
<wd:ID wd:type="WID">b0d4df2a961101bdb3b6ae7b120dd829</wd:ID>
<wd:ID wd:type="Employee_ID">77088</wd:ID>
</wd:Worker>
<wd:Job_Profile wd:Descriptor="51227 - Board Certified Behav Analyst">
<wd:ID wd:type="WID">1117412e168001250ea7f14c41031293</wd:ID>
<wd:ID wd:type="Job_Profile_ID">51227</wd:ID>
</wd:Job_Profile>
<wd:Certification wd:Descriptor="Board Certified Behavior Analyst - Behavior Analyst Certification Board">
<wd:ID wd:type="WID">e27b2aff960c01a0b7f176c5b201122a</wd:ID>
</wd:Certification>
<wd:Certification_-_Selected_group>
<wd:referenceID>BCBA</wd:referenceID>
</wd:Certification_-_Selected_group>
<wd:Cert_Number>1/11/8595</wd:Cert_Number>
<wd:Issuer>Behavior Analyst Certification Board</wd:Issuer>
<wd:Expiration_Date>2023-05-31-07:00</wd:Expiration_Date>
</wd:Report_Entry>
</wd:Report_Data>
</root>
XSLT
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:wd="urn:com.workday/bsvc"
xmlns:wd2="urn:com.workday.report/Worker_Certs"
xmlns:map="http://www.w3.org/2005/xpath-functions/map"
exclude-result-prefixes="xs">
<xsl:output method="xml" indent="yes"/>
<!-- Declare Accumulator to store the Job Profile ID from Web Service, this will be used to lookup Cert ID from the Web Service -->
<xsl:accumulator name="qjp.id" streamable="yes" as="xs:string" initial-value="''">
<xsl:accumulator-rule match="wd:Job_Profile_Reference/wd:ID[@wd:type='Job_Profile_ID']/text()" select="."/>
</xsl:accumulator>
<!-- Declare Accumulator with map to lookup CertID from Web Service -->
<xsl:accumulator name="map.cert" as="map(xs:string,xs:string)" initial-value="map{}" streamable="yes">
<xsl:accumulator-rule match="wd:Target_Instance_Reference/wd:ID[@wd:type='Certification_ID']/text()">
<xsl:sequence select="map:put($value, accumulator-after('qjp.id'), xs:string(.))"/>
</xsl:accumulator-rule>
</xsl:accumulator>
<xsl:mode streamable="yes" on-no-match="shallow-skip" use-accumulators="#all"/>
<xsl:mode streamable="no" name="in-memory"/>
<xsl:template match="/">
<root>
<xsl:apply-templates/>
</root>
</xsl:template>
<xsl:template match="wd2:Report_Entry">
<xsl:apply-templates select="copy-of()" mode="in-memory"/>
</xsl:template>
<!--
<xsl:template match="wd:Qualification_Equivalence_Rule_Data">
<xsl:apply-templates select="copy-of()" mode="in-memory"/>
</xsl:template>
-->
<xsl:template match="wd2:Report_Entry" mode="in-memory">
<xsl:variable name="vmap.cert" select="accumulator-after('map.cert')"/>
<xsl:variable name="v.empl_id" select="wd2:Worker/wd2:ID[@wd2:type='Employee_ID']" />
<xsl:variable name="v.jp_id" select="wd2:Job_Profile/wd2:ID[@wd2:type='Job_Profile_ID']" />
<xsl:variable name="v.cert_id" select="wd2:Cert_Number"/>
<xsl:variable name="v.Cref" select="wd2:Certification_-_Selected_group/wd2:referenceID"/>
<xsl:variable name="v.exp_dt" select="substring(wd2:Expiration_Date,1,10)"/>
<Worker_Cert>
<Emp_ID><xsl:value-of select="$v.empl_id"/></Emp_ID>
<Job_Profile_ID><xsl:value-of select="$v.jp_id"/></Job_Profile_ID>
<Cref><xsl:value-of select="$v.Cref"/></Cref>
<Cert_Number><xsl:value-of select="$v.cert_id"/></Cert_Number>
<Expiration_Dt><xsl:value-of select="$v.exp_dt"/></Expiration_Dt>
<QER>
<QCert><xsl:value-of select="$vmap.cert ($v.jp_id)"/></QCert>
</QER>
</Worker_Cert>
</xsl:template>
</xsl:stylesheet>
Final Expected Output ->
<?xml version="1.0" encoding="UTF-8"?>
<root xmlns:map="http://www.w3.org/2005/xpath-functions/map"
xmlns:wd="urn:com.workday/bsvc"
xmlns:wd2="urn:com.workday.report/Worker_Certs">
<Worker_Cert>
<Emp_ID>770077</Emp_ID>
<Job_Profile_ID>48082</Job_Profile_ID>
<Cref>CBAP</Cref>
<Cert_Number>2100</Cert_Number>
<Expiration_Dt>2023-12-31</Expiration_Dt>
<QCert>CBAP</QCert>
</Worker_Cert>
<Worker_Cert>
<Emp_ID>770088</Emp_ID>
<Job_Profile_ID>51227</Job_Profile_ID>
<Cref>BCBA</Cref>
<Cert_Number>2100</Cert_Number>
<Expiration_Dt>2023-05-31</Expiration_Dt>
<QCert>BCBA</QCert>
</Worker_Cert>
</root>
Upvotes: 0
Views: 415
Reputation: 167716
If you want to store more than one value related to a key in your map change
<xsl:accumulator name="map.cert" as="map(xs:string,xs:string)" initial-value="map{}" streamable="yes">
<xsl:accumulator-rule match="wd:Target_Instance_Reference/wd:ID[@wd:type='Certification_ID']/text()">
<xsl:sequence select="map:put($value, accumulator-after('qjp.id'), xs:string(.))"/>
</xsl:accumulator-rule>
</xsl:accumulator>
to
<xsl:accumulator name="map.cert" as="map(xs:string,xs:string+)" initial-value="map{}" streamable="yes">
<xsl:accumulator-rule match="wd:Target_Instance_Reference/wd:ID[@wd:type='Certification_ID']/text()">
<xsl:sequence select="if (map:contains($value, accumulator-after('qjp.id'))) then map:put($value, accumulator-after('qjp.id'), (map:get($value, accumulator-after('qjp.id')), string()) else map:put($value, accumulator-after('qjp.id'), string())"/>
</xsl:accumulator-rule>
</xsl:accumulator>
I am still not sure how you want to use that accumulator with the order of data in your sample in the question but the suggestion above at least should help to store a sequence of values.
Upvotes: 0