Home > Software engineering >  Get unique number for tag CASH_RECEIPT_LINE_NO in XML using XSLT1.0
Get unique number for tag CASH_RECEIPT_LINE_NO in XML using XSLT1.0

Time:10-08

Below is my XML input file

<?xml version="1.0" encoding="UTF-8"?>
<ns3:Bonger xmlns:ns3="http://NEXSTEP.Schemas.Bonger" xmlns:ns2="http://NEXSTEP.Schemas.NexstepTypes">
  <ROUTE_RECORD>
    <ns2:SENDER Sender_code="BO_SERVER"/>
    <ns2:RECEIPIENT Receipient_code="MASTER"/>
    <ns2:MESSAGE_ID Type_name="Bonger" Version_number="1.0"/>
    <ns2:DATE Date_of_preparation="2021-09-17 02:00" Time_of_preparation="09:20:30"/>
    <ns2:OverAllStatus>NY</ns2:OverAllStatus>
  </ROUTE_RECORD>
  <MESSAGE_RECORD>
    <InsertChange>
      <Bongnr>T10-116</Bongnr>
      <DokumentType>B</DokumentType>
      <DokumentNr>T10-116</DokumentNr>
      <VareLager>STA</VareLager>
      <SalgsKampanjer>
        <SalgsKampanje>
          <KampanjeKode>RAB_BUT</KampanjeKode>
          <KampanjeBeskrivelse>RABATT KAMPANJE</KampanjeBeskrivelse>
          <KampanjeSumEksVat>-119.2000000000000028421709430404007434844970703125</KampanjeSumEksVat>
          <KampanjeSumInkVat>249</KampanjeSumInkVat>
          <KampanjaMvaKode>103</KampanjaMvaKode>
          <KampanjeMvaSats>25</KampanjeMvaSats>
        </SalgsKampanje>
      </SalgsKampanjer>
      <totalSum>
        <ns2:BelopFelt>238.40</ns2:BelopFelt>
        <ns2:Valutakode>NOK</ns2:Valutakode>
      </totalSum>
    </InsertChange>
  </MESSAGE_RECORD>
</ns3:Bonger>

I have the XSLT as below.

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:ns3="http://NEXSTEP.Schemas.Bonger" xmlns:ns2="http://NEXSTEP.Schemas.NexstepTypes" exclude-result-prefixes="ns2 ns3">
   <xsl:output method="xml" encoding="ISO-8859-1" indent="yes"/>
   <xsl:template match="*">
        <xsl:element name="{name()}" namespace="{namespace-uri()}">
            <xsl:apply-templates/>
        </xsl:element>
    </xsl:template>
    <xsl:template match="/ns3:Bonger">
           <xsl:if test="MESSAGE_RECORD/InsertChange/DokumentType = 'S' ">
              <xsl:message terminate="yes">
                Transformation is terminated due to DokumentType being `S`
              </xsl:message>
           </xsl:if>
           <xsl:if test="MESSAGE_RECORD/InsertChange/DokumentType != 'S' ">
        <CASH_RECEIPT_LOG xmlns:xsi="urn:ifsworld-com:schemas:receive_cash_receipt_pos" xmlns:fo="http://www.w3.org/1999/XSL/Format">
            <MSG_CONTRACT>
                <xsl:value-of select="MESSAGE_RECORD/InsertChange/VareLager"/>
            </MSG_CONTRACT>
            <CASH_RECEIPTS>
                <CASH_RECEIPT>
                    <CASH_RECEIPT_NO>
                        <xsl:value-of select="MESSAGE_RECORD/InsertChange/Bongnr"/>
                    </CASH_RECEIPT_NO>
                    <LINES>
                        <xsl:for-each select="MESSAGE_RECORD/InsertChange">
                            <xsl:for-each select="SalgsKampanjer/SalgsKampanje">
                              <xsl:if test="KampanjeSumInkVat > 0">     
                              <CASH_RECEIPT_LINE>
                                        <CASH_RECEIPT_LINE_NO>
                                          <xsl:value-of select="position()   5000"/>
                                        </CASH_RECEIPT_LINE_NO>
                                        <INTERNAL_TRANSACTION_CODE>DISCOUNT</INTERNAL_TRANSACTION_CODE>
                                        <EXTERNAL_TRANSACTION_CODE>
                                          <xsl:value-of select="KampanjeKode"/>
                                        </EXTERNAL_TRANSACTION_CODE>
                                        <REFERENCE></REFERENCE>
                                        <ACTUAL_AMOUNT>
                                            <xsl:value-of select="KampanjeSumEksVat"/>
                                        </ACTUAL_AMOUNT>
                                        <QUANTITY>1</QUANTITY>
                                        <TOTAL_AMOUNT>
                                            <xsl:value-of select="KampanjeSumEksVat"/>
                                        </TOTAL_AMOUNT>
                                        <CURRENCY_CODE>
                                            <xsl:value-of select="../../totalSum/ns2:Valutakode"/>
                                        </CURRENCY_CODE>
                                        <FREE_TEXT_1>
                                            <xsl:value-of select="KampanjeBeskrivelse"/>
                                        </FREE_TEXT_1>
                                    </CASH_RECEIPT_LINE>
                                </xsl:if>
                                <xsl:variable name="variant" select="-translate(translate(KampanjeSumInkVat,'-','') - translate(KampanjeSumEksVat,'-',''),'-','')"></xsl:variable>
                                <xsl:if test="$variant != 0">       
                              <CASH_RECEIPT_LINE>
                                        <CASH_RECEIPT_LINE_NO>
                                           <xsl:value-of select="position()   1   5000"/>
                                        </CASH_RECEIPT_LINE_NO>
                                        <INTERNAL_TRANSACTION_CODE>VATRET</INTERNAL_TRANSACTION_CODE>
                                        <EXTERNAL_TRANSACTION_CODE>
                                          <xsl:value-of select="KampanjaMvaKode"/>
                                        </EXTERNAL_TRANSACTION_CODE>
                                        <ACTUAL_AMOUNT>
                                            <xsl:value-of select="$variant"></xsl:value-of>
                                        </ACTUAL_AMOUNT>
                                        <QUANTITY>0</QUANTITY>
                                        <TOTAL_AMOUNT>
                                          <xsl:value-of select="$variant"></xsl:value-of>
                                        </TOTAL_AMOUNT>
                                        <CURRENCY_CODE>
                                            <xsl:value-of select="../../totalSum/ns2:Valutakode"/>
                                        </CURRENCY_CODE>
                                    </CASH_RECEIPT_LINE>
                                </xsl:if>
                            </xsl:for-each>
                        </xsl:for-each>
                    </LINES>
                </CASH_RECEIPT>
            </CASH_RECEIPTS>
        </CASH_RECEIPT_LOG>
            </xsl:if>
    </xsl:template>
