Jesse Roper
Jesse Roper

Reputation: 1309

Guidance for complex XSLT

I'm working on parsing XML that is to be converted to text and submitted to FinCEN, who requires it to be in a very specific format. Basically, I will get an xml file with elements all arranged as siblings and their association with each other is based on order of appearance in the file. So I may have a file that looks like this:

<bsar:BSAForm xmlns:bsar="http://www.fincen.gov/bsa/bsar/2011-06-01">
<bsar:FilingInstitutionInformation>
    <bsar:PrimaryRegulator>D</bsar:PrimaryRegulator>
    <bsar:FilerName>New Banking Corp.</bsar:FilerName>
    <bsar:TIN>373637383</bsar:TIN>
    <bsar:TINTYPE>A</bsar:TINTYPE>
    <bsar:FIType>
        <ucc:FinInsType xmlns:ucc="http://www.fincen.gov/bsa/ucommon-components/2011-06-01">C</ucc:FinInsType>
        <ucc:OtherSpecify xmlns:ucc="http://www.fincen.gov/bsa/ucommon-components/2011-06-01" />
    </bsar:FIType>
    <bsar:SecuritiesFuturesType>
        <bsar:ClearingBrokerSecurities />
        <bsar:CPOCTA />
        <bsar:FuturesCommissionMerchant />
        <bsar:HoldingCompany />
        <bsar:IntroducingCommodities />
        <bsar:IntroducingSecurities />
        <bsar:InvestmentAdvisor />
        <bsar:InvestmentCompany />
        <bsar:RetailForeign />
        <bsar:SROFutures />
        <bsar:SROSecurities />
        <bsar:Subsidiary />
        <bsar:Other />
        <bsar:OtherSpecify />
    </bsar:SecuritiesFuturesType>
    <bsar:FIIdentification>
        <ucc:FIIDType xmlns:ucc="http://www.fincen.gov/bsa/ucommon-components/2011-06-01">D</ucc:FIIDType>
        <ucc:FIIDNumber xmlns:ucc="http://www.fincen.gov/bsa/ucommon-components/2011-06-01">654646321321</ucc:FIIDNumber>
    </bsar:FIIdentification>
    <bsar:FIAddress>
        <ucc:Address xmlns:ucc="http://www.fincen.gov/bsa/ucommon-components/2011-06-01">Ave X</ucc:Address>
        <ucc:City xmlns:ucc="http://www.fincen.gov/bsa/ucommon-components/2011-06-01">Brooklyn</ucc:City>
        <ucc:State xmlns:ucc="http://www.fincen.gov/bsa/ucommon-components/2011-06-01">NY</ucc:State>
        <ucc:ZIP xmlns:ucc="http://www.fincen.gov/bsa/ucommon-components/2011-06-01">11235</ucc:ZIP>
        <ucc:Country xmlns:ucc="http://www.fincen.gov/bsa/ucommon-components/2011-06-01">US</ucc:Country>
    </bsar:FIAddress>
    <bsar:AlternateName>alternate name</bsar:AlternateName>
</bsar:FilingInstitutionInformation> <!--2A-->

<bsar:FinancialInstitutionInformation>
    <bsar:LegalName>Citibank</bsar:LegalName>
