none
Biztalk inline XSLT group and sum by element

    Question

  • BizTalk or XSLT exports. I am very new with BizTalk and I need help to solve XML group and sum problem. I need get TaxAmount using group by TaxCode for a given VoucherRecord. Preferable with inline XSLT. Thanks.

    Input data source

    <ns0:Voucher xmlns:ns0="http://VoucherLoad.PreTransform.VoucherGroupSchema" xmlns:userVB="http://schemas.microsoft.com/BizTalk/2003/userVB">
    <VoucherRecord>
      <InvoiceNum>14230639</InvoiceNum>
      <InvoiceDate>2016-09-23</InvoiceDate>  
     <Children>
     <VoucherChildTax>
      <TaxAmount>12</TaxAmount>
      <TaxCode>V01</TaxCode>
     </VoucherChildTax>
     <VoucherChildTax>
      <TaxAmount>10</TaxAmount>
      <TaxCode>V02</TaxCode>
      </VoucherChildTax>
     <VoucherChildTax>
      <TaxAmount>7</TaxAmount>
      <TaxCode>V01</TaxCode>
      </VoucherChildTax>
     </Children>
    </VoucherRecord>
    <VoucherRecord>
      <InvoiceNum>14230727</InvoiceNum>
      <InvoiceDate>2016-03-23</InvoiceDate>  
     <Children>
     <VoucherChildTax>
      <TaxAmount>15</TaxAmount>
      <TaxCode>V02</TaxCode>
     </VoucherChildTax>
     <VoucherChildTax>
      <TaxAmount>12</TaxAmount>
      <TaxCode>V02</TaxCode>
      </VoucherChildTax>
     <VoucherChildTax>
      <TaxAmount>13</TaxAmount>
      <TaxCode>V01</TaxCode>
      </VoucherChildTax>
     <VoucherChildTax>
      <TaxAmount>8</TaxAmount>
      <TaxCode>V01</TaxCode>
      </VoucherChildTax>
     </Children>
    </VoucherRecord>
    </ns0:Voucher>

    Desire output


    <ns0:Voucher xmlns:ns0="http://VoucherLoad.PreTransform.VoucherGroupSchema" xmlns:userVB="http://schemas.microsoft.com/BizTalk/2003/userVB">
    <VoucherRecord>
      <InvoiceNum>14230639</InvoiceNum>
      <InvoiceDate>2016-09-23</InvoiceDate>  
     <Children>
     <VoucherChildTax>
      <TaxAmount>18</TaxAmount>
      <TaxCode>V01</TaxCode>
     </VoucherChildTax>
     <VoucherChildTax>
      <TaxAmount>10</TaxAmount>
      <TaxCode>V02</TaxCode>
      </VoucherChildTax>
     </Children>
    </VoucherRecord>
    <VoucherRecord>
      <InvoiceNum>14230727</InvoiceNum>
      <InvoiceDate>2016-03-23</InvoiceDate>  
     <Children>
     <VoucherChildTax>
      <TaxAmount>27</TaxAmount>
      <TaxCode>V02</TaxCode>
     </VoucherChildTax>
     <VoucherChildTax>
      <TaxAmount>21</TaxAmount>
      <TaxCode>V01</TaxCode>
      </VoucherChildTax>
     </Children>
    </VoucherRecord>
    </ns0:Voucher>

     
    Tuesday, November 8, 2016 4:02 AM

