xml - XSLT 2.0, templates and matching -
xslt newbie (thanks in advance)
i have xml file containing payment data. trying transform xml format used bank. xml needs different based on payment type (urgent payment/wire, standard payment/etf or manual payment). multiple payments possible in given file. here sample of source xml (simplified, 2 transactions, both same payment type)
<payments> <payment xmlns:ns="urn:com.bank/paymentconnector"> <payment_detail> <payment_info> <ns:payment_payment_memo>payment info1</ns:payment_payment_memo> <ns:payment_payment_amount>1111</ns:payment_payment_amount> <ns:payment_type>wire</ns:payment_type> <ns:payment_currency_code>usd</ns:payment_currency_code> <ns:payment_check_or_advice_number>0</ns:payment_check_or_advice_number> </payment_info> <payer_data> <ns:payer_company_name>company, llp</ns:payer_company_name> <ns:payer_address_line_1>main st</ns:payer_address_line_1> <ns:payer_address_line_2>line 2</ns:payer_address_line_2> <ns:payer_city>cleveland</ns:payer_city> <ns:payer_zip_code>11111</ns:payer_zip_code> <ns:payer_country>us</ns:payer_country> <ns:payer_account_number>1111-11111111</ns:payer_account_number> <ns:payer_currency>usd</ns:payer_currency> </payer_data> <payee_data> <ns:payee_name>name</ns:payee_name> <ns:payee_bank_name>bank name</ns:payee_bank_name> <ns:payee_bank_account_name>account name</ns:payee_bank_account_name> <ns:payee_account_number>1111111</ns:payee_account_number> <ns:payee_masked_account_number>********** </ns:payee_masked_account_number> <ns:payee_account_type>dd</ns:payee_account_type> <ns:payee_routing_transit_number>22222</ns:payee_routing_transit_number> <ns:payee_bank_country>us</ns:payee_bank_country> </payee_data> </payment_detail> </payment> <payment> <payment_detail> <payment_info> <ns:payment_payment_memo>payment info2</ns:payment_payment_memo> <ns:payment_payment_amount>22222</ns:payment_payment_amount> <ns:payment_type>wire</ns:payment_type> <ns:payment_currency_code>usd</ns:payment_currency_code> <ns:payment_check_or_advice_number>0</ns:payment_check_or_advice_number> </payment_info> <payer_data> <ns:payer_company_name>company, llp</ns:payer_company_name> <ns:payer_address_line_1>main st</ns:payer_address_line_1> <ns:payer_address_line_2>line 2</ns:payer_address_line_2> <ns:payer_city>cleveland</ns:payer_city> <ns:payer_zip_code>11111</ns:payer_zip_code> <ns:payer_country>us</ns:payer_country> <ns:payer_account_number>1111-11111111</ns:payer_account_number> <ns:payer_currency>usd</ns:payer_currency> </payer_data> <payee_data> <ns:payee_name>name</ns:payee_name> <ns:payee_bank_name>bank name</ns:payee_bank_name> <ns:payee_bank_account_name>account name</ns:payee_bank_account_name> <ns:payee_account_number>1111111</ns:payee_account_number> <ns:payee_masked_account_number>**********</ns:payee_masked_account_number> <ns:payee_account_type>dd</ns:payee_account_type> <ns:payee_routing_transit_number>22222</ns:payee_routing_transit_number> <ns:payee_bank_country>us</ns:payee_bank_country> </payee_data> </payment_detail> </payments>
here (simplified) output
<?xml version="1.0" encoding="utf-8"?> <!-- urgent payment--> <urgent_payment_header> <header_fields/> </urgent_payment_header> <paymentrec> <recordtype>5</recordtype> <payeraccnum>1111-11111111</payeraccnum> <!-- (other fields)--> </paymentrec> <paymentrec> <recordtype>5</recordtype> <payeraccnum></payeraccnum> <!-- continue other urgent payments in file--> </paymentrec> <urgent_control_fields> </urgent_control_fields> <!-- standard payment--> <standard_payment_header> <header_fields/> </standard_payment_header> <paymentrec> <recordtype>4</recordtype> <payeraccnum>1111-11111111</payeraccnum> <!-- (other fields)--> </paymentrec> <paymentrec> <recordtype>4</recordtype> <payeraccnum></payeraccnum> <!-- continue other standard payments in file--> </paymentrec> <standard_control_fields> </standard_control_fields> <!-- catch payments--> <catchall_payment_header> <header_fields/> </catchall_payment_header> <paymentrec> <recordtype>3</recordtype> <payeraccnum>1111-11111111</payeraccnum> <!-- (other fields)--> </paymentrec> <paymentrec> <recordtype>3</recordtype> <payeraccnum></payeraccnum> <!-- continue other catchall payments in file--> </paymentrec> <catchall_control_fields> </catchall_control_fields>
my xslt works when of payments in source file same type (all urgent, standard, other types) 1 header, payment records listed out , 1 control record
however, when payment types mixed (for example, 1 urgent , 1 standard) header, first node , control record written output. if file contains urgent payment/wire , standard payment, want output be
here (simplified xslt)
<!-- begin writing output--> <xsl:template match="payments"> <xsl:choose> <xsl:when test="payment/payment_detail/payment_info[ns:payment_type != 'wire']"> <xsl:call-template select="payment-header"/> <xsl:apply-templates select="payment"/> <xsl:call-templates select="payment-control-standard"/> </xsl:when> <xsl:when test="payment/payment_detail/payment_info[ns:payment_type = 'wire']"> <xsl:call-template select="payment-header"/> <xsl:apply-templates select="payment"/> <xsl:call-template name="payment-control-urgent"/> </xsl:when> <xsl:otherwise> <xsl:call-template name="payment-header"/> <xsl:apply-templates select="payment"/> <xsl:call-template name="payment-control-catchall"/> </xsl:otherwise> </xsl:choose> </xsl:template> <xsl:template match="payment"> <xsl:choose> <xsl:when test="payment_detail/payment_info[ns:payment_type != 'wire']"> <xsl:call-template name="payment-standard"/> </xsl:when> <xsl:when test="payment_detail/payment_info[ns:payment_type = 'wire']"> <xsl:call-template name="payment-urgent"/> </xsl:when> <xsl:otherwise> <xsl:call-template name="payment-catchall"/> </xsl:otherwise> </xsl:choose> </xsl:template> <!-- end writing output--> <!-- begin template details--> <xsl:template name="payment-header"> <header> (header fields, details not important) </header> </xsl:template> <xsl:template name="payment-control-standard"> <control> <numberofpayments>count of standard payments in file</numberofpayments> <sumofpayments>sum of standard payments in file</sumofpayments> </control> </xsl:template> <xsl:template name="payment-control-urgent"> <control> <numberofpayments>count of urgent payments in file</numberofpayments> <sumofpayments>sum of urgent payments in file</sumofpayments> </control> </xsl:template> <xsl:template name="payment-control-catchall"> <control> <numberofpayments>count of catch payments in file</numberofpayments> <sumofpayments>sum of catch payments in file</sumofpayments> </control> </xsl:template> <xsl:template name="payment-standard"> <paymentrec> (payment fields, details not important) </paymentrec> </xsl:template> <xsl:template name="payment-urgent"> <paymentrec> (payment fields, details not important) </paymentrec> </xsl:template> <xsl:template name="payment-catchall"> <paymentrec> (payment fields, details not important) </paymentrec> </xsl:template>
the thing with
<xsl:template match="payments"> <xsl:choose> <xsl:when test="payment/payment_detail/payment_info/ns:payment_type != 'wire']">
is evaluates true if there @ least one payment
element payment_type
not 'wire'. not, want.
if 1 record in input transformed 1 record in output , nothing else done, don't need general template für payments
. so, i'd suggest completly delete template payments
, important stuff inside payment
template.
inside current template payment
can see 2 problems:
as martin honnen pointet out, have syntax error there:
]
is superfluous.by calling template via xsl:apply-templates context node
payment
,payment
in xpath expressions wrong.
Comments
Post a Comment