</bsar:FinancialInstitutionInformation> <!--2B-->
<bsar:SuspiciousActivityInformation>
    <bsar:FilingType>A</bsar:FilingType>
    <bsar:ContinuingActivity />
    <bsar:JointReport />
    <ucc:DocumentControlNumber xmlns:ucc="http://www.fincen.gov/bsa/ucommon-components/2011-06-01" />
    <bsar:ViolationAmount />
    <bsar:AmountUnKnownOrNotInvolved>B</bsar:AmountUnKnownOrNotInvolved>
    <bsar:FromSuspiciousActivityDate>12312012</bsar:FromSuspiciousActivityDate>
    <bsar:ToSuspiciousActivityDate>12312012</bsar:ToSuspiciousActivityDate>
    <bsar:CumulativeAmount />
    <bsar:Structuring>
        <bsar:AltersTransactionBSA>A</bsar:AltersTransactionBSA>
        <bsar:AltersTransactionCTR />
        <bsar:CustomerCancels />
        <bsar:MultipleTransactions />
        <bsar:MultipleTransactionsCTR />
        <bsar:SuspiciousInquiry />
        <bsar:Other />
        <bsar:OtherSpecify />
    </bsar:Structuring>
    <bsar:TerroristFinanacing>
        <bsar:KnownTerroristOrg />
        <bsar:Other />
        <bsar:OtherSpecify />
    </bsar:TerroristFinanacing>
    <bsar:Fraud>
        <bsar:ACH />
        <bsar:BusinessLoan />
        <bsar:Check />
        <bsar:ConsumerLoan />
        <bsar:CreditDebitCard />
        <bsar:HealthCare />
        <bsar:Mail />
        <bsar:MassMarketing />
        <bsar:PyramidScheme />
        <bsar:Wire />
        <bsar:Other />
        <bsar:OtherSpecify />
    </bsar:Fraud>
    <bsar:Casinos>
        <bsar:InquiryOnEOB />
        <bsar:MinimalGaming />
        <bsar:IntraCasinoFundTransfer />
        <bsar:CounterChecksorMarkers />
        <bsar:Other />
        <bsar:OtherSpecify />
    </bsar:Casinos>
    <bsar:MoneyLaundering>
        <bsar:ExchangeSmallBig />
        <bsar:PhysicalCondition />
        <bsar:SourceFund />
        <bsar:Designation />
        <bsar:EftOrWireTransfer />
        <bsar:ExchangeCurrency />
        <bsar:GovernmentPaymentReceipt />
        <bsar:MultipleAccounts />
        <bsar:NonCashMonetaryInstr />
        <bsar:StrawMan />
        <bsar:MoneyLaunderingBlackMarket />
        <bsar:OutOfPatterns />
        <bsar:Other />
        <bsar:OtherSpecify />
    </bsar:MoneyLaundering>
    <bsar:IdentificationDocumentation>
        <bsar:ChangeName />
        <bsar:MultiIndiWithSameSimilarName />
        <bsar:QuestionableOrfalseDoc />
        <bsar:RefusedDoc />
        <bsar:MultipleIdentities />
        <bsar:Other />
        <bsar:OtherSpecify />
    </bsar:IdentificationDocumentation>
    <bsar:OtherSuspicoiusActivities>
        <bsar:AccountTakeOver />
        <bsar:BriberyOrGratuity />
        <bsar:CounterfeitInstr />
        <bsar:ElderFinancial />
        <bsar:Embezzlement />
        <bsar:Forgeries />
        <bsar:IdentifyTheft />
        <bsar:LittleNoConcerns />
        <bsar:MisuseFreeLook />
        <bsar:MisusePosition />
        <bsar:SuspectedDomesticCorruption />
        <bsar:SuspectedForeignCorruption />
        <bsar:SuspiciousUseInformationValueSys />
        <bsar:SuspiciousUseMultiLoc />
        <bsar:NoPurpose />
        <bsar:TwoOrMoreWorkingTogether />
        <bsar:UnAuthorizedEInstrusion />
        <bsar:UnLicensedMSB />
        <bsar:Other />
        <bsar:OtherSpecify />
    </bsar:OtherSuspicoiusActivities>
    <bsar:Insurance>
        <bsar:ExcessiveInsurance>A</bsar:ExcessiveInsurance>
        <bsar:ExcessiveOrUnusalCash />
        <bsar:ProceedsFromUnrelated3rd />
        <bsar:LifeSettlement />
        <bsar:PolicyTermination />
        <bsar:UnclearNoInterest />
        <bsar:Other />
        <bsar:OtherSpecify />
    </bsar:Insurance>
    <bsar:SecuritiesFutureOptions>
        <bsar:InsiderTrading />
        <bsar:WashTrading />
        <bsar:Misappropriation />
        <bsar:UnauthorizedPooling />
        <bsar:Other />
        <bsar:OtherSpecify />
    </bsar:SecuritiesFutureOptions>
    <bsar:MortgageFraud>
        <bsar:Appraisal />
        <bsar:Foreclosure />
        <bsar:LoanModification />
        <bsar:ReverseMortgage />
        <bsar:Other />
        <bsar:OtherSpecify />
    </bsar:MortgageFraud>
    <bsar:Product>
        <bsar:BondsNotes>A</bsar:BondsNotes>
        <bsar:CommercialMtgg />
        <bsar:CommercialPaper />
        <bsar:CreditCard />
        <bsar:DebitCard />
        <bsar:ForexTrans />
        <bsar:FutureOptionsOnFu />
        <bsar:HedgeFund />
        <bsar:HomeEquityLoan />
        <bsar:HomeEquityLine />
        <bsar:InsuranceAnuity />
        <bsar:MutualFund />
        <bsar:OptionsOnSec />
        <bsar:PennyStocks />
        <bsar:PrepaidAccess />
        <bsar:ResidentialMtgg />
        <bsar:SecurityFuture />
        <bsar:Stocks />
        <bsar:SwapHybridDer />
        <bsar:Other />
        <bsar:OtherSpecify />
    </bsar:Product>
    <bsar:InstrumentOrPayment>
        <bsar:BankCheck />
        <bsar:ForeignCurrency />
        <bsar:FundsTransfer />
        <bsar:GamingInstrm />
        <bsar:GovernmentPayment />
        <bsar:MoneyOrders />
        <bsar:PersonalCheck />
        <bsar:TravelersCheck />
        <bsar:USCurrency />
        <bsar:Other />
        <bsar:OtherSpecify />
    </bsar:InstrumentOrPayment>
    <bsar:InternalControlNumber>654321654321</bsar:InternalControlNumber>
    <bsar:CommodityTypeRecord>
        <bsar:CommodityType>commodity type</bsar:CommodityType>
    </bsar:CommodityTypeRecord>
    <bsar:ProductInstrumentDescRecord>
        <bsar:ProductInstrumentDesc>product description</bsar:ProductInstrumentDesc>
    </bsar:ProductInstrumentDescRecord>
    <bsar:MarketTradedRecord>
        <bsar:MarketTraded>101</bsar:MarketTraded>
    </bsar:MarketTradedRecord>
    <bsar:IPAddressRecord>
        <bsar:IPAddress>255.255.255.255</bsar:IPAddress>
    </bsar:IPAddressRecord>
    <bsar:CUSIPNumberRecord>
        <bsar:CUSIPNumber>3465431654</bsar:CUSIPNumber>
    </bsar:CUSIPNumberRecord>