Answers

  • Hi,

    Refer: BizTalk 2010 Recipes : Document Mapping - Using XSLT Group-By

    Drop Scripting Functoid on the mapper and use below Inline XSLT:

    <xsl:for-each select="//Tax[not(TaxCode=preceding-sibling::Tax/TaxCode)]/TaxCode">
    <Tax>
    <TaxCode>
    <xsl:value-of select="current()"/>
    </TaxCode>
    <TaxAmount>
    <xsl:value-of select="sum(//Tax[TaxCode=current()]/TaxAmount)"/>
    </TaxAmount>
    </Tax>
    </xsl:for-each>

    Map:

    Output:

    <voucher>
     <Details>
      <Tax>
       <TaxCode>V01</TaxCode> 
       <TaxAmount>25</TaxAmount> 
      </Tax>
      <Tax>
       <TaxCode>V02</TaxCode> 
       <TaxAmount>44</TaxAmount> 
      </Tax>
     </Details>
    </voucher>



    Rachit Sikroria (Microsoft Azure MVP)

    Saturday, November 5, 2016 2:16 AM
    Moderator
  • Hi ZD Li,

    This XML sample is quite different from what has been shared before in earlier thread by you. Is this some new requirement?

    You need to understand that XSLT, XPATH and XML all are case sensitive. You should be very careful when providing samples of your requirement.

    Inline XSLT:

    <xsl:for-each select="//ns0:Voucher/VoucherRecord">
    <xsl:variable name="i" select="position()" />
    <VoucherRecord>
    <InvoiceNum>
    <xsl:value-of select="./InvoiceNum"/>
    </InvoiceNum>
    <InvoiceDate>
    <xsl:value-of select="./InvoiceDate"/>
    </InvoiceDate>
    <Children>
    <xsl:for-each select="../../ns0:Voucher/VoucherRecord[$i]/Children/VoucherChildTax">
    <xsl:variable name="j" select="position()" />
    <xsl:for-each select="../VoucherChildTax[$j][not(TaxCode=preceding-sibling::VoucherChildTax/TaxCode)]/TaxCode">
    <VoucherChildTax>
    <TaxAmount>
    <xsl:value-of select="sum(//VoucherRecord[$i]/Children/VoucherChildTax[TaxCode=current()]/TaxAmount)"/>
    </TaxAmount>
    <TaxCode>
    <xsl:value-of select="current()"/>
    </TaxCode>
    </VoucherChildTax>
    </xsl:for-each>
    </xsl:for-each>
    </Children>
    </VoucherRecord>
    </xsl:for-each>

    Map:

    Output:

    - <ns0:Voucher xmlns:ns0="http://VoucherLoad.PreTransform.VoucherGroupSchema">
    - <VoucherRecord>
      <InvoiceNum>14230639</InvoiceNum> 
      <InvoiceDate>2016-09-23</InvoiceDate> 
    - <Children>
    - <VoucherChildTax>
      <TaxAmount>19</TaxAmount> 
      <TaxCode>V01</TaxCode> 
      </VoucherChildTax>
    - <VoucherChildTax>
      <TaxAmount>10</TaxAmount> 
      <TaxCode>V02</TaxCode> 
      </VoucherChildTax>
      </Children>
      </VoucherRecord>
    - <VoucherRecord>
      <InvoiceNum>14230727</InvoiceNum> 
      <InvoiceDate>2016-03-23</InvoiceDate> 
    - <Children>
    - <VoucherChildTax>
      <TaxAmount>27</TaxAmount> 
      <TaxCode>V02</TaxCode> 
      </VoucherChildTax>
    - <VoucherChildTax>
      <TaxAmount>21</TaxAmount> 
      <TaxCode>V01</TaxCode> 
      </VoucherChildTax>
      </Children>
      </VoucherRecord>
      </ns0:Voucher>


    Rachit Sikroria (Microsoft Azure MVP)

    Tuesday, November 8, 2016 9:50 AM
    Moderator
  • Hi ZD Li,

    I have given you pointers on the approach that you need to follow. With the changing requirements, its important that you learn XSLT and BizTalk Mapping for your own benefit.

    Do some POCs around grouping and sorting.

    Refer the links below:

    BizTalk 2010 Recipes : Document Mapping - Using XSLT Group-By

    BizTalk Training – Mapping – How to implement multi-level Muenchian grouping in BizTalk Maps

    GoodLuck!

    PS: The input message you provided is not a valid XML. You should handle the complete mapping in Inline XSLT instead of try to map only specific part as there are nested loops involved.


    Rachit Sikroria (Microsoft Azure MVP)

    Wednesday, November 9, 2016 11:28 AM
    Moderator