</xsl:stylesheet>

My final output after transformer is as below.

<?xml version="1.0" encoding="ISO-8859-1"?>
<CASH_RECEIPT_LOG xmlns:fo="http://www.w3.org/1999/XSL/Format"
                  xmlns:xsi="urn:ifsworld-com:schemas:receive_cash_receipt_pos">
   <MSG_CONTRACT>STA</MSG_CONTRACT>
   <CASH_RECEIPTS>
      <CASH_RECEIPT>
         <CASH_RECEIPT_NO>T10-116</CASH_RECEIPT_NO>
         <LINES>
            <CASH_RECEIPT_LINE>
               <CASH_RECEIPT_LINE_NO>5001</CASH_RECEIPT_LINE_NO>
               <INTERNAL_TRANSACTION_CODE>DISCOUNT</INTERNAL_TRANSACTION_CODE>
               <EXTERNAL_TRANSACTION_CODE>RAB_BUT</EXTERNAL_TRANSACTION_CODE>
               <REFERENCE/>
               <ACTUAL_AMOUNT>-119.2000000000000028421709430404007434844970703125</ACTUAL_AMOUNT>
               <QUANTITY>1</QUANTITY>
               <TOTAL_AMOUNT>-119.2000000000000028421709430404007434844970703125</TOTAL_AMOUNT>
               <CURRENCY_CODE>NOK</CURRENCY_CODE>
               <FREE_TEXT_1>RABATT KAMPANJE</FREE_TEXT_1>
            </CASH_RECEIPT_LINE>
            <CASH_RECEIPT_LINE>
               <CASH_RECEIPT_LINE_NO>5002</CASH_RECEIPT_LINE_NO>
               <INTERNAL_TRANSACTION_CODE>VATRET</INTERNAL_TRANSACTION_CODE>
               <EXTERNAL_TRANSACTION_CODE>103</EXTERNAL_TRANSACTION_CODE>
               <ACTUAL_AMOUNT>-129.8</ACTUAL_AMOUNT>
               <QUANTITY>0</QUANTITY>
               <TOTAL_AMOUNT>-129.8</TOTAL_AMOUNT>
               <CURRENCY_CODE>NOK</CURRENCY_CODE>
            </CASH_RECEIPT_LINE>
         </LINES>
      </CASH_RECEIPT>
   </CASH_RECEIPTS>
</CASH_RECEIPT_LOG>

My query is related to CASH_RECEIPT_LINE_NO. At this point its ok. But for example if there are two SalgsKampanjer/SalgsKampanje records CASH_RECEIPT_LINE_NO will be duplicated.

Is there any way I can modify the below code so that it will give me unique CASH_RECEIPT_LINE_NOs (e.g: 5001,5002, 5003.... etc.)

<CASH_RECEIPT_LINE_NO>
    <xsl:value-of select="position()   5000"/>
</CASH_RECEIPT_LINE_NO>

CodePudding user response:

If you intend to create 2 lines for each SalgsKampanje and you want to have consecutive numbering for all lines, then use:

<CASH_RECEIPT_LINE_NO>
    <xsl:value-of select="2 * position()   4999"/>
</CASH_RECEIPT_LINE_NO>

for the first instance and:

<CASH_RECEIPT_LINE_NO>
    <xsl:value-of select="2 * position()   5000"/>
</CASH_RECEIPT_LINE_NO>

for the second one.


P.S Your first template does not do anything. And for mutually exclusive conditions you should be using xsl:choose instead of multiple xsl:if instructions that repeat the same test. And do you really need the output to carry an xmlns:fo namespace declaration?

  • Related