</bsar:SuspiciousActivityInformation> <!--3A-->

<bsar:FinancialInstitutionInformation>
    <bsar:LegalName>Bank of America</bsar:LegalName>
</bsar:FinancialInstitutionInformation> <!--2B-->
<bsar:SuspiciousActivityInformation>
    <bsar:FilingType>A</bsar:FilingType>
    <bsar:ContinuingActivity />
    <bsar:JointReport />
    <ucc:DocumentControlNumber xmlns:ucc="http://www.fincen.gov/bsa/ucommon-components/2011-06-01" />
    <bsar:ViolationAmount />
    <bsar:AmountUnKnownOrNotInvolved>B</bsar:AmountUnKnownOrNotInvolved>
    <bsar:FromSuspiciousActivityDate>12312012</bsar:FromSuspiciousActivityDate>
    <bsar:ToSuspiciousActivityDate>12312012</bsar:ToSuspiciousActivityDate>
    <bsar:CumulativeAmount />
    <bsar:Structuring>
        <bsar:AltersTransactionBSA>A</bsar:AltersTransactionBSA>
        <bsar:AltersTransactionCTR />
        <bsar:CustomerCancels />
        <bsar:MultipleTransactions />
        <bsar:MultipleTransactionsCTR />
        <bsar:SuspiciousInquiry />
        <bsar:Other />
        <bsar:OtherSpecify />
    </bsar:Structuring>
    <bsar:TerroristFinanacing>
        <bsar:KnownTerroristOrg />
        <bsar:Other />
        <bsar:OtherSpecify />
    </bsar:TerroristFinanacing>
    <bsar:Fraud>
        <bsar:ACH />
        <bsar:BusinessLoan />
        <bsar:Check />
        <bsar:ConsumerLoan />
        <bsar:CreditDebitCard />
        <bsar:HealthCare />
        <bsar:Mail />
        <bsar:MassMarketing />
        <bsar:PyramidScheme />
        <bsar:Wire />
        <bsar:Other />
        <bsar:OtherSpecify />
    </bsar:Fraud>
    <bsar:Casinos>
        <bsar:InquiryOnEOB />
        <bsar:MinimalGaming />
        <bsar:IntraCasinoFundTransfer />
        <bsar:CounterChecksorMarkers />
        <bsar:Other />
        <bsar:OtherSpecify />
    </bsar:Casinos>
    <bsar:MoneyLaundering>
        <bsar:ExchangeSmallBig />
        <bsar:PhysicalCondition />
        <bsar:SourceFund />
        <bsar:Designation />
        <bsar:EftOrWireTransfer />
        <bsar:ExchangeCurrency />
        <bsar:GovernmentPaymentReceipt />
        <bsar:MultipleAccounts />
        <bsar:NonCashMonetaryInstr />
        <bsar:StrawMan />
        <bsar:MoneyLaunderingBlackMarket />
        <bsar:OutOfPatterns />
        <bsar:Other />
        <bsar:OtherSpecify />
    </bsar:MoneyLaundering>
    <bsar:IdentificationDocumentation>
        <bsar:ChangeName />
        <bsar:MultiIndiWithSameSimilarName />
        <bsar:QuestionableOrfalseDoc />
        <bsar:RefusedDoc />
        <bsar:MultipleIdentities />
        <bsar:Other />
        <bsar:OtherSpecify />
    </bsar:IdentificationDocumentation>
    <bsar:OtherSuspicoiusActivities>
        <bsar:AccountTakeOver />
        <bsar:BriberyOrGratuity />
        <bsar:CounterfeitInstr />
        <bsar:ElderFinancial />
        <bsar:Embezzlement />
        <bsar:Forgeries />
        <bsar:IdentifyTheft />
        <bsar:LittleNoConcerns />
        <bsar:MisuseFreeLook />
        <bsar:MisusePosition />
        <bsar:SuspectedDomesticCorruption />
        <bsar:SuspectedForeignCorruption />
        <bsar:SuspiciousUseInformationValueSys />
        <bsar:SuspiciousUseMultiLoc />
        <bsar:NoPurpose />
        <bsar:TwoOrMoreWorkingTogether />
        <bsar:UnAuthorizedEInstrusion />
        <bsar:UnLicensedMSB />
        <bsar:Other />
        <bsar:OtherSpecify />
    </bsar:OtherSuspicoiusActivities>
    <bsar:Insurance>
        <bsar:ExcessiveInsurance>A</bsar:ExcessiveInsurance>
        <bsar:ExcessiveOrUnusalCash />
        <bsar:ProceedsFromUnrelated3rd />
        <bsar:LifeSettlement />
        <bsar:PolicyTermination />
        <bsar:UnclearNoInterest />
        <bsar:Other />
        <bsar:OtherSpecify />
    </bsar:Insurance>
    <bsar:SecuritiesFutureOptions>
        <bsar:InsiderTrading />
        <bsar:WashTrading />
        <bsar:Misappropriation />
        <bsar:UnauthorizedPooling />
        <bsar:Other />
        <bsar:OtherSpecify />
    </bsar:SecuritiesFutureOptions>
    <bsar:MortgageFraud>
        <bsar:Appraisal />
        <bsar:Foreclosure />
        <bsar:LoanModification />
        <bsar:ReverseMortgage />
        <bsar:Other />
        <bsar:OtherSpecify />
    </bsar:MortgageFraud>
    <bsar:Product>
        <bsar:BondsNotes>A</bsar:BondsNotes>
        <bsar:CommercialMtgg />
        <bsar:CommercialPaper />
        <bsar:CreditCard />
        <bsar:DebitCard />
        <bsar:ForexTrans />
        <bsar:FutureOptionsOnFu />
        <bsar:HedgeFund />
        <bsar:HomeEquityLoan />
        <bsar:HomeEquityLine />
        <bsar:InsuranceAnuity />
        <bsar:MutualFund />
        <bsar:OptionsOnSec />
        <bsar:PennyStocks />
        <bsar:PrepaidAccess />
        <bsar:ResidentialMtgg />
        <bsar:SecurityFuture />
        <bsar:Stocks />
        <bsar:SwapHybridDer />
        <bsar:Other />
        <bsar:OtherSpecify />
    </bsar:Product>
    <bsar:InstrumentOrPayment>
        <bsar:BankCheck />
        <bsar:ForeignCurrency />
        <bsar:FundsTransfer />
        <bsar:GamingInstrm />
        <bsar:GovernmentPayment />
        <bsar:MoneyOrders />
        <bsar:PersonalCheck />
        <bsar:TravelersCheck />
        <bsar:USCurrency />
        <bsar:Other />
        <bsar:OtherSpecify />
    </bsar:InstrumentOrPayment>
    <bsar:InternalControlNumber>654321654321</bsar:InternalControlNumber>
    <bsar:CommodityTypeRecord>
        <bsar:CommodityType>commodity type</bsar:CommodityType>
    </bsar:CommodityTypeRecord>
    <bsar:ProductInstrumentDescRecord>
        <bsar:ProductInstrumentDesc>product description</bsar:ProductInstrumentDesc>
    </bsar:ProductInstrumentDescRecord>
    <bsar:MarketTradedRecord>
        <bsar:MarketTraded>101</bsar:MarketTraded>
    </bsar:MarketTradedRecord>
    <bsar:IPAddressRecord>
        <bsar:IPAddress>255.255.255.255</bsar:IPAddress>
    </bsar:IPAddressRecord>
    <bsar:CUSIPNumberRecord>
        <bsar:CUSIPNumber>3465431654</bsar:CUSIPNumber>
    </bsar:CUSIPNumberRecord>
