Dimitar Dimitrov
Dimitar Dimitrov

Reputation: 109

XSLT different template based on child

I have the following source XML, which I have to transform in order to import into accounting software. In a nutshell, the resulting XML should have a static header and Multiple Lines (one Line per Project Ledger Line on the source XML). I would like to choose a different template for expenses and timesheets, because there are many differences in the accounting entries. One example is account code. The below example is very simplified only to differentiate account code, but there are a lot of other differences as well. The problem I have in my current transformation is that I only get one line, instead of 2, for some reason one is ignored. Please help,

thank you,

This is where you can access this project: http://xsltransform.net/jyRYYjg/1

Source XML:

<?xml version="1.0" encoding="utf-8"?>
    <TIMEATWORK xsl:version="1.0" server="localhost" database="TAW_TTC" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
        <PROJECT_LEDGER_LINE>
            <CalcVal11>600</CalcVal11>
            <Orig_Trans_Type>TIMESHEET</Orig_Trans_Type>
            <Project_Company_Accounts>
                  <Proj_AccName1>70600000</Proj_AccName1>
                  <Proj_AccName2>46141101</Proj_AccName2>
            </Project_Company_Accounts>
        </PROJECT_LEDGER_LINE>
        <PROJECT_LEDGER_LINE>
            <CalcVal11>50</CalcVal11>
            <Orig_Trans_Type>EXPENSE</Orig_Trans_Type>
            <Project_Company_Accounts>
                  <Proj_AccName1>70600000</Proj_AccName1>
                  <Proj_AccName2>46141101</Proj_AccName2>
            </Project_Company_Accounts>
        </PROJECT_LEDGER_LINE>
    </TIMEATWORK>

XSLT:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:msxsl="urn:schemas-microsoft-com:xslt"
    xmlns:user="http://llpgroup.com/TAWnamespace"
    exclude-result-prefixes="msxsl user" >
    <xsl:output method="xml" version="1.0" encoding="utf-8" indent="yes" />

    <xsl:template match="TIMEATWORK">
    <SSC>
        <Header>
            <BudgetCode>A</BudgetCode>
        </Header>
        <Details>
            <Ledger>
                <xsl:apply-templates select="PROJECT_LEDGER_LINE">
                    <xsl:sort select="Orig_Trans_Type"/>
                </xsl:apply-templates>
            </Ledger>
        </Details>
    </SSC>

    </xsl:template>

    <xsl:template match="PROJECT_LEDGER_LINE">  
    <xsl:if test="Orig_Trans_Type = 'TIMESHEET'">
        <Line>
            <AccountCode><xsl:value-of select="Project_Company_Accounts/Proj_AccName1"/></AccountCode>
            <CurrencyCode><xsl:value-of select="CalcVal11"/></CurrencyCode>
            <DebitCredit>D</DebitCredit>
        </Line>
    </xsl:if>
    </xsl:template>

    <xsl:template match="PROJECT_LEDGER_LINE">  
    <xsl:if test="Orig_Trans_Type = 'EXPENSE'">
        <Line>
            <AccountCode><xsl:value-of select="Project_Company_Accounts/Proj_AccName2"/></AccountCode>
            <CurrencyCode><xsl:value-of select="CalcVal11"/></CurrencyCode>
            <DebitCredit>D</DebitCredit>
        </Line>
    </xsl:if>
    </xsl:template>

</xsl:stylesheet>

Desired Output:

<?xml version="1.0" encoding="utf-8"?>
<SSC>
   <Header>
      <BudgetCode>A</BudgetCode>
   </Header>
   <Details>
      <Ledger>
           <Line>
            <AccountCode>70600000</AccountCode>
            <CurrencyCode>600</CurrencyCode>
            <DebitCredit>D</DebitCredit>
         </Line>
         <Line>
            <AccountCode>46141101</AccountCode>
            <CurrencyCode>50</CurrencyCode>
            <DebitCredit>D</DebitCredit>
         </Line>
      </Ledger>
   </Details>
</SSC>

Upvotes: 0

Views: 38

Answers (1)

michael.hor257k
michael.hor257k

Reputation: 117073

When you have two (or more) templates matching the same node, only one of them will be applied.

If you want to have each template applied to a different type of the same node, use a predicate instead of xsl:if, e.g.:

<xsl:template match="PROJECT_LEDGER_LINE[Orig_Trans_Type = 'TIMESHEET']">  
    <Line>
        <AccountCode><xsl:value-of select="Project_Company_Accounts/Proj_AccName1"/></AccountCode>
        <CurrencyCode><xsl:value-of select="CalcVal11"/></CurrencyCode>
        <DebitCredit>D</DebitCredit>
    </Line>
</xsl:template>

<xsl:template match="PROJECT_LEDGER_LINE[Orig_Trans_Type = 'EXPENSE']">  
    <Line>
        <AccountCode><xsl:value-of select="Project_Company_Accounts/Proj_AccName2"/></AccountCode>
        <CurrencyCode><xsl:value-of select="CalcVal11"/></CurrencyCode>
        <DebitCredit>D</DebitCredit>
    </Line>
</xsl:template>

Upvotes: 1

Related Questions