问题
I have a fairly large (270mb) XML file that I need to group, sort, and run multiple transforms on.
Input XML:
<!-- language: lang-xml -->
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<EligibilityRecords xmlns="http://Eligibility_LSDD">
<Eligibility_Detail_Record xmlns="">
<PT_PARTICIPANT_FILE_IMP_ID></PT_PARTICIPANT_FILE_IMP_ID>
<PT_LST_NM>VALLE</PT_LST_NM>
<PT_FRST_NM>FRANKIE</PT_FRST_NM>
<EN_PLAN_NAME>Health Reimbursement Arrangement</EN_PLAN_NAME>
<EN_MBRSHP_EFF_STRT_DT>01012017</EN_MBRSHP_EFF_STRT_DT>
<EN_MBRSHP_EFF_END_DT></EN_MBRSHP_EFF_END_DT>
<EN_PLAN_YEAR_STRT_DT>01012017</EN_PLAN_YEAR_STRT_DT>
<DP_PARTICIPANT_FILE_IMP_ID></DP_PARTICIPANT_FILE_IMP_ID>
<DP_DEPENDENT_FILE_IMP_ID></DP_DEPENDENT_FILE_IMP_ID>
<DP_RELATIONSHIP></DP_RELATIONSHIP>
</Eligibility_Detail_Record>
<Eligibility_Detail_Record xmlns="">
<PT_PARTICIPANT_FILE_IMP_ID>123456</PT_PARTICIPANT_FILE_IMP_ID>
<PT_LST_NM>BULLOCK</PT_LST_NM>
<PT_FRST_NM>SANDRA</PT_FRST_NM>
<EN_PLAN_NAME></EN_PLAN_NAME>
<EN_MBRSHP_EFF_STRT_DT>01012017</EN_MBRSHP_EFF_STRT_DT>
<EN_MBRSHP_EFF_END_DT></EN_MBRSHP_EFF_END_DT>
<EN_PLAN_YEAR_STRT_DT>01012017</EN_PLAN_YEAR_STRT_DT>
<DP_PARTICIPANT_FILE_IMP_ID></DP_PARTICIPANT_FILE_IMP_ID>
<DP_DEPENDENT_FILE_IMP_ID></DP_DEPENDENT_FILE_IMP_ID>
<DP_RELATIONSHIP></DP_RELATIONSHIP>
</Eligibility_Detail_Record>
<Eligibility_Detail_Record xmlns="">
<PT_PARTICIPANT_FILE_IMP_ID>553739837</PT_PARTICIPANT_FILE_IMP_ID>
<PT_LST_NM>DOE</PT_LST_NM>
<PT_FRST_NM>JANE</PT_FRST_NM>
<EN_PLAN_NAME>Health Reimbursement Arrangement</EN_PLAN_NAME>
<EN_MBRSHP_EFF_STRT_DT>01012017</EN_MBRSHP_EFF_STRT_DT>
<EN_MBRSHP_EFF_END_DT></EN_MBRSHP_EFF_END_DT>
<EN_PLAN_YEAR_STRT_DT>01012017</EN_PLAN_YEAR_STRT_DT>
<DP_PARTICIPANT_FILE_IMP_ID></DP_PARTICIPANT_FILE_IMP_ID>
<DP_DEPENDENT_FILE_IMP_ID></DP_DEPENDENT_FILE_IMP_ID>
<DP_RELATIONSHIP></DP_RELATIONSHIP>
</Eligibility_Detail_Record>
<Eligibility_Detail_Record xmlns="">
<PT_PARTICIPANT_FILE_IMP_ID>610051908</PT_PARTICIPANT_FILE_IMP_ID>
<PT_LST_NM>JACKSON</PT_LST_NM>
<PT_FRST_NM>MICHAEL</PT_FRST_NM>
<EN_PLAN_NAME>Health Reimbursement Arrangement</EN_PLAN_NAME>
<EN_MBRSHP_EFF_STRT_DT>01012017</EN_MBRSHP_EFF_STRT_DT>
<EN_MBRSHP_EFF_END_DT></EN_MBRSHP_EFF_END_DT>
<EN_PLAN_YEAR_STRT_DT>01012017</EN_PLAN_YEAR_STRT_DT>
<DP_PARTICIPANT_FILE_IMP_ID>610051908</DP_PARTICIPANT_FILE_IMP_ID>
<DP_DEPENDENT_FILE_IMP_ID>NC110015202761</DP_DEPENDENT_FILE_IMP_ID>
<DP_RELATIONSHIP>Spouse</DP_RELATIONSHIP>
<DP_LST_NM>JACKSON</DP_LST_NM>
<DP_FRST_NM>MELISSA</DP_FRST_NM>
</Eligibility_Detail_Record>
<Eligibility_Detail_Record xmlns="">
<PT_PARTICIPANT_FILE_IMP_ID>561859010</PT_PARTICIPANT_FILE_IMP_ID>
<PT_LST_NM>MCLEOD</PT_LST_NM>
<PT_FRST_NM>CONOR</PT_FRST_NM>
<EN_PLAN_NAME>Health Reimbursement Arrangement</EN_PLAN_NAME>
<EN_MBRSHP_EFF_STRT_DT>01012016</EN_MBRSHP_EFF_STRT_DT>
<EN_MBRSHP_EFF_END_DT></EN_MBRSHP_EFF_END_DT>
<EN_PLAN_YEAR_STRT_DT>01012016</EN_PLAN_YEAR_STRT_DT>
<DP_PARTICIPANT_FILE_IMP_ID>561859010</DP_PARTICIPANT_FILE_IMP_ID>
<DP_DEPENDENT_FILE_IMP_ID>SC000018241906</DP_DEPENDENT_FILE_IMP_ID>
<DP_RELATIONSHIP>Dependent</DP_RELATIONSHIP>
<DP_LST_NM>MCLEOD</DP_LST_NM>
<DP_FRST_NM>DUNCAN</DP_FRST_NM>
</Eligibility_Detail_Record>
<Eligibility_Detail_Record xmlns="">
<PT_PARTICIPANT_FILE_IMP_ID>573794953</PT_PARTICIPANT_FILE_IMP_ID>
<PT_LST_NM>GABRIEL</PT_LST_NM>
<PT_FRST_NM>PETER</PT_FRST_NM>
<EN_PLAN_NAME>Health Reimbursement Arrangement</EN_PLAN_NAME>
<EN_MBRSHP_EFF_STRT_DT>01012016</EN_MBRSHP_EFF_STRT_DT>
<EN_MBRSHP_EFF_END_DT></EN_MBRSHP_EFF_END_DT>
<EN_PLAN_YEAR_STRT_DT>01012016</EN_PLAN_YEAR_STRT_DT>
<DP_PARTICIPANT_FILE_IMP_ID></DP_PARTICIPANT_FILE_IMP_ID>
<DP_DEPENDENT_FILE_IMP_ID></DP_DEPENDENT_FILE_IMP_ID>
<DP_RELATIONSHIP></DP_RELATIONSHIP>
</Eligibility_Detail_Record>
<Eligibility_Detail_Record xmlns="">
<PT_PARTICIPANT_FILE_IMP_ID>553739837</PT_PARTICIPANT_FILE_IMP_ID>
<PT_LST_NM>DOE</PT_LST_NM>
<PT_FRST_NM>JANE</PT_FRST_NM>
<EN_PLAN_NAME>Health Reimbursement Arrangement</EN_PLAN_NAME>
<EN_MBRSHP_EFF_STRT_DT>01012016</EN_MBRSHP_EFF_STRT_DT>
<EN_MBRSHP_EFF_END_DT></EN_MBRSHP_EFF_END_DT>
<EN_PLAN_YEAR_STRT_DT>01012016</EN_PLAN_YEAR_STRT_DT>
<DP_PARTICIPANT_FILE_IMP_ID>553739837</DP_PARTICIPANT_FILE_IMP_ID>
<DP_DEPENDENT_FILE_IMP_ID>NC110012077673</DP_DEPENDENT_FILE_IMP_ID>
<DP_RELATIONSHIP>Spouse</DP_RELATIONSHIP>
<DP_LST_NM>DOE</DP_LST_NM>
<DP_FRST_NM>JOHN</DP_FRST_NM>
</Eligibility_Detail_Record>
<Eligibility_Detail_Record xmlns="">
<PT_PARTICIPANT_FILE_IMP_ID>553739837</PT_PARTICIPANT_FILE_IMP_ID>
<PT_LST_NM>DOE</PT_LST_NM>
<PT_FRST_NM>JANE</PT_FRST_NM>
<EN_PLAN_NAME>Health Reimbursement Arrangement</EN_PLAN_NAME>
<EN_MBRSHP_EFF_STRT_DT>01012016</EN_MBRSHP_EFF_STRT_DT>
<EN_MBRSHP_EFF_END_DT></EN_MBRSHP_EFF_END_DT>
<EN_PLAN_YEAR_STRT_DT>01012016</EN_PLAN_YEAR_STRT_DT>
<DP_PARTICIPANT_FILE_IMP_ID>553739837</DP_PARTICIPANT_FILE_IMP_ID>
<DP_DEPENDENT_FILE_IMP_ID>NC110012077680</DP_DEPENDENT_FILE_IMP_ID>
<DP_RELATIONSHIP>Dependent</DP_RELATIONSHIP>
<DP_LST_NM>DOE</DP_LST_NM>
<DP_FRST_NM>JIMMY</DP_FRST_NM>
</Eligibility_Detail_Record>
<Eligibility_Detail_Record xmlns="">
<PT_PARTICIPANT_FILE_IMP_ID>553739837</PT_PARTICIPANT_FILE_IMP_ID>
<PT_LST_NM>DOE</PT_LST_NM>
<PT_FRST_NM>JANE</PT_FRST_NM>
<EN_PLAN_NAME>Health Reimbursement Arrangement</EN_PLAN_NAME>
<EN_MBRSHP_EFF_STRT_DT>01012016</EN_MBRSHP_EFF_STRT_DT>
<EN_MBRSHP_EFF_END_DT></EN_MBRSHP_EFF_END_DT>
<EN_PLAN_YEAR_STRT_DT>01012016</EN_PLAN_YEAR_STRT_DT>
<DP_PARTICIPANT_FILE_IMP_ID>553739837</DP_PARTICIPANT_FILE_IMP_ID>
<DP_DEPENDENT_FILE_IMP_ID>NC110012077681</DP_DEPENDENT_FILE_IMP_ID>
<DP_RELATIONSHIP>Dependent</DP_RELATIONSHIP>
<DP_LST_NM>DOE</DP_LST_NM>
<DP_FRST_NM>JESSICA</DP_FRST_NM>
</Eligibility_Detail_Record>
</EligibilityRecords>
I have the following requirements:
- Strip all Eligibility_Detail_Records that have a blank PT_PARTICIPANT_FILE_IMP_ID AND The EN_PLAN_NAME node is not "Health Reimbursement Arrangement" or "Health Savings Account"
- Create a new Dependent_Record that is a child record of Eligibility_Detail_Record for each DP_PARTICIPANT_FILE_IMP_ID that matches a PT_PARTICIPANT_FILE_IMP_ID
- Add an EN_PLAN_TYPE field for each Record that has an EN_PLAN_NAME of "Health Reimbursement Arrangement" that reads:
- "Ind" if no dependents are found
- "IndSpouse" if one and only one dependent that has DP_RELATIONSHIP of Spouse
- "IndChild" if one and only one dependent that has DP_RELATIONSHIP of Dependent
- "Family" if more than one dependent
- Add an EN_HDHP_COVERAGE_LEVEL field for each Record that has en EN_PLAN_NAME of "Health Savings Account" that reads:
- "Ind" if no dependents are found
- "Family" if one or more dependents are found
Expected XML output:
<!-- language: lang-xml -->
<?xml version="1.0" encoding="UTF-8"?>
<EligibilityRecords xmlns="http://Eligibility_LSDD">
<Eligibility_Detail_Record xmlns="">
<PT_PARTICIPANT_FILE_IMP_ID>553739837</PT_PARTICIPANT_FILE_IMP_ID>
<PT_LST_NM>DOE</PT_LST_NM>
<PT_FRST_NM>JANE</PT_FRST_NM>
<EN_PLAN_NAME>Health Reimbursement Arrangement</EN_PLAN_NAME>
<EN_PLAN_TYPE>Family</EN_PLAN_TYPE>
<EN_MBRSHP_EFF_STRT_DT>01012017</EN_MBRSHP_EFF_STRT_DT>
<EN_MBRSHP_EFF_END_DT></EN_MBRSHP_EFF_END_DT>
<EN_PLAN_YEAR_STRT_DT>01012017</EN_PLAN_YEAR_STRT_DT>
<Dependent_Record>
<DP_PARTICIPANT_FILE_IMP_ID>553739837</DP_PARTICIPANT_FILE_IMP_ID>
<DP_DEPENDENT_FILE_IMP_ID>NC110012077673</DP_DEPENDENT_FILE_IMP_ID>
<DP_RELATIONSHIP>Spouse</DP_RELATIONSHIP>
<DP_LST_NM>DOE</DP_LST_NM>
<DP_FRST_NM>JOHN</DP_FRST_NM>
</Dependent_Record>
<Dependent_Record>
<DP_PARTICIPANT_FILE_IMP_ID>553739837</DP_PARTICIPANT_FILE_IMP_ID>
<DP_DEPENDENT_FILE_IMP_ID>NC110012077680</DP_DEPENDENT_FILE_IMP_ID>
<DP_RELATIONSHIP>Dependent</DP_RELATIONSHIP>
<DP_LST_NM>DOE</DP_LST_NM>
<DP_FRST_NM>JIMMY</DP_FRST_NM>
</Dependent_Record>
<Dependent_Record>
<DP_PARTICIPANT_FILE_IMP_ID>553739837</DP_PARTICIPANT_FILE_IMP_ID>
<DP_DEPENDENT_FILE_IMP_ID>NC110012077681</DP_DEPENDENT_FILE_IMP_ID>
<DP_RELATIONSHIP>Dependent</DP_RELATIONSHIP>
<DP_LST_NM>DOE</DP_LST_NM>
<DP_FRST_NM>JESSICA</DP_FRST_NM>
</Dependent_Record>
</Eligibility_Detail_Record>
<Eligibility_Detail_Record xmlns="">
<PT_PARTICIPANT_FILE_IMP_ID>610051908</PT_PARTICIPANT_FILE_IMP_ID>
<PT_LST_NM>JACKSON</PT_LST_NM>
<PT_FRST_NM>MICHAEL</PT_FRST_NM>
<EN_PLAN_NAME>Health Reimbursement Arrangement</EN_PLAN_NAME>
<EN_PLAN_TYPE>IndSpouse</EN_PLAN_TYPE>
<EN_MBRSHP_EFF_STRT_DT>01012017</EN_MBRSHP_EFF_STRT_DT>
<EN_MBRSHP_EFF_END_DT></EN_MBRSHP_EFF_END_DT>
<EN_PLAN_YEAR_STRT_DT>01012017</EN_PLAN_YEAR_STRT_DT>
<Dependent_Record>
<DP_PARTICIPANT_FILE_IMP_ID>610051908</DP_PARTICIPANT_FILE_IMP_ID>
<DP_DEPENDENT_FILE_IMP_ID>NC110015202761</DP_DEPENDENT_FILE_IMP_ID>
<DP_RELATIONSHIP>Spouse</DP_RELATIONSHIP>
<DP_LST_NM>JACKSON</DP_LST_NM>
<DP_FRST_NM>MELISSA</DP_FRST_NM>
</Dependent_Record>
</Eligibility_Detail_Record>
<Eligibility_Detail_Record xmlns="">
<PT_PARTICIPANT_FILE_IMP_ID>561859010</PT_PARTICIPANT_FILE_IMP_ID>
<PT_LST_NM>MCLEOD</PT_LST_NM>
<PT_FRST_NM>CONOR</PT_FRST_NM>
<EN_PLAN_NAME>Health Reimbursement Arrangement</EN_PLAN_NAME>
<EN_PLAN_TYPE>IndChild</EN_PLAN_TYPE>
<EN_MBRSHP_EFF_STRT_DT>01012016</EN_MBRSHP_EFF_STRT_DT>
<EN_MBRSHP_EFF_END_DT></EN_MBRSHP_EFF_END_DT>
<EN_PLAN_YEAR_STRT_DT>01012016</EN_PLAN_YEAR_STRT_DT>
<Dependent_Record>
<DP_PARTICIPANT_FILE_IMP_ID>561859010</DP_PARTICIPANT_FILE_IMP_ID>
<DP_DEPENDENT_FILE_IMP_ID>SC000018241906</DP_DEPENDENT_FILE_IMP_ID>
<DP_RELATIONSHIP>Dependent</DP_RELATIONSHIP>
<DP_LST_NM>MCLEOD</DP_LST_NM>
<DP_FRST_NM>DUNCAN</DP_FRST_NM>
</Dependent_Record>
</Eligibility_Detail_Record>
<Eligibility_Detail_Record xmlns="">
<PT_PARTICIPANT_FILE_IMP_ID>573794953</PT_PARTICIPANT_FILE_IMP_ID>
<PT_LST_NM>GABRIEL</PT_LST_NM>
<PT_FRST_NM>PETER</PT_FRST_NM>
<EN_PLAN_NAME>Health Reimbursement Arrangement</EN_PLAN_NAME>
<EN_MBRSHP_EFF_STRT_DT>01012016</EN_MBRSHP_EFF_STRT_DT>
<EN_MBRSHP_EFF_END_DT></EN_MBRSHP_EFF_END_DT>
<EN_PLAN_YEAR_STRT_DT>01012016</EN_PLAN_YEAR_STRT_DT>
<EN_PLAN_TYPE>Ind</EN_PLAN_TYPE>
</Eligibility_Detail_Record>
<Eligibility_Detail_Record xmlns="">
<PT_PARTICIPANT_FILE_IMP_ID>561859457</PT_PARTICIPANT_FILE_IMP_ID>
<PT_LST_NM>BUGLE</PT_LST_NM>
<PT_FRST_NM>MAN</PT_FRST_NM>
<EN_PLAN_NAME>Health Savings Account</EN_PLAN_NAME>
<EN_HDHP_COVERAGE_LEVEL>Family</EN_HDHP_COVERAGE_LEVEL>
<EN_MBRSHP_EFF_STRT_DT>01012016</EN_MBRSHP_EFF_STRT_DT>
<EN_MBRSHP_EFF_END_DT></EN_MBRSHP_EFF_END_DT>
<EN_PLAN_YEAR_STRT_DT>01012016</EN_PLAN_YEAR_STRT_DT>
<Dependent_Record>
<DP_PARTICIPANT_FILE_IMP_ID>561859457</DP_PARTICIPANT_FILE_IMP_ID>
<DP_DEPENDENT_FILE_IMP_ID>SC000018241906</DP_DEPENDENT_FILE_IMP_ID>
<DP_RELATIONSHIP>Dependent</DP_RELATIONSHIP>
<DP_LST_NM>BUGLE</DP_LST_NM>
<DP_FRST_NM>BOY</DP_FRST_NM>
</Dependent_Record>
</Eligibility_Detail_Record>
</EligibilityRecords>
XSLT:
<!-- language: lang-xml -->
<?xml version="1.0" encoding="utf-16"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt" xmlns:var="http://schemas.microsoft.com/BizTalk/2003/var" exclude-result-prefixes="msxsl var" version="1.0" xmlns:ns0="http://Eligibility_LSDD" xmlns:set="http://exslt.org/sets">
<xsl:output omit-xml-declaration="yes" method="xml" version="1.0" />
<xsl:key name="ParticipantGroup" match="Eligibility_Detail_Record" use="PT_PARTICIPANT_FILE_IMP_ID" />
<xsl:key name="DependentSearch" match="Eligibility_Detail_Record" use="DP_PARTICIPANT_FILE_IMP_ID" />
<xsl:template match="/">
<xsl:apply-templates select="/ns0:EligibilityRecords" />
</xsl:template>
<xsl:template match="/ns0:EligibilityRecords">
<ns0:EligibilityRecords>
<xsl:for-each select="set:distinct(Eligibility_Detail_Record/PT_PARTICIPANT_FILE_IMP_ID)/..">
<xsl:if test="PT_PARTICIPANT_FILE_IMP_ID != '' and (EN_PLAN_NAME = 'Health Reimbursement Arrangement' or EN_PLAN_NAME = 'Health Savings Account')">
<Eligibility_Detail_Record>
<PT_PARTICIPANT_FILE_IMP_ID>
<xsl:value-of select="PT_PARTICIPANT_FILE_IMP_ID/text()" />
</PT_PARTICIPANT_FILE_IMP_ID>
<PT_LST_NM>
<xsl:value-of select="PT_LST_NM/text()" />
</PT_LST_NM>
<PT_FRST_NM>
<xsl:value-of select="PT_FRST_NM/text()" />
</PT_FRST_NM>
<EN_PLAN_NAME>
<xsl:value-of select="EN_PLAN_NAME/text()" />
</EN_PLAN_NAME>
<xsl:choose>
<xsl:when test="EN_PLAN_NAME = 'Health Reimbursement Arrangement'">
<xsl:choose>
<xsl:when test="key('DependentSearch',DP_PARTICIPANT_FILE_IMP_ID) != ''">
<xsl:choose>
<xsl:when test="count(key('DependentSearch',DP_PARTICIPANT_FILE_IMP_ID)) > 1">
<EN_PLAN_TYPE>Family</EN_PLAN_TYPE>
</xsl:when>
<xsl:when test="count(key('DependentSearch',DP_PARTICIPANT_FILE_IMP_ID)) = 1">
<xsl:choose>
<xsl:when test="DP_RELATIONSHIP = 'Spouse'">
<EN_PLAN_TYPE>IndSpouse</EN_PLAN_TYPE>
</xsl:when>
<xsl:otherwise>
<EN_PLAN_TYPE>IndChild</EN_PLAN_TYPE>
</xsl:otherwise>
</xsl:choose>
</xsl:when>
</xsl:choose>
</xsl:when>
<xsl:otherwise>
<EN_PLAN_TYPE>Ind</EN_PLAN_TYPE>
</xsl:otherwise>
</xsl:choose>
</xsl:when>
<xsl:when test="EN_PLAN_NAME = 'Health Savings Account'">
<xsl:choose>
<xsl:when test="count(key('DependentSearch',DP_PARTICIPANT_FILE_IMP_ID)) > 0">
<EN_HDHP_COVERAGE_LEVEL>Family</EN_HDHP_COVERAGE_LEVEL>
</xsl:when>
<xsl:otherwise>
<EN_HDHP_COVERAGE_LEVEL>Single</EN_HDHP_COVERAGE_LEVEL>
</xsl:otherwise>
</xsl:choose>
</xsl:when>
</xsl:choose>
<EN_MBRSHP_EFF_STRT_DT>
<xsl:value-of select="EN_MBRSHP_EFF_STRT_DT/text()" />
</EN_MBRSHP_EFF_STRT_DT>
<EN_MBRSHP_EFF_END_DT>
<xsl:value-of select="EN_MBRSHP_EFF_END_DT/text()" />
</EN_MBRSHP_EFF_END_DT>
<EN_PLAN_YEAR_STRT_DT>
<xsl:value-of select="EN_PLAN_YEAR_STRT_DT/text()" />
</EN_PLAN_YEAR_STRT_DT>
<xsl:for-each select="key('ParticipantGroup',PT_PARTICIPANT_FILE_IMP_ID)">
<xsl:if test="DP_DEPENDENT_FILE_IMP_ID/text()">
<Dependent_Record>
<DP_PARTICIPANT_FILE_IMP_ID>
<xsl:value-of select="DP_PARTICIPANT_FILE_IMP_ID/text()" />
</DP_PARTICIPANT_FILE_IMP_ID>
<DP_DEPENDENT_FILE_IMP_ID>
<xsl:value-of select="DP_DEPENDENT_FILE_IMP_ID/text()" />
</DP_DEPENDENT_FILE_IMP_ID>
<DP_RELATIONSHIP>
<xsl:value-of select="DP_RELATIONSHIP/text()" />
</DP_RELATIONSHIP>
<DP_LST_NM>
<xsl:value-of select="DP_LST_NM/text()" />
</DP_LST_NM>
<DP_FRST_NM>
<xsl:value-of select="DP_FRST_NM/text()" />
</DP_FRST_NM>
</Dependent_Record>
</xsl:if>
</xsl:for-each>
</Eligibility_Detail_Record>
</xsl:if>
</xsl:for-each>
</ns0:EligibilityRecords>
</xsl:template>
</xsl:stylesheet>
I am fairly green at XML but I am using a Muenchian Grouping to create the Dependent Groups under the appropriate parent record and then had the idea to create another key for the DP_PARTICIPANT_FILE_IMP_ID, then count how many occurrences of that key there are to determine what the EN_PLAN_TYPE or EN_HDHP_COVERAGE_LEVEL should be.
All of my requirements are met and everything is working with the exception of that EN_PLAN_TYPE code. Even that almost works correctly.
It outputs IndSpouse, IndChild, and Family correctly when those criteria are met but when there are no dependents for a particular parent record it still outputs Family in the EN_PLAN_TYPE node.
My assumption is that when you create an xsl:key it will put empty values in the key-value pair for each one and I thought I was testing for that properly but apparently I am not.
I will take any and all advice on how to make any of this code more readable/efficient/what have you. Such as using templates to remove the unwanted nodes from the result set rather than using an xsl:if. But the major concern I have right now is getting the correct output into the EN_PLAN_TYPE node.
The engine I am using is actually the BizTalk 2010 Mapper and I do have access to ESXLT (which I am already making use of for the Muenchian Grouping)
回答1:
My answer is based on your original, more detailed, requirements:
- Strip all Eligibility_Detail_Records that have a blank PT_PARTICIPANT_FILE_IMP_ID AND The EN_PLAN_NAME node is not "Health Reimbursement Arrangement" or "Health Savings Account"
- Create a new Dependent_Record that is a child record of Eligibility_Detail_Record for each DP_PARTICIPANT_FILE_IMP_ID that matches a PT_PARTICIPANT_FILE_IMP_ID
- Add an EN_PLAN_TYPE field for each Record that has an EN_PLAN_NAME of "Health Reimbursement Arrangement" that reads:
- "Ind" if no dependents are found
- "IndSpouse" if one and only one dependent that has DP_RELATIONSHIP of Spouse
- "IndChild" if one and only one dependent that has DP_RELATIONSHIP of Dependent
- "Family" if more than one dependent
- Add an EN_HDHP_COVERAGE_LEVEL field for each Record that has en EN_PLAN_NAME of "Health Savings Account" that reads:
- "Ind" if no dependents are found
- "Family" if one or more dependents are found
I started to look at your original XSLT (before the edit for brevity), but I think it was a little more complicated than it needed to be and that made it harder to determine what the problem was with generating the EN_PLAN_TYPE
.
Here are a few suggestions:
- Just use a single
xsl:key
for all participants based on thePT_PARTICIPANT_FILE_IMP_ID
that ties them all together. - Since you're not making any changes to the content of most elements, instead of creating new elements and using
xsl:value-of
to output the text(), just copy the original element usingxsl:copy-of
. - For the bigger pieces of logic, like determining
EN_PLAN_TYPE
/EN_HDHP_COVERAGE_LEVEL
, create named templates you can call (or you could apply-templates).
Here's an example. Determining the EN_HDHP_COVERAGE_LEVEL
for Health Savings Account
hasn't been tested since there wasn't an example in the input.
XML Input
<EligibilityRecords xmlns="http://Eligibility_LSDD">
<Eligibility_Detail_Record xmlns="">
<PT_PARTICIPANT_FILE_IMP_ID></PT_PARTICIPANT_FILE_IMP_ID>
<PT_LST_NM>VALLE</PT_LST_NM>
<PT_FRST_NM>FRANKIE</PT_FRST_NM>
<EN_PLAN_NAME>Health Reimbursement Arrangement</EN_PLAN_NAME>
<EN_MBRSHP_EFF_STRT_DT>01012017</EN_MBRSHP_EFF_STRT_DT>
<EN_MBRSHP_EFF_END_DT></EN_MBRSHP_EFF_END_DT>
<EN_PLAN_YEAR_STRT_DT>01012017</EN_PLAN_YEAR_STRT_DT>
<DP_PARTICIPANT_FILE_IMP_ID></DP_PARTICIPANT_FILE_IMP_ID>
<DP_DEPENDENT_FILE_IMP_ID></DP_DEPENDENT_FILE_IMP_ID>
<DP_RELATIONSHIP></DP_RELATIONSHIP>
</Eligibility_Detail_Record>
<Eligibility_Detail_Record xmlns="">
<PT_PARTICIPANT_FILE_IMP_ID>123456</PT_PARTICIPANT_FILE_IMP_ID>
<PT_LST_NM>BULLOCK</PT_LST_NM>
<PT_FRST_NM>SANDRA</PT_FRST_NM>
<EN_PLAN_NAME></EN_PLAN_NAME>
<EN_MBRSHP_EFF_STRT_DT>01012017</EN_MBRSHP_EFF_STRT_DT>
<EN_MBRSHP_EFF_END_DT></EN_MBRSHP_EFF_END_DT>
<EN_PLAN_YEAR_STRT_DT>01012017</EN_PLAN_YEAR_STRT_DT>
<DP_PARTICIPANT_FILE_IMP_ID></DP_PARTICIPANT_FILE_IMP_ID>
<DP_DEPENDENT_FILE_IMP_ID></DP_DEPENDENT_FILE_IMP_ID>
<DP_RELATIONSHIP></DP_RELATIONSHIP>
</Eligibility_Detail_Record>
<Eligibility_Detail_Record xmlns="">
<PT_PARTICIPANT_FILE_IMP_ID>553739837</PT_PARTICIPANT_FILE_IMP_ID>
<PT_LST_NM>DOE</PT_LST_NM>
<PT_FRST_NM>JANE</PT_FRST_NM>
<EN_PLAN_NAME>Health Reimbursement Arrangement</EN_PLAN_NAME>
<EN_MBRSHP_EFF_STRT_DT>01012017</EN_MBRSHP_EFF_STRT_DT>
<EN_MBRSHP_EFF_END_DT></EN_MBRSHP_EFF_END_DT>
<EN_PLAN_YEAR_STRT_DT>01012017</EN_PLAN_YEAR_STRT_DT>
<DP_PARTICIPANT_FILE_IMP_ID></DP_PARTICIPANT_FILE_IMP_ID>
<DP_DEPENDENT_FILE_IMP_ID></DP_DEPENDENT_FILE_IMP_ID>
<DP_RELATIONSHIP></DP_RELATIONSHIP>
</Eligibility_Detail_Record>
<Eligibility_Detail_Record xmlns="">
<PT_PARTICIPANT_FILE_IMP_ID>610051908</PT_PARTICIPANT_FILE_IMP_ID>
<PT_LST_NM>JACKSON</PT_LST_NM>
<PT_FRST_NM>MICHAEL</PT_FRST_NM>
<EN_PLAN_NAME>Health Reimbursement Arrangement</EN_PLAN_NAME>
<EN_MBRSHP_EFF_STRT_DT>01012017</EN_MBRSHP_EFF_STRT_DT>
<EN_MBRSHP_EFF_END_DT></EN_MBRSHP_EFF_END_DT>
<EN_PLAN_YEAR_STRT_DT>01012017</EN_PLAN_YEAR_STRT_DT>
<DP_PARTICIPANT_FILE_IMP_ID>610051908</DP_PARTICIPANT_FILE_IMP_ID>
<DP_DEPENDENT_FILE_IMP_ID>NC110015202761</DP_DEPENDENT_FILE_IMP_ID>
<DP_RELATIONSHIP>Spouse</DP_RELATIONSHIP>
<DP_LST_NM>JACKSON</DP_LST_NM>
<DP_FRST_NM>MELISSA</DP_FRST_NM>
</Eligibility_Detail_Record>
<Eligibility_Detail_Record xmlns="">
<PT_PARTICIPANT_FILE_IMP_ID>561859010</PT_PARTICIPANT_FILE_IMP_ID>
<PT_LST_NM>MCLEOD</PT_LST_NM>
<PT_FRST_NM>CONOR</PT_FRST_NM>
<EN_PLAN_NAME>Health Reimbursement Arrangement</EN_PLAN_NAME>
<EN_MBRSHP_EFF_STRT_DT>01012016</EN_MBRSHP_EFF_STRT_DT>
<EN_MBRSHP_EFF_END_DT></EN_MBRSHP_EFF_END_DT>
<EN_PLAN_YEAR_STRT_DT>01012016</EN_PLAN_YEAR_STRT_DT>
<DP_PARTICIPANT_FILE_IMP_ID>561859010</DP_PARTICIPANT_FILE_IMP_ID>
<DP_DEPENDENT_FILE_IMP_ID>SC000018241906</DP_DEPENDENT_FILE_IMP_ID>
<DP_RELATIONSHIP>Dependent</DP_RELATIONSHIP>
<DP_LST_NM>MCLEOD</DP_LST_NM>
<DP_FRST_NM>DUNCAN</DP_FRST_NM>
</Eligibility_Detail_Record>
<Eligibility_Detail_Record xmlns="">
<PT_PARTICIPANT_FILE_IMP_ID>573794953</PT_PARTICIPANT_FILE_IMP_ID>
<PT_LST_NM>GABRIEL</PT_LST_NM>
<PT_FRST_NM>PETER</PT_FRST_NM>
<EN_PLAN_NAME>Health Reimbursement Arrangement</EN_PLAN_NAME>
<EN_MBRSHP_EFF_STRT_DT>01012016</EN_MBRSHP_EFF_STRT_DT>
<EN_MBRSHP_EFF_END_DT></EN_MBRSHP_EFF_END_DT>
<EN_PLAN_YEAR_STRT_DT>01012016</EN_PLAN_YEAR_STRT_DT>
<DP_PARTICIPANT_FILE_IMP_ID></DP_PARTICIPANT_FILE_IMP_ID>
<DP_DEPENDENT_FILE_IMP_ID></DP_DEPENDENT_FILE_IMP_ID>
<DP_RELATIONSHIP></DP_RELATIONSHIP>
</Eligibility_Detail_Record>
<Eligibility_Detail_Record xmlns="">
<PT_PARTICIPANT_FILE_IMP_ID>553739837</PT_PARTICIPANT_FILE_IMP_ID>
<PT_LST_NM>DOE</PT_LST_NM>
<PT_FRST_NM>JANE</PT_FRST_NM>
<EN_PLAN_NAME>Health Reimbursement Arrangement</EN_PLAN_NAME>
<EN_MBRSHP_EFF_STRT_DT>01012016</EN_MBRSHP_EFF_STRT_DT>
<EN_MBRSHP_EFF_END_DT></EN_MBRSHP_EFF_END_DT>
<EN_PLAN_YEAR_STRT_DT>01012016</EN_PLAN_YEAR_STRT_DT>
<DP_PARTICIPANT_FILE_IMP_ID>553739837</DP_PARTICIPANT_FILE_IMP_ID>
<DP_DEPENDENT_FILE_IMP_ID>NC110012077673</DP_DEPENDENT_FILE_IMP_ID>
<DP_RELATIONSHIP>Spouse</DP_RELATIONSHIP>
<DP_LST_NM>DOE</DP_LST_NM>
<DP_FRST_NM>JOHN</DP_FRST_NM>
</Eligibility_Detail_Record>
<Eligibility_Detail_Record xmlns="">
<PT_PARTICIPANT_FILE_IMP_ID>553739837</PT_PARTICIPANT_FILE_IMP_ID>
<PT_LST_NM>DOE</PT_LST_NM>
<PT_FRST_NM>JANE</PT_FRST_NM>
<EN_PLAN_NAME>Health Reimbursement Arrangement</EN_PLAN_NAME>
<EN_MBRSHP_EFF_STRT_DT>01012016</EN_MBRSHP_EFF_STRT_DT>
<EN_MBRSHP_EFF_END_DT></EN_MBRSHP_EFF_END_DT>
<EN_PLAN_YEAR_STRT_DT>01012016</EN_PLAN_YEAR_STRT_DT>
<DP_PARTICIPANT_FILE_IMP_ID>553739837</DP_PARTICIPANT_FILE_IMP_ID>
<DP_DEPENDENT_FILE_IMP_ID>NC110012077680</DP_DEPENDENT_FILE_IMP_ID>
<DP_RELATIONSHIP>Dependent</DP_RELATIONSHIP>
<DP_LST_NM>DOE</DP_LST_NM>
<DP_FRST_NM>JIMMY</DP_FRST_NM>
</Eligibility_Detail_Record>
<Eligibility_Detail_Record xmlns="">
<PT_PARTICIPANT_FILE_IMP_ID>553739837</PT_PARTICIPANT_FILE_IMP_ID>
<PT_LST_NM>DOE</PT_LST_NM>
<PT_FRST_NM>JANE</PT_FRST_NM>
<EN_PLAN_NAME>Health Reimbursement Arrangement</EN_PLAN_NAME>
<EN_MBRSHP_EFF_STRT_DT>01012016</EN_MBRSHP_EFF_STRT_DT>
<EN_MBRSHP_EFF_END_DT></EN_MBRSHP_EFF_END_DT>
<EN_PLAN_YEAR_STRT_DT>01012016</EN_PLAN_YEAR_STRT_DT>
<DP_PARTICIPANT_FILE_IMP_ID>553739837</DP_PARTICIPANT_FILE_IMP_ID>
<DP_DEPENDENT_FILE_IMP_ID>NC110012077681</DP_DEPENDENT_FILE_IMP_ID>
<DP_RELATIONSHIP>Dependent</DP_RELATIONSHIP>
<DP_LST_NM>DOE</DP_LST_NM>
<DP_FRST_NM>JESSICA</DP_FRST_NM>
</Eligibility_Detail_Record>
</EligibilityRecords>
XSLT 1.0 (requirements are added as comments)
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes" omit-xml-declaration="yes"/>
<xsl:strip-space elements="*"/>
<xsl:key name="participants" match="Eligibility_Detail_Record" use="PT_PARTICIPANT_FILE_IMP_ID"/>
<xsl:template match="/*">
<xsl:copy>
<!--Strip all Eligibility_Detail_Records that have a blank PT_PARTICIPANT_FILE_IMP_ID AND The EN_PLAN_NAME node is not "Health Reimbursement Arrangement" or "Health Savings Account"-->
<xsl:for-each select="Eligibility_Detail_Record[string(PT_PARTICIPANT_FILE_IMP_ID) and (EN_PLAN_NAME='Health Reimbursement Arrangement' or EN_PLAN_NAME='Health Savings Account')]
[count(.|key('participants',PT_PARTICIPANT_FILE_IMP_ID)[1])=1]">
<xsl:variable name="participantCount" select="count(key('participants',PT_PARTICIPANT_FILE_IMP_ID))"/>
<Eligibility_Detail_Record>
<xsl:copy-of select="*[starts-with(name(),'PT_')]|EN_PLAN_NAME"/>
<xsl:choose>
<!--Add an EN_PLAN_TYPE field for each Record that has an EN_PLAN_NAME of "Health Reimbursement Arrangement" that reads:-->
<xsl:when test="EN_PLAN_NAME='Health Reimbursement Arrangement'">
<xsl:call-template name="HRA">
<xsl:with-param name="participantCount" select="$participantCount"/>
</xsl:call-template>
</xsl:when>
<!--Add an EN_HDHP_COVERAGE_LEVEL field for each Record that has en EN_PLAN_NAME of "Health Savings Account" that reads:-->
<xsl:when test="EN_PLAN_NAME='Health Savings Account'">
<xsl:call-template name="HSA">
<xsl:with-param name="participantCount" select="$participantCount"/>
</xsl:call-template>
</xsl:when>
</xsl:choose>
<xsl:copy-of select="*[not(self::EN_PLAN_NAME) and starts-with(name(),'EN_')]"/>
<!--Create a new Dependent_Record that is a child record of Eligibility_Detail_Record for each DP_PARTICIPANT_FILE_IMP_ID that matches a PT_PARTICIPANT_FILE_IMP_ID-->
<xsl:for-each select="key('participants',PT_PARTICIPANT_FILE_IMP_ID)[string(DP_PARTICIPANT_FILE_IMP_ID)]">
<Dependent_Record>
<xsl:copy-of select="*[starts-with(name(),'DP_')]"/>
</Dependent_Record>
</xsl:for-each>
</Eligibility_Detail_Record>
</xsl:for-each>
</xsl:copy>
</xsl:template>
<xsl:template name="HRA">
<xsl:param name="participantCount"/>
<EN_PLAN_TYPE>
<xsl:choose>
<!--"Family" if more than one dependent-->
<xsl:when test="$participantCount > 1">Family</xsl:when>
<!--"IndChild" if one and only one dependent that has DP_RELATIONSHIP of Dependent-->
<xsl:when test="$participantCount = 1 and DP_RELATIONSHIP = 'Dependent'">IndChild</xsl:when>
<!--"IndSpouse" if one and only one dependent that has DP_RELATIONSHIP of Spouse-->
<xsl:when test="$participantCount = 1 and DP_RELATIONSHIP = 'Spouse'">IndSpouse</xsl:when>
<!--"Ind" if no dependents are found-->
<xsl:when test="$participantCount = 1">Ind</xsl:when>
</xsl:choose>
</EN_PLAN_TYPE>
</xsl:template>
<xsl:template name="HSA">
<xsl:param name="participantCount"/>
<EN_HDHP_COVERAGE_LEVEL>
<xsl:choose>
<!--"Family" if one or more dependents are found-->
<xsl:when test="$participantCount > 1 or
$participantCount = 1 and string(DP_RELATIONSHIP)">Family</xsl:when>
<!--"Ind" if no dependents are found-->
<xsl:when test="$participantCount = 1">Ind</xsl:when>
</xsl:choose>
</EN_HDHP_COVERAGE_LEVEL>
</xsl:template>
</xsl:stylesheet>
Output
<EligibilityRecords xmlns="http://Eligibility_LSDD">
<Eligibility_Detail_Record xmlns="">
<PT_PARTICIPANT_FILE_IMP_ID>553739837</PT_PARTICIPANT_FILE_IMP_ID>
<PT_LST_NM>DOE</PT_LST_NM>
<PT_FRST_NM>JANE</PT_FRST_NM>
<EN_PLAN_NAME>Health Reimbursement Arrangement</EN_PLAN_NAME>
<EN_PLAN_TYPE>Family</EN_PLAN_TYPE>
<EN_MBRSHP_EFF_STRT_DT>01012017</EN_MBRSHP_EFF_STRT_DT>
<EN_MBRSHP_EFF_END_DT/>
<EN_PLAN_YEAR_STRT_DT>01012017</EN_PLAN_YEAR_STRT_DT>
<Dependent_Record>
<DP_PARTICIPANT_FILE_IMP_ID>553739837</DP_PARTICIPANT_FILE_IMP_ID>
<DP_DEPENDENT_FILE_IMP_ID>NC110012077673</DP_DEPENDENT_FILE_IMP_ID>
<DP_RELATIONSHIP>Spouse</DP_RELATIONSHIP>
<DP_LST_NM>DOE</DP_LST_NM>
<DP_FRST_NM>JOHN</DP_FRST_NM>
</Dependent_Record>
<Dependent_Record>
<DP_PARTICIPANT_FILE_IMP_ID>553739837</DP_PARTICIPANT_FILE_IMP_ID>
<DP_DEPENDENT_FILE_IMP_ID>NC110012077680</DP_DEPENDENT_FILE_IMP_ID>
<DP_RELATIONSHIP>Dependent</DP_RELATIONSHIP>
<DP_LST_NM>DOE</DP_LST_NM>
<DP_FRST_NM>JIMMY</DP_FRST_NM>
</Dependent_Record>
<Dependent_Record>
<DP_PARTICIPANT_FILE_IMP_ID>553739837</DP_PARTICIPANT_FILE_IMP_ID>
<DP_DEPENDENT_FILE_IMP_ID>NC110012077681</DP_DEPENDENT_FILE_IMP_ID>
<DP_RELATIONSHIP>Dependent</DP_RELATIONSHIP>
<DP_LST_NM>DOE</DP_LST_NM>
<DP_FRST_NM>JESSICA</DP_FRST_NM>
</Dependent_Record>
</Eligibility_Detail_Record>
<Eligibility_Detail_Record xmlns="">
<PT_PARTICIPANT_FILE_IMP_ID>610051908</PT_PARTICIPANT_FILE_IMP_ID>
<PT_LST_NM>JACKSON</PT_LST_NM>
<PT_FRST_NM>MICHAEL</PT_FRST_NM>
<EN_PLAN_NAME>Health Reimbursement Arrangement</EN_PLAN_NAME>
<EN_PLAN_TYPE>IndSpouse</EN_PLAN_TYPE>
<EN_MBRSHP_EFF_STRT_DT>01012017</EN_MBRSHP_EFF_STRT_DT>
<EN_MBRSHP_EFF_END_DT/>
<EN_PLAN_YEAR_STRT_DT>01012017</EN_PLAN_YEAR_STRT_DT>
<Dependent_Record>
<DP_PARTICIPANT_FILE_IMP_ID>610051908</DP_PARTICIPANT_FILE_IMP_ID>
<DP_DEPENDENT_FILE_IMP_ID>NC110015202761</DP_DEPENDENT_FILE_IMP_ID>
<DP_RELATIONSHIP>Spouse</DP_RELATIONSHIP>
<DP_LST_NM>JACKSON</DP_LST_NM>
<DP_FRST_NM>MELISSA</DP_FRST_NM>
</Dependent_Record>
</Eligibility_Detail_Record>
<Eligibility_Detail_Record xmlns="">
<PT_PARTICIPANT_FILE_IMP_ID>561859010</PT_PARTICIPANT_FILE_IMP_ID>
<PT_LST_NM>MCLEOD</PT_LST_NM>
<PT_FRST_NM>CONOR</PT_FRST_NM>
<EN_PLAN_NAME>Health Reimbursement Arrangement</EN_PLAN_NAME>
<EN_PLAN_TYPE>IndChild</EN_PLAN_TYPE>
<EN_MBRSHP_EFF_STRT_DT>01012016</EN_MBRSHP_EFF_STRT_DT>
<EN_MBRSHP_EFF_END_DT/>
<EN_PLAN_YEAR_STRT_DT>01012016</EN_PLAN_YEAR_STRT_DT>
<Dependent_Record>
<DP_PARTICIPANT_FILE_IMP_ID>561859010</DP_PARTICIPANT_FILE_IMP_ID>
<DP_DEPENDENT_FILE_IMP_ID>SC000018241906</DP_DEPENDENT_FILE_IMP_ID>
<DP_RELATIONSHIP>Dependent</DP_RELATIONSHIP>
<DP_LST_NM>MCLEOD</DP_LST_NM>
<DP_FRST_NM>DUNCAN</DP_FRST_NM>
</Dependent_Record>
</Eligibility_Detail_Record>
<Eligibility_Detail_Record xmlns="">
<PT_PARTICIPANT_FILE_IMP_ID>573794953</PT_PARTICIPANT_FILE_IMP_ID>
<PT_LST_NM>GABRIEL</PT_LST_NM>
<PT_FRST_NM>PETER</PT_FRST_NM>
<EN_PLAN_NAME>Health Reimbursement Arrangement</EN_PLAN_NAME>
<EN_PLAN_TYPE>Ind</EN_PLAN_TYPE>
<EN_MBRSHP_EFF_STRT_DT>01012016</EN_MBRSHP_EFF_STRT_DT>
<EN_MBRSHP_EFF_END_DT/>
<EN_PLAN_YEAR_STRT_DT>01012016</EN_PLAN_YEAR_STRT_DT>
</Eligibility_Detail_Record>
</EligibilityRecords>
来源:https://stackoverflow.com/questions/41601305/change-output-based-on-value-in-xslkey-in-xslt-1-0