</bsar:SuspiciousActivityInformation> <!--3A-->
<bsar:SubjectInformation>
    <bsar:Entity />
    <bsar:SubjectInformationUnavailable />
    <bsar:LastNameOrNameOfEntity>Ceriello</bsar:LastNameOrNameOfEntity>
</bsar:SubjectInformation> <!--4A-->
<bsar:SubjectInformation>
    <bsar:Entity />
    <bsar:SubjectInformationUnavailable>B</bsar:SubjectInformationUnavailable>
    <bsar:LastNameOrNameOfEntity>Gutierrez</bsar:LastNameOrNameOfEntity>
</bsar:SubjectInformation> <!--4A-->
<bsar:SubjectInformation>
    <bsar:Entity />
    <bsar:SubjectInformationUnavailable />
    <bsar:LastNameOrNameOfEntity>Roper</bsar:LastNameOrNameOfEntity>
</bsar:SubjectInformation> <!--4A-->

Basically, the pseudo-code would look like this:

Output 1A

For each 2A

    Output 2A

    For each 2B before the next 2A

        Output 2B

        For each 3A before the next 2B

            Output 3A; increment counter

                For each 4A before the next 3A

                    Output 4A with above counter

The text will essentially need to be formatted in the order it is in the file, with some summary sections (after each 2B, for instance) . I'm having trouble figuring out how to loop over elements that follow a 3A, for example without looping over all the 4A records in the document. For each 3A, I will also need to keep a counter so I can output that with the text for the 3A section and associated 4A sections.

