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

Popular posts from this blog

html - Outlook 2010 Anchor (url/address/link) -

javascript - Why does running this loop 9 times take 100x longer than running it 8 times? -

Getting gateway time-out Rails app with Nginx + Puma running on Digital Ocean -