All replies

  • I am doing BizTalk project and need to sum TaxAmount by TaxCode as shown below:


    SOurce

    <voucher>
      <Details>
      <Tax>
      <TaxCode>V01</TaxCode>
      <TaxAmount>10.0</TaxAmount>
      </Tax>
      <Tax>
      <TaxCode>V02</TaxCode>
      <TaxAmount>12.0</TaxAmount>
      </Tax>
      <Tax>
      <TaxCode>V01</TaxCode>
      <TaxAmount>15.0</TaxAmount>
      </Tax>
      <Tax>
      <TaxCode>V02</TaxCode>
      <TaxAmount>32.0</TaxAmount>
      </Tax>
      </Details>
    </voucher>

    Desire Output

    <voucher>
      <Details>
      <Tax>
      <TaxCode>V01</TaxCode>
      <TaxAmount>20.0</TaxAmount>
      </Tax>
      <Tax>
      <TaxCode>V02</TaxCode>
      <TaxAmount>44.0</TaxAmount>
      </Tax> 
      </Details>
    </voucher>

    I did read Johan Hedberg  block and article "BizTalk Training – Mapping – How to implement multi-level Muenchian grouping in BizTalk Maps" but still couldn't find way to make it work. Please give details as I am very new with BizTalk mapping and xslt. Thanks.

    Friday, November 4, 2016 9:34 PM
  • Hi,

    Refer: BizTalk 2010 Recipes : Document Mapping - Using XSLT Group-By

    Drop Scripting Functoid on the mapper and use below Inline XSLT:

    <xsl:for-each select="//Tax[not(TaxCode=preceding-sibling::Tax/TaxCode)]/TaxCode">
    <Tax>
    <TaxCode>
    <xsl:value-of select="current()"/>
    </TaxCode>
    <TaxAmount>
    <xsl:value-of select="sum(//Tax[TaxCode=current()]/TaxAmount)"/>
    </TaxAmount>
    </Tax>
    </xsl:for-each>

    Map:

    Output:

    <voucher>
     <Details>
      <Tax>
       <TaxCode>V01</TaxCode> 
       <TaxAmount>25</TaxAmount> 
      </Tax>
      <Tax>
       <TaxCode>V02</TaxCode> 
       <TaxAmount>44</TaxAmount> 
      </Tax>
     </Details>
    </voucher>



    Rachit Sikroria (Microsoft Azure MVP)

    Saturday, November 5, 2016 2:16 AM
    Moderator
  • That is sweet! Thank you so much Rachit. I will give a try shortly.
    Monday, November 7, 2016 2:34 PM
  • Hi Rachit, I just tested it and it indeed work very well if my input data is just like what I initially posted. However, when my Voucher elements are repetitive it fails. For example (see below). Please recommend changes. Thanks again.


    Input data:
    <Root>
    <voucher>
       <Details>
       <Tax>
       <TaxCode>V01</TaxCode>
       <TaxAmount>10.0</TaxAmount>
       </Tax>
       <Tax>
       <TaxCode>V02</TaxCode>
       <TaxAmount>12.0</TaxAmount>
       </Tax>
       <Tax>
       <TaxCode>V01</TaxCode>
       <TaxAmount>15.0</TaxAmount>
       </Tax>
       <Tax>
       <TaxCode>V02</TaxCode>
       <TaxAmount>32.0</TaxAmount>
       </Tax>
       </Details>
     </voucher>
     <voucher>
       <Details>
       <Tax>
       <TaxCode>V11</TaxCode>
       <TaxAmount>15.0</TaxAmount>
       </Tax>
       <Tax>
       <TaxCode>V12</TaxCode>
       <TaxAmount>13.0</TaxAmount>
       </Tax>
       <Tax>
       <TaxCode>V11</TaxCode>
       <TaxAmount>12.0</TaxAmount>
       </Tax>
       <Tax>
       <TaxCode>V12</TaxCode>
       <TaxAmount>18.0</TaxAmount>
       </Tax>
       </Details>
     </voucher>
     .........
     </Root>
     
     Desire output
     
     <Root>
     <voucher>
       <Details>
       <Tax>
       <TaxCode>V01</TaxCode>
       <TaxAmount>20.0</TaxAmount>
       </Tax>
       <Tax>
       <TaxCode>V02</TaxCode>
       <TaxAmount>44.0</TaxAmount>
       </Tax> 
       </Details>
     </voucher>
     <voucher>
       <Details>
       <Tax>
       <TaxCode>V11</TaxCode>
       <TaxAmount>27.0</TaxAmount>
       </Tax>
       <Tax>
       <TaxCode>V12</TaxCode>
       <TaxAmount>31.0</TaxAmount>
       </Tax> 
       </Details>
     </voucher>
     ..........
     </Root>


    • Edited by ZD Li Monday, November 7, 2016 3:59 PM
    Monday, November 7, 2016 3:26 PM
  • Hi,

    In that case use below:

    Inline XSLT:

    <xsl:for-each select="//Root[not(voucher=preceding-sibling::Root/voucher)]/voucher">
    <xsl:variable name="i" select="position()" />
    <voucher>
    <Details>
    <xsl:for-each select="../../Root/voucher[$i]/Details/Tax">
    <xsl:variable name="j" select="position()" />
    <xsl:for-each select="../Tax[$j][not(TaxCode=preceding-sibling::Tax/TaxCode)]/TaxCode">
    <Tax>
    <TaxCode>
    <xsl:value-of select="current()"/>
    </TaxCode>
    <TaxAmount>
    <xsl:value-of select="sum(//Tax[TaxCode=current()]/TaxAmount)"/>
    </TaxAmount>
    </Tax>
    </xsl:for-each>
    </xsl:for-each>
    </Details>
    </voucher>
    </xsl:for-each>

    Map:

    Output:

    <Root>
     <voucher>
      <Details>
       <Tax>
        <TaxCode>V01</TaxCode> 
        <TaxAmount>25</TaxAmount> 
       </Tax>
       <Tax>
        <TaxCode>V02</TaxCode> 
        <TaxAmount>44</TaxAmount> 
       </Tax>
      </Details>
     </voucher>
     <voucher>
      <Details>
       <Tax>
        <TaxCode>V11</TaxCode> 
        <TaxAmount>27</TaxAmount> 
       </Tax>
       <Tax>
        <TaxCode>V12</TaxCode> 
        <TaxAmount>31</TaxAmount> 
       </Tax>
      </Details>
     </voucher>
    </Root


    Rachit Sikroria (Microsoft Azure MVP)

    Monday, November 7, 2016 7:54 PM
    Moderator
  • Thanks so much Rachit again. I did try it and somehow I lost <Voucher> element. Also I do not see grouped TaxCode and TaxAmount. Maybe I did something wrong.
    Tuesday, November 8, 2016 4:05 AM
  • Thanks so much Rachit again. I did try it and somehow I lost <Voucher> element. Also I do not see grouped TaxCode and TaxAmount. Maybe I did something wrong.
    The code I gave you should work, just try to debug it from visual studio. Because xslt is case sensitive, check if the code i gave you matches the elements. For startup- check if it is voucher or Voucher, change accordingly.

    Rachit Sikroria (Microsoft Azure MVP)

    Tuesday, November 8, 2016 4:32 AM
    Moderator
  • Hi ZD Li,

    I think this is a duplicate thread.

    https://social.msdn.microsoft.com/Forums/en-US/d26b80db-198c-46b3-a663-56d2fa3d5b59/biztalk-map-to-group-and-sum-data-elements?forum=biztalkgeneral

    Please continue there. Rachit has already provided valuable inputs towards your xslt.


    Pi_xel_xar

    Blog: My Blog

    BizTalkApplicationDeploymentTool: BizTalk Application Deployment Tool/

    Tuesday, November 8, 2016 8:21 AM
    Answerer
  • Hi ZD Li,

    This XML sample is quite different from what has been shared before in earlier thread by you. Is this some new requirement?

    You need to understand that XSLT, XPATH and XML all are case sensitive. You should be very careful when providing samples of your requirement.

    Inline XSLT:

    <xsl:for-each select="//ns0:Voucher/VoucherRecord">
    <xsl:variable name="i" select="position()" />
    <VoucherRecord>
    <InvoiceNum>
    <xsl:value-of select="./InvoiceNum"/>
    </InvoiceNum>
    <InvoiceDate>
    <xsl:value-of select="./InvoiceDate"/>
    </InvoiceDate>
    <Children>
    <xsl:for-each select="../../ns0:Voucher/VoucherRecord[$i]/Children/VoucherChildTax">
    <xsl:variable name="j" select="position()" />
    <xsl:for-each select="../VoucherChildTax[$j][not(TaxCode=preceding-sibling::VoucherChildTax/TaxCode)]/TaxCode">
    <VoucherChildTax>
    <TaxAmount>
    <xsl:value-of select="sum(//VoucherRecord[$i]/Children/VoucherChildTax[TaxCode=current()]/TaxAmount)"/>
    </TaxAmount>
    <TaxCode>
    <xsl:value-of select="current()"/>
    </TaxCode>
    </VoucherChildTax>
    </xsl:for-each>
    </xsl:for-each>
    </Children>
    </VoucherRecord>
    </xsl:for-each>

    Map:

    Output:

    - <ns0:Voucher xmlns:ns0="http://VoucherLoad.PreTransform.VoucherGroupSchema">
    - <VoucherRecord>
      <InvoiceNum>14230639</InvoiceNum> 
      <InvoiceDate>2016-09-23</InvoiceDate> 
    - <Children>
    - <VoucherChildTax>
      <TaxAmount>19</TaxAmount> 
      <TaxCode>V01</TaxCode> 
      </VoucherChildTax>
    - <VoucherChildTax>
      <TaxAmount>10</TaxAmount> 
      <TaxCode>V02</TaxCode> 
      </VoucherChildTax>
      </Children>
      </VoucherRecord>
    - <VoucherRecord>
      <InvoiceNum>14230727</InvoiceNum> 
      <InvoiceDate>2016-03-23</InvoiceDate> 
    - <Children>
    - <VoucherChildTax>
      <TaxAmount>27</TaxAmount> 
      <TaxCode>V02</TaxCode> 
      </VoucherChildTax>
    - <VoucherChildTax>
      <TaxAmount>21</TaxAmount> 
      <TaxCode>V01</TaxCode> 
      </VoucherChildTax>
      </Children>
      </VoucherRecord>
      </ns0:Voucher>


    Rachit Sikroria (Microsoft Azure MVP)

    Tuesday, November 8, 2016 9:50 AM
    Moderator
  • I am sorry for duplication and I was desperate main due to my unclear request. What I really want to achieve is just to sum TaxAMount group by TaxCode for each invoice and payee for the input side schema to populate them to the destination schema. The rest attributes are mapped one to one. See attached for detail. Would be possible to use Inline XSLT just do that part.
    Tuesday, November 8, 2016 7:30 PM
  • Tuesday, November 8, 2016 7:30 PM
  • Here are reference data.

    Fig. 1 Sample input data

    <?xml version="1.0" encoding="utf-8"?>
    <ns0:Voucher xmlns:ns0="http://VoucherLoad.PreTransform.VoucherGroupSchema" xmlns:userVB="http://schemas.microsoft.com/BizTalk/2003/userVB">
    <VoucherRecord>
    <InvoiceNum>1423063909290501</InvoiceNum>
    <Payee>01</Payee>
    <InvoiceDate>2016-09-23</InvoiceDate>
    <Children>
    <VoucherChildTax>
    <TaxAmount>10</TaxAmount>
    <TaxCode>V01</TaxCode>
    </VoucherChildTax>
    <VoucherChildGL>
    <GLAccount>71610-00000-000000</GLAccount>
    <Office>01</Office>
    </VoucherChildGL>
    <VoucherChildTax>
    <TaxAmount>12</TaxAmount>
    <TaxCode>V02</TaxCode>
    </VoucherChildTax>
    <VoucherChildGL>
    <GLAccount>71710-00000-000000</GLAccount>
    <Office>01</Office>
    </VoucherChildGL>
    <VoucherChildTax>
    <TaxAmount>16</TaxAmount>
    <TaxCode>V01</TaxCode>
    </VoucherChildTax>
    <VoucherChildGL>
    <GLAccount>71710-00000-000000</GLAccount>
    <Office>01</Office>       
    </VoucherChildGL>
    </Children>
    </VoucherRecord>
    <VoucherRecord>
    <InvoiceNum>1421764509290501</InvoiceNum>
    <Payee>01</Payee>
    <InvoiceDate>2016-09-22</InvoiceDate> 
    <Children>
    <VoucherChildTax>
    <TaxAmount>7</TaxAmount>
    <TaxCode>V01</TaxCode>
    </VoucherChildTax>
    <Timekeeper>11044</Timekeeper>
    <CostType>156</CostType>     
    </VoucherChildCost>
    <TaxAmount>11</TaxAmount>
    <TaxCode>V01</TaxCode>
    </Children>
    </VoucherRecord>
    <VoucherRecord>
    <InvoiceNum>1422823809290503</InvoiceNum>
    <InvoiceDate>2016-09-23</InvoiceDate>  
    <Children>
    <VoucherChildTax>
    <TaxAmount>9</TaxAmount>
    <TaxCode>V01</TaxCode>
    </VoucherChildTax>
    <VoucherChildGL>
    <GLAccount>72710-00000-000000</GLAccount>
    <Office>01</Office>     
    </VoucherChildGL>
    </Children>
    </VoucherRecord>
    <VoucherRecord>
    <InvoiceNum>1420401809290503</InvoiceNum>
    <Payee>02</Payee>
    <InvoiceDate>2016-09-22</InvoiceDate>  
    <Children>
    <VoucherChildTax>
    <TaxAmount>11</TaxAmount>
    <TaxCode>V02</TaxCode>
    </VoucherChildTax>
    <VoucherChildGL>
    <GLAccount>71710-00000-000000</GLAccount>
    <Office>01</Office>
    </VoucherChildGL>
    <VoucherChildTax>
    <TaxAmount>10</TaxAmount>
    <TaxCode>V01</TaxCode>
    </VoucherChildTax>
    <VoucherChildGL>
    <GLAccount>72610-00000-000000</GLAccount>
    <Office>01</Office>       
    </VoucherChildGL>
    </Children>
    </VoucherRecord> 
    </ns0:Voucher>


    Fig. 3 Desired Output

    <ns0:Voucher xmlns:ns0="http://VoucherLoad.PreTransform.VoucherGroupSchema" xmlns:userVB="http://schemas.microsoft.com/BizTalk/2003/userVB">
    <VoucherRecord>
    <InvoiceNum>1423063909290501</InvoiceNum>
    <Payee>01</Payee>
    <InvoiceDate>2016-09-23</InvoiceDate>
    <Children>
    <VoucherChildTax>
    <TaxAmount>44</TaxAmount>
    <TaxCode>V01</TaxCode>
    </VoucherChildTax>
    <VoucherChildTax>
    <TaxAmount>12</TaxAmount>
    <TaxCode>V02</TaxCode>
    <VoucherChildTax>
    <TaxAmount>16</TaxAmount>
    <TaxCode>V01</TaxCode>
    </VoucherChildTax>
    </Children>
    </VoucherRecord>  
    <VoucherRecord>
    <InvoiceNum>1422823809290503</InvoiceNum>
    <Payee>02</Payee>
    <InvoiceDate>2016-09-23</InvoiceDate>  
    <Children>
    <VoucherChildTax>
    <TaxAmount>19</TaxAmount>
    <TaxCode>V01</TaxCode>
    </VoucherChildTax>   
    <VoucherChildTax>
    <TaxAmount>11</TaxAmount>
    <TaxCode>V02</TaxCode>  
    </VoucherChildTax>
    </Children>
    </VoucherRecord> 
    </ns0:Voucher>

    Tuesday, November 8, 2016 7:36 PM
  • Hi ZD Li,

    I have given you pointers on the approach that you need to follow. With the changing requirements, its important that you learn XSLT and BizTalk Mapping for your own benefit.

    Do some POCs around grouping and sorting.

    Refer the links below:

    BizTalk 2010 Recipes : Document Mapping - Using XSLT Group-By

    BizTalk Training – Mapping – How to implement multi-level Muenchian grouping in BizTalk Maps

    GoodLuck!

    PS: The input message you provided is not a valid XML. You should handle the complete mapping in Inline XSLT instead of try to map only specific part as there are nested loops involved.


    Rachit Sikroria (Microsoft Azure MVP)

    Wednesday, November 9, 2016 11:28 AM
    Moderator
  • Thanks Rachit for your help. Yes, I need to do some POCs as you suggested.
    Wednesday, November 9, 2016 2:57 PM
  • After some reading I start understand some basic. I made changes to your code above in two places: 1) use <xsl:for-each select="//VoucherRecord"> to replace <xsl:for-each select="//ns0:Voucher/VoucherRecord">; 2) use <xsl:for-each select="../VoucherRecord[$i]/Children/VoucherChildTax"> to replace <xsl:for-each select="../../ns0:Voucher/VoucherRecord[$i]/Children/VoucherChildTax">. I don't know how it works but it works well now. Thanks again Rachit.

    I have an additional request for this project due to new request from my users - to group InvoiceNum and Payee for rest datasets. Following is my working XSLT code (I omit a lot of detail elements for both voucherChildGL and voucherChildCost segments. Would you please recommend needed changes please?

    <xsl:for-each select="//VoucherRecord">
    <xsl:variable name="i" select="position()" />
    <VoucherRecord>
    <InvoiceNum>
    <xsl:value-of select="./InvoiceNum"/>
    </InvoiceNum>
    <InvoiceDate>
    <xsl:value-of select="./InvoiceDate"/>
    </InvoiceDate>
    <xsl:if test="Payee">
    <Payee>
        <xsl:value-of select="Payee/text()" />
    </Payee>
    </xsl:if>


    <Children>

    <xsl:for-each select="Children">
    <xsl:for-each select="VoucherChildGL">
    <VoucherChildGL>
    <xsl:if test="GLAccount">
    <GLAccount>
    <xsl:value-of select="GLAccount/text()" />
    </GLAccount>
    </xsl:if>
    <xsl:value-of select="./text()" />
    </VoucherChildGL>
    </xsl:for-each>
    </xsl:for-each>

    <xsl:for-each select="Children">
    <xsl:for-each select="VoucherChildCost">
    <VoucherChildCost>
    <xsl:if test="Matter">
    <Matter>
    <xsl:value-of select="Matter/text()" />
    </Matter>
    </xsl:if>
    <xsl:value-of select="./text()" />
    </VoucherChildCost>
    </xsl:for-each>
    </xsl:for-each>

    <xsl:for-each select="../VoucherRecord[$i]/Children/VoucherChildTax">
    <xsl:variable name="j" select="position()" />
    <xsl:for-each select="../VoucherChildTax[$j][not(TaxCode=preceding-sibling::VoucherChildTax/TaxCode)]/TaxCode">
    <VoucherChildTax>
    <TaxAmount>
    <xsl:value-of select="sum(//VoucherRecord[$i]/Children/VoucherChildTax[TaxCode=current()]/TaxAmount)"/>
    </TaxAmount>
    <TaxCode>
    <xsl:value-of select="current()"/>
    </TaxCode>
    </VoucherChildTax>
    </xsl:for-each>
    </xsl:for-each>

    </Children>

    </VoucherRecord>
    </xsl:for-each>


    • Edited by ZD Li Wednesday, November 16, 2016 8:29 PM
    Tuesday, November 15, 2016 7:40 PM