Originally, I had designed a series of loops that would go through each of elements in the file and call the appropriate once for each, but I realized that will pick out all the elements in the file and not just the ones that appear beneath the relevant (parent) element that I want to see for that section.

Then, I considered using a catch-all so all the elements would be dealt with in the order they appear in the file. However, I don't see how I could use any kind of counter if I do it this way. (I understand I can't use an actual counter, but my contention was to call a template inside a for each loop and pass the position() as a parameter)

Please let me know if you have any suggestions on where to go with this. I have some XSL experience, but this is a bit different than what I'm used to.

Thanks in advance.

EDIT:

The output should come out looking something like this:

1A Transmitter info
2A Filing Institution Info
2B Financial Institution Info
3A Suspicious Activity Info
9A Suspicious Activity Summary Info
2B Financial Institution 2 Info
3A Suspicious Activity 2 Info
4A Subject 1 Info
4A Subject 2 Info
4A Subject 3 Info
9B Filing institution   Summary info

Here's some XSL that I have tried, but I determined would not work because the loops are looping over all the record types in the whole document and not just the ones following the sibling element acting as the parent:

<xsl:template match="/bsar:BSAForm">
    <xsl:for-each select="bsar:FilingInstitutionInformation"> 
        <xsl:call-template name="FileInstInfo"/> <!--2A-->
        <xsl:for-each select="../bsar:FinancialInstitutionInformation"> 
            <xsl:call-template name="FinInstActivity"/> <!--2B-->
            <xsl:for-each select="../bsar:SuspiciousActivityInformation">
                <xsl:call-template name="SuspActivityInfo"/> <!--3A-->
                <xsl:for-each select="../bsar:SubjectInformation">
                    <xsl:call-template name="Subject"/> <!--4A-->
                </xsl:for-each>
                <xsl:for-each select="../bsar:SuspiciousActivityInformationNarrative">
                    <xsl:call-template name="NarrativeDesc"/> <!--5A-->
                </xsl:for-each>
                <xsl:call-template name="SuspActivityInfoSmry"/> <!--9A-->
            </xsl:for-each>
        </xsl:for-each>
        <xsl:call-template name="FileInstSmry"/> <!--9B-->
    </xsl:for-each>
    <xsl:call-template name="FileSmry"/> <!--9Z-->
