1

Im trying to build an output file (based on a determined template) having as input another xml.

The xslt code (XSLT 1.0) used to build the output, is "divided" by sections.

I'm skipping the first part of the code... I was "assigning" the variables, for ex:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:date="http://exslt.org/dates-and-times" extension-element-prefixes="date">
    
<xsl:variable name="securityCode"select="/A/securityCode"/>
<!--and the others variables to I think is are not relevant for my question-->

The xslt (the original code has more sections than this, also I have to use it for different inputs to produce different outputs)

                                       <!--Here we call the templates-->

<xsl:template match="/">
 <Header>

 <xsl:call-template name="Header">
 <xsl:with-param name="securityCode" select = "$securityCode"/>
 <xsl:with-param name="generatedTime" select = "$generatedTime"/>
 </xsl:call-template>

 </Header>

</xsl:template>

                                       



<xsl:call-template name="StructureData">

<xsl:with-param name = "payDate"/>
<xsl:with-param name = "amount"/>
<xsl:with-param  name = "priRte"/> 
<xsl:with-param name = "settlement"/> 
<xsl:with-param name = "rate"/> 
<xsl:with-param name = "curr"/> 
<xsl:with-param name = "rdate"/>
<xsl:with-param name = "ID"/>
<xsl:with-param name = "CID" />
<xsl:with-param name = "Nom" />

</xsl:call-template>

                                     <!--Here we call "define" the templates-->
<xsl:template name = "Header" >
<xsl:param name = "securityCode" />
<xsl:param name = "generatedTime" />

 <NHeader>
  <MessageID><xsl:value-of select="$securityCode"/></MessageID>
 
  <Timezone>GMT</Timezone>
  <GeneratedTime><xsl:value-of select="$generatedTime"/></GeneratedTime>
  
 </NHeader>

</xsl:template>

<xsl:template name = "StructureData" >

<xsl:param name = "payDate"/>
<xsl:param name = "amount"/>
<xsl:param name = "priRte"/> 
<xsl:param name = "settlement"/> 
<xsl:param name = "rate"/> 
<xsl:param name = "curr"/> 
<xsl:param name = "rdate"/>
<xsl:param name = "ID"/>
<xsl:param name = "CID" />
<xsl:param name = "Nom" />
<xsl:param name = "securityCode" />
                    <Data2>
                      <ID><xsl:value-of select="$ID"/></ID>
                      <Sett><xsl:value-of select="$settlement"/></Sett>
                      <BuyOrSell value="Sell"/>
                      <price value="Price"><xsl:value-of select="$priRte"/></price>
                      <Cost><xsl:value-of select="$Nom"/></Cost>
                     <Accrual>
                        <Cashflow CFLType="Principal">
                          <Cid><xsl:value-of select="$CID"/></CID>
                          <CashflowPayment>
                            <PayDate><xsl:value-of select="$payDate"/></PayDate>
                            <Amount><xsl:value-of select="$amount"/></Amount>
                        </CashflowPayment>
                      </Cashflow>
                  </Accrual>
                </Data2>

</xsl:template>


</xsl:stylesheet>

Finally, my question:

I would like to modify (or rename it) the node value :

<BuyOrSell value="Sell"/>

Depending on the input condition (from an input) variable, let say secutityCode defined above.

Suppose (securityCode can be: 1 or 2)

  1. securityCode=1 then <BuyOrSell value="Sell"/>
  2. securityCode=2 then <BuyOrSell value="Buy"/>

I know how to modify nodes, but once I template as input...actually there are some hints: hint1 hint2 none of these works, or probably I don't how to implement it on my code.

2 Answers 2

2

Here is a compact way to do this in XSLT 1.0

(just in a single line like this: <BuyOrSell value="{$vOps[$psecurityCode]}"/> regardless of the number of different possible op-codes):

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:param name="psecurityCode" select="1"/>
 <xsl:variable name="vTxs">
   <op>Sell</op>
   <op>Buy</op>
 </xsl:variable>
 
 <xsl:variable name="vOps" select="document('')/*/xsl:variable[@name='vTxs']/*"/>

  <xsl:template match="/">
    <BuyOrSell value="{$vOps[$psecurityCode]}"/>
  </xsl:template>
</xsl:stylesheet>

When this transformation is applied on any XML document (not used), the wanted, correct result is produced:

<BuyOrSell value="Sell"/>

If you replace the xsl:param declaration with: <xsl:param name="psecurityCode" select="2"/> then again the wanted result is produced:

<BuyOrSell value="Buy"/>

II. Explanation

  1. Using AVT (Attribute Value Templates)

  2. Using document('') to access the stylesheet document and its descendents

Sign up to request clarification or add additional context in comments.

Comments

1

If you create an attribute with e.g.

<BuyOrSell>
  <xsl:attribute name="value">
    <xsl:choose>
      <xsl:when test="$securityCode = 1">Sell</xsl:when>
      <xsl:when test="$securityCode = 2">Buy</xsl:when>
    </xsl:choose>
  </xsl:attribute>
</BuyOrSell>

you can implement the condition, although in XSLT 1 that is a rather verbose way.

In general I would suggest to try to use template matching e.g.

<xsl:template match="/A/securityCode[. = 1]">
  <BuyOrSell>Sell</BuyOrSell>
</xsl:template>

<xsl:template match="/A/securityCode[. = 2]">
  <BuyOrSell>Buy</BuyOrSell>
</xsl:template>

and then further up in the tree processing use <xsl:apply-templates/> or <xsl:apply-templates select="securityCode"/> depending on your needs to implement the transformation.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.