</xsl:template>

<xsl:template name="FileInstInfo" match="bsar:FilingInstitutionInformation">

    <xsl:variable name="FIType" select="bsar:FIType"/>
    <xsl:variable name="SecFuType" select="bsar:SecuritiesFuturesType"/>
    <xsl:variable name="FIId" select="bsar:FIIdentification"/>
    <xsl:variable name="FIIdType" select="$FIId/ucc:FIIDType"/>
    <xsl:variable name="Addr" select="bsar:FIAddress"/>
    <xsl:variable name="Country" select="$Addr/ucc:Country"/>
    <xsl:variable name="ZIP" select="translate($Addr/ucc:ZIP, translate($Addr/ucc:ZIP, '0123456789', ''), '')"/>
    <xsl:variable name="FinInstType" select="$FIType/ucc:FinInsType"/>

    <!-- 1-2(2) Record Type -->
    <xsl:text xml:space="preserve">2A</xsl:text>

    <!-- 3-4(2) Part IV Primary Federal Regulator -->
    <xsl:call-template name="append-pad">
        <xsl:with-param name="text" select="bsar:PrimaryRegulator"/>
        <xsl:with-param name="length" select="2"/>
    </xsl:call-template>

    <!-- 5-154(150) Part IV Filer Name -->
    <xsl:call-template name="append-pad">
        <xsl:with-param name="text" select="bsar:FilerName"/>
        <xsl:with-param name="length" select="150"/>
    </xsl:call-template>

    <!-- 155-179(25) Part IV TIN -->
    <xsl:call-template name="append-pad">
        <xsl:with-param name="text" select="translate(bsar:TIN, translate(bsar:TIN, '0123456789', ''), '')"/>
        <xsl:with-param name="length" select="25"/>
    </xsl:call-template>

    <!-- 180(1) Part IV TIN Type -->
    <xsl:call-template name="append-pad">
        <xsl:with-param name="text" select="bsar:TINTYPE"/>
        <xsl:with-param name="length" select="1"/>
    </xsl:call-template>

    <!-- 181(1) Part IV Type of Financial Institution -->
    <xsl:call-template name="append-pad">
        <xsl:with-param name="text" select="$FinInstType"/>
        <xsl:with-param name="length" select="1"/>
    </xsl:call-template>

    <!-- 182-231(50) Part IV Type of Financial Institution - Other -->
    <xsl:variable name="FinInstTypeOther">
        <xsl:choose>
            <xsl:when test="$FinInstType = 'Z'">
                <xsl:value-of select="$FIType/ucc:OtherSpecify"/>
            </xsl:when>
            <xsl:otherwise>
                <xsl:value-of select="''"/>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:variable>

    <xsl:call-template name="append-pad">
        <xsl:with-param name="text" select="$FinInstTypeOther"/>
        <xsl:with-param name="length" select="50"/>
    </xsl:call-template>

    <!-- 232-244(13) Part IV Type of Securities and Futures Institution -->
    <xsl:variable name="SecFuInstType">
        <xsl:choose>
            <xsl:when test="$FinInstType = 'E'">
                <xsl:for-each select="$SecFuType/*">
                    <xsl:if test="position() != last()">
                        <xsl:value-of select="."/>
                    </xsl:if>
                </xsl:for-each>
            </xsl:when>
            <xsl:otherwise>
                <xsl:value-of select="''"/>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:variable>

    <xsl:call-template name="append-pad">
        <xsl:with-param name="text" select="$SecFuInstType"/>
        <xsl:with-param name="length" select="13"/>
    </xsl:call-template>

    <!-- 245-294(50) Part IV Type of Securities and Futures Institution - Other -->
    <xsl:variable name="SecFuInstOtherSpecify">
        <xsl:choose>
            <xsl:when test="contains($SecFuInstType,'Z')">
                <xsl:value-of select="$SecFuType/bsar:OtherSpecify"/>
            </xsl:when>
            <xsl:otherwise>
                <xsl:value-of select="''"/>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:variable>

    <xsl:call-template name="append-pad">
        <xsl:with-param name="text" select="$SecFuInstOtherSpecify"/>
        <xsl:with-param name="length" select="50"/>
    </xsl:call-template>

    <!-- 295(1) Part IV Financial Institution Identification Type -->
    <xsl:call-template name="append-pad">
        <xsl:with-param name="text" select="$FIIdType"/>
        <xsl:with-param name="length" select="1"/>
    </xsl:call-template>

    <!-- 296-315(20) Part IV Financial Institution Identification Number -->
    <xsl:variable name="FIIdNumber">
        <xsl:choose>
            <xsl:when test="$FIIdType != ''">
                <xsl:value-of select="$FIId/ucc:FIIDNumber"/>
            </xsl:when>
            <xsl:otherwise>
                <xsl:value-of select="''"/>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:variable>

    <xsl:call-template name="append-pad">
        <xsl:with-param name="text" select="$FIIdNumber"/>
        <xsl:with-param name="length" select="20"/>
    </xsl:call-template>

    <!-- 316-415(100) Part IV Address -->
    <xsl:call-template name="append-pad">
        <xsl:with-param name="text" select="$Addr/ucc:Address"/>
        <xsl:with-param name="length" select="100"/>
    </xsl:call-template>

    <!-- 416-465(50) Part IV City -->
    <xsl:call-template name="append-pad">
        <xsl:with-param name="text" select="$Addr/ucc:City"/>
        <xsl:with-param name="length" select="50"/>
    </xsl:call-template>

    <!-- 466-468(3) Part IV State -->
    <xsl:variable name="State">
        <xsl:choose>
            <xsl:when test="$Country = 'CA' or $Country = 'US' or $Country = 'MX'">
                <xsl:value-of select="$Addr/ucc:State"/>
            </xsl:when>
            <xsl:otherwise>
                <xsl:value-of select="''"/>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:variable>

    <xsl:call-template name="append-pad">
        <xsl:with-param name="text" select="$State"/>
        <xsl:with-param name="length" select="3"/>
    </xsl:call-template>

    <!-- 469-477(9) Part IV Zip / Postal Code -->
    <xsl:variable name="ZipCode">
        <xsl:choose>
            <xsl:when test="$Country = 'US' and (string-length($ZIP) = 9 and (substring($ZIP, 6, 9) = '0000' or substring($ZIP, 6, 9) = '9999'))">
                <xsl:value-of select="substring($ZIP, 1, 5)"/>
            </xsl:when>
            <xsl:otherwise>
                <xsl:value-of select="$ZIP"/>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:variable>

    <xsl:call-template name="append-pad">
        <xsl:with-param name="text" select="$ZipCode"/>
        <xsl:with-param name="length" select="9"/>
    </xsl:call-template>

    <!-- 478-479(2) Part IV Country -->
    <xsl:call-template name="append-pad">
        <xsl:with-param name="text" select="$Country"/>
        <xsl:with-param name="length" select="2"/>
    </xsl:call-template>

    <!-- 480-629(150) Part IV Alternate Name -->
    <xsl:call-template name="append-pad">
        <xsl:with-param name="text" select="./bsar:AlternateName"/>
        <xsl:with-param name="length" select="150"/>
    </xsl:call-template>

    <!-- 630-1190(561) Filler -->
    <xsl:call-template name="append-pad">
        <xsl:with-param name="text" select="''"/>
        <xsl:with-param name="length" select="561"/>
    </xsl:call-template>

    <!-- 1191-1200(10) User Field -->
    <xsl:call-template name="append-pad">
        <xsl:with-param name="text" select="''"/>
        <xsl:with-param name="length" select="10"/>
    </xsl:call-template>

    <xsl:value-of select="$newline" />

</xsl:template>

<xsl:template name="append-pad">
    <!-- recursive template to left justify and append  -->
    <!-- the value with whatever padding is passed in   -->
    <xsl:param name="padding" xml:space="preserve"> </xsl:param>
    <xsl:param name="text"/>
    <xsl:param name="length"/>
    <xsl:choose>
        <xsl:when test="string-length($text) &lt; $length">
            <xsl:call-template name="append-pad">
                <xsl:with-param name="padding" select="$padding"/>
                <xsl:with-param name="text" select="concat($text,$padding)"/>
                <xsl:with-param name="length" select="$length"/>
            </xsl:call-template>
        </xsl:when>
        <xsl:otherwise>
            <xsl:value-of select="substring($text,1,$length)"/>
        </xsl:otherwise>
    </xsl:choose>
</xsl:template> 

This first section should produce the following output: (spacing ommitted for this post)

2AD New Banking Corp.373637383ACD654646321321Ave XBrooklynNY11235USalternate name

Upvotes: 1

Views: 254

Answers (1)

Jesse Roper
Jesse Roper

Reputation: 1309

I'm not sure if anyone really understood my question, but if anyone comes here facing a similar problem, here is how I solved it:

<xsl:template match="/bsar:BSAForm">
    <xsl:call-template name="Transmitter"/>
    <xsl:apply-templates select="bsar:FilingInstitutionInformation" />
    <xsl:call-template name="FileSmry"/>
</xsl:template>

<xsl:template match="bsar:FilingInstitutionInformation">

    <xsl:variable name="FileInstHeader" select="."/>

    <xsl:call-template name="FileInstInfo"/>

    <!--For each 2B before the next 2A-->
    <xsl:for-each select="following-sibling::bsar:FinancialInstitutionInformation[preceding-sibling::bsar:FilingInstitutionInformation[1] = $FileInstHeader]">
        <!--Output 2B-->
        <xsl:call-template name="FinInstActivity"/>
        <xsl:variable name="FinInstHeader" select="."/>
        <!--For each 3A before the next 2B-->
        <xsl:for-each select="following-sibling::bsar:SuspiciousActivityInformation[preceding-sibling::bsar:FinancialInstitutionInformation[1] = $FinInstHeader]">
            <!--Output 3A; Increment counter-->
            <xsl:variable name="TranSeqNum">
                <xsl:number count="bsar:SuspiciousActivityInformation" />
            </xsl:variable>
            <xsl:call-template name="SuspActivityInfo">
                <xsl:with-param name="TranSeqNum" select="$TranSeqNum"/>
            </xsl:call-template>
            <xsl:variable name="SuspActHeader" select="."/>
            <!--For each 4A before the next 3A-->
            <xsl:for-each select="following-sibling::bsar:SubjectInformation[preceding-sibling::bsar:SuspiciousActivityInformation[1] = $SuspActHeader]">
                <!--Output 4A with above counter-->
                <xsl:call-template name="Subject">
                    <xsl:with-param name="TranSeqNum" select="$TranSeqNum"/>
                </xsl:call-template>
            </xsl:for-each>
            <!--Output 9A-->
            <!--<xsl:call-template name="SuspActivityInfoSmry"/>-->
        </xsl:for-each>
    </xsl:for-each>

    <!--Output 9B-->
    <xsl:call-template name="FileInstSmry"/>

</xsl:template>

The "Transmitter" record needs to be shown once at the beginning (showing that template is irrelevant) and the FileInstSmry record needs to be shown once at the ending. Everything else is grouped by 2A records. Calling will call the template for each of those tags found in the document. For each of them found, the details of the template will be called () and then the inner looping runs each time the FilingInsitutionInformation template is run.

FileInstHeader contains the parent element, so the first for each loop runs until another one of those elements is hit. The header variable is set to the next parent and the looping continues. I haven't figured out the counters for 3A and 4A sections yet, but I can update this at that point if anyone is interested.

Upvotes: 2

Related Questions