Click to See Complete Forum and Search --> : dynamic template calling


fiddes_c
October 29th, 2003, 07:14 AM
Hi,
I've an xml file that has the following repeating structure:
<MEMBER_DETAILS>
<Number>102204</Number>
<Title>Mr</Title>
<Name>Cormac</Name>
<Surname>Fiddes</Surname>
<Staff>CC99</Staff>
<Centre>200</Centre>
<Prod>Good</Prod>
<Cov>Land</Cov>
<Ad>6</Ad>
<Stu>5</Stu>
<Chi>7</Chi>
<Stat>A</Stat>
</MEMBER_DETAILS>

In the XSL, I use this to apply a sort to the data: (dependant on a value coming across in the META).
<!--
Defining sorts -->
<xsl:template name="DETAIL_SORT">
<xsl:variable name="BDigit">
<xsl:value-of select="string(META//SortCode)"/>
</xsl:variable>
<xsl:choose>
<!-- When SortCode = 3 then apply a sort first by Centre, for the MEMBER_DETAILS subform -->
<xsl:when test="$BDigit=3">
<xsl:apply-templates select="MEMBER_DETAILS">
<xsl:sort select="Centre" order="ascending"/>
</xsl:apply-templates>
</xsl:when>
</xsl:choose>
</xsl:template>

Then from the apply_templates, I match the items:
<xsl:template match="MEMBER_DETAILS">
<MEMBER_DETAILS>
<xsl:call-template name="G_MEMBER_DETAILS"/>
<xsl:apply-templates select="descendant::Number"/>
<xsl:apply-templates select="descendant::Name"/>
<xsl:apply-templates select="descendant::Surname"/>
<xsl:apply-templates select="descendant::Staff"/>
<xsl:apply-templates select="descendant::Centre"/>
<xsl:apply-templates select="descendant::Prod"/>
<xsl:apply-templates select="descendant::Cov"/>
<xsl:apply-templates select="descendant::Adu"/>
<xsl:apply-templates select="descendant::Stu"/>
<xsl:apply-templates select="descendant::Chi"/>
<xsl:apply-templates select="descendant::Stat"/>
</MEMBER_DETAILS>
</xsl:template>

The good news is this all works fine!
However, I now have a requirement to dynamically lay down the name of the group MEMBER_DETAILS, again dependant on a value coming across in the META.
For example, if item, SubCode, (in the META), can be 1,2,3 or 4.
If it's 1 lay down the data in the dat file as follows:

G_MEMBER_DETAILS_1
Number
102204
Title
Mr
Name
Cormac
Surname
Fiddes
Staff
CC99
Centre
200
Prod
Good
Cov
Land
Ad
6
Stu5
Chi7
Stat
A
G_MEMBER_DETAILS_1
Number
102244
Title
Ms
Name
Sean
Surname
Murphy
Staff
CC99
Centre
200
Prod
Good
Cov
Land
Ad
6
Stu5
Chi7
Stat
A

I had thought this would work for the calling of a different template, but alas no:
<!--
Define the elements that are required within the block GROUP_MEMBER_DETAILS
-->
<xsl:template match="MEMBER_DETAILS">
<MEMBER_DETAILS>
<xsl:variable name="XDigit">
<xsl:value-of select="string(META//SubCode)"/>
</xsl:variable>
<xsl:choose>
<xsl:when test="$XDigit=1">
<xsl:call-template name="MEMBER_DETAILS_1"/>
</xsl:when>
<xsl:when test="$XDigit=2">
<xsl:call-template name="MEMBER_DETAILS_2"/>
</xsl:when>
</xsl:choose>
<xsl:apply-templates select="descendant::Number"/>
<xsl:apply-templates select="descendant::Name"/>
<xsl:apply-templates select="descendant::Surname"/>
<xsl:apply-templates select="descendant::Staff"/>
<xsl:apply-templates select="descendant::Centre"/>
<xsl:apply-templates select="descendant::Prod"/>
<xsl:apply-templates select="descendant::Cov"/>
<xsl:apply-templates select="descendant::Adu"/>
<xsl:apply-templates select="descendant::Stu"/>
<xsl:apply-templates select="descendant::Chi"/>
<xsl:apply-templates select="descendant::Stat"/>
</MEMBER_DETAILS>
</xsl:template>

However, it just lays down the data items and NO template name:
i.e.

Number
102204
Title
Mr
Name
Cormac
Surname
Fiddes
Staff
CC99
Centre
200
Prod
Good
Cov
Land
Ad
6
Stu5
Chi7
Stat
A
Number
102244
Title
Ms
Name
Sean
Surname
Murphy
Staff
CC99
Centre
200
Prod
Good
Cov
Land
Ad
6
Stu5
Chi7
Stat
A

Any idea's. If this is not so obvious, I can post the full xml and xsl files.
Cheers
Cormac

ps FULL files:
XML:
<?xml version="1.0"?>

<JOB xmlns:xfa="http://www.xfa.org/schema/xfa-data/1.0/">

<!-- Document #1 -->
<DOCUMENT template="ABC">
<!-- Document Level Meta Data. Generated for each document in the batch -->
<META>
<DocName>TEST</DocName>
<SubCode>3</SubCode>
<SortCode>3</SortCode>
</META>

<HEADER>
<!-- Header Information. -->
</HEADER>

<MEMBER_DETAILS>
<Number>102204</Number>
<Title>Mr</Title>
<Name>Cormac</Name>
<Surname>Fiddes</Surname>
<Staff>CC99</Staff>
<Centre>200</Centre>
<Prod>Good</Prod>
<Cov>Land</Cov>
<Adu>6</Adu>
<Stu>5</Stu>
<Chi>7</Chi>
<Stat>A</Stat>
</MEMBER_DETAILS>

<MEMBER_DETAILS>
<Number>102224</Number>
<Title>Mr</Title>
<Name>Cormac</Name>
<Surname>Murphy</Surname>
<Staff>CC55</Staff>
<Centre>100</Centre>
<Prod>Bad</Prod>
<Cov>Land</Cov>
<Adu>5</Adu>
<Stu>1</Stu>
<Chi>0</Chi>
<Stat>B</Stat>
</MEMBER_DETAILS>

</DOCUMENT>

</JOB>


XSL:
<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xfa="http://www.xfa.org/schema/xfa-data/1.0"
version="1.0">

<!--
Find the Element DOCUMENT. Here will will order the output of the groups within document
META
HEADER
GROUP_MEMBER_DETAILS(may be repeating)
-->


<xsl:template match="DOCUMENT">
<DOCUMENT>
<xsl:apply-templates select="descendant::HEADER"/>
<xsl:call-template name="DocType"/>
<xsl:call-template name="DETAIL_SORT"/>
</DOCUMENT>
</xsl:template>

<!--
All Elements within the block META will need to be defined as Globals.
Use * to indicate that all elements of META will be added to .dat file
-->
<xsl:template match="META">
<META>
<xsl:apply-templates select="descendant::*"/>
</META>
</xsl:template>

<xsl:template match="META//*">
<xsl:call-template name="global"/>
</xsl:template>


<!--
All Elements within the block HEADER will need to be defined as Globals.
Use * to indicate that all elements of HEADER will be added to .dat file
-->
<xsl:template match="HEADER">
<HEADER>
<xsl:apply-templates select="descendant::*"/>
</HEADER>
</xsl:template>

<xsl:template match="HEADER//*">
<xsl:call-template name="global"/>
</xsl:template>

<!--
Define the elements that are required within the block GROUP_MEMBER_DETAILS
-->
<xsl:template match="MEMBER_DETAILS_both">
<MEMBER_DETAILS_both>
<xsl:call-template name="G_MEMBER_DETAILS_both"/>
</MEMBER_DETAILS_both>
</xsl:template>

<!--
Define the elements that are required within the block MEMBER_DETAILS
-->
<xsl:template match="MEMBER_DETAILS">
<MEMBER_DETAILS>
<xsl:variable name="XDigit">
<xsl:value-of select="string(META//SubCode)"/>
</xsl:variable>
<xsl:choose>
<xsl:when test="$XDigit=3">
<xsl:apply-templates select="MEMBER_DETAILS_both"/>
</xsl:when>
</xsl:choose>
<xsl:apply-templates select="descendant::Number"/>
<xsl:apply-templates select="descendant::Name"/>
<xsl:apply-templates select="descendant::Surname"/>
<xsl:apply-templates select="descendant::Staff"/>
<xsl:apply-templates select="descendant::Centre"/>
<xsl:apply-templates select="descendant::Prod"/>
<xsl:apply-templates select="descendant::Cov"/>
<xsl:apply-templates select="descendant::Adu"/>
<xsl:apply-templates select="descendant::Stu"/>
<xsl:apply-templates select="descendant::Chi"/>
<xsl:apply-templates select="descendant::Stat"/>
</MEMBER_DETAILS>
</xsl:template>

<xsl:template match="MEMBER_DETAILS//*">
<xsl:call-template name="global"/>
</xsl:template>

<!--
Defining calls for different Detail subforms
-->
<xsl:template name="DETAIL_SORT">
<xsl:variable name="DDigit">
<xsl:value-of select="string(META//SubCode)"/>
</xsl:variable>
<xsl:choose>
<!-- When SubCode = 3 then choose MEMBER_DETAILS_both
which uses both staff and centre -->
<xsl:when test="$DDigit=3">
<xsl:call-template name="DETAIL_BOTH"/>
</xsl:when>
</xsl:choose>
</xsl:template>

<!--
Defining sorts, 4 different sorts possible
-->
<xsl:template name="DETAIL_BOTH">
<xsl:variable name="BDigit">
<xsl:value-of select="string(META//SortCode)"/>
</xsl:variable>
<xsl:choose>
<!-- When SortCode = 3 then apply a sort by Centre,
for the MEMBER_DETAILS_both subform -->

<xsl:when test="$BDigit=3">
<xsl:apply-templates select="MEMBER_DETAILS">
</xsl:apply-templates>
</xsl:when>
</xsl:choose>
</xsl:template>

<!--
This default template will output the element only if the
field contains something non-blank.
-->
<xsl:template match="*">
<xsl:if test="normalize-space()!=''">
<xsl:element name="{name()}">
<xsl:apply-templates/>
</xsl:element>
</xsl:if>
</xsl:template>

<!--
Force a specified field to be a global field
-->
<xsl:template name="global">
<xsl:element name="{name() }">
<xsl:attribute name="xfa:match">many</xsl:attribute>
<xsl:apply-templates/>
</xsl:element>
</xsl:template>

<!-- G_MEMBER_DETAILS_both
-->
<xsl:template name="G_MEMBER_DETAILS_both">
<xsl:element name="MEMBER_DETAILS_both">
<xsl:attribute name="xfa:dataNode">dataGroup</xsl:attribute>
<xsl:text>begin</xsl:text>
</xsl:element>
</xsl:template>

<!-- G_MEMBER_DETAILS
-->
<xsl:template name="G_MEMBER_DETAILS">
<xsl:element name="MEMBER_DETAILS">
<xsl:attribute name="xfa:dataNode">dataGroup</xsl:attribute>
<xsl:text>begin</xsl:text>
</xsl:element>
</xsl:template>

</xsl:stylesheet>

fiddes_c
October 29th, 2003, 09:20 AM
hi,
files,
Cormac

~~~~
XML
<?xml version="1.0"?>

<JOB xmlns:xfa="http://www.xfa.org/schema/xfa-data/1.0/">

<!-- Document #1 -->
<DOCUMENT template="ABC">
<!-- Document Level Meta Data. Generated for each document in the batch -->
<META>
<DocName>TEST</DocName>
<SubCode>3</SubCode>
<SortCode>3</SortCode>
</META>

<HEADER>
<!-- Header Information. -->
</HEADER>

<MEMBER_DETAILS>
<Number>102204</Number>
<Title>Mr</Title>
<Name>Cormac</Name>
<Surname>Fiddes</Surname>
<Staff>CC99</Staff>
<Centre>200</Centre>
<Prod>Good</Prod>
<Cov>Land</Cov>
<Adu>6</Adu>
<Stu>5</Stu>
<Chi>7</Chi>
<Stat>A</Stat>
</MEMBER_DETAILS>

<MEMBER_DETAILS>
<Number>102224</Number>
<Title>Mr</Title>
<Name>Cormac</Name>
<Surname>Murphy</Surname>
<Staff>CC55</Staff>
<Centre>100</Centre>
<Prod>Bad</Prod>
<Cov>Land</Cov>
<Adu>5</Adu>
<Stu>1</Stu>
<Chi>0</Chi>
<Stat>B</Stat>
</MEMBER_DETAILS>

</DOCUMENT>

</JOB>
~~~~~~~~~~~~~~
XSL:
<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xfa="http://www.xfa.org/schema/xfa-data/1.0"
version="1.0">

<!--
Find the Element DOCUMENT. Here will will order the output of the groups within document
META
HEADER
MEMBER_DETAILS(may be repeating)
-->


<xsl:template match="DOCUMENT">
<DOCUMENT>
<xsl:apply-templates select="descendant::HEADER"/>
<xsl:call-template name="DocType"/>
<xsl:call-template name="DETAIL_SORT"/>
</DOCUMENT>
</xsl:template>

<!--
All Elements within the block META will need to be defined as Globals.
Use * to indicate that all elements of META will be added to .dat file
-->
<xsl:template match="META">
<META>
<xsl:apply-templates select="descendant::*"/>
</META>
</xsl:template>

<xsl:template match="META//*">
<xsl:call-template name="global"/>
</xsl:template>


<!--
All Elements within the block HEADER will need to be defined as Globals.
Use * to indicate that all elements of HEADER will be added to .dat file
-->
<xsl:template match="HEADER">
<HEADER>
<xsl:apply-templates select="descendant::*"/>
</HEADER>
</xsl:template>

<xsl:template match="HEADER//*">
<xsl:call-template name="global"/>
</xsl:template>

<!--
Define the elements that are required within the block MEMBER_DETAILS
-->
<xsl:template match="MEMBER_DETAILS_both">
<MEMBER_DETAILS_both>
<xsl:call-template name="G_MEMBER_DETAILS_both"/>
</MEMBER_DETAILS_both>
</xsl:template>

<!--
Define the elements that are required within the block MEMBER_DETAILS
-->
<xsl:template match="MEMBER_DETAILS">
<MEMBER_DETAILS>
<xsl:variable name="XDigit">
<xsl:value-of select="string(META//SubCode)"/>
</xsl:variable>
<xsl:choose>
<xsl:when test="$XDigit=3">
<xsl:apply-templates select="MEMBER_DETAILS_both"/>
</xsl:when>
</xsl:choose>
<xsl:apply-templates select="descendant::Number"/>
<xsl:apply-templates select="descendant::Name"/>
<xsl:apply-templates select="descendant::Surname"/>
<xsl:apply-templates select="descendant::Staff"/>
<xsl:apply-templates select="descendant::Centre"/>
<xsl:apply-templates select="descendant::Prod"/>
<xsl:apply-templates select="descendant::Cov"/>
<xsl:apply-templates select="descendant::Adu"/>
<xsl:apply-templates select="descendant::Stu"/>
<xsl:apply-templates select="descendant::Chi"/>
<xsl:apply-templates select="descendant::Stat"/>
</MEMBER_DETAILS>
</xsl:template>

<xsl:template match="MEMBER_DETAILS//*">
<xsl:call-template name="global"/>
</xsl:template>

<!--
Defining calls for different Detail subforms
-->
<xsl:template name="DETAIL_SORT">
<xsl:variable name="DDigit">
<xsl:value-of select="string(META//SubCode)"/>
</xsl:variable>
<xsl:choose>
<!-- When SubCode = 3 then choose MEMBER_DETAILS_both
which uses both staff and centre -->
<xsl:when test="$DDigit=3">
<xsl:call-template name="DETAIL_BOTH"/>
</xsl:when>
</xsl:choose>
</xsl:template>

<!--
Defining sorts, 4 different sorts possible
-->
<xsl:template name="DETAIL_BOTH">
<xsl:variable name="BDigit">
<xsl:value-of select="string(META//SortCode)"/>
</xsl:variable>
<xsl:choose>
<!-- When SortCode = 3 then apply a sort by Centre,
for the MEMBER_DETAILS_both subform -->

<xsl:when test="$BDigit=3">
<xsl:apply-templates select="MEMBER_DETAILS">
</xsl:apply-templates>
</xsl:when>
</xsl:choose>
</xsl:template>

<!--
This default template will output the element only if the
field contains something non-blank.
-->
<xsl:template match="*">
<xsl:if test="normalize-space()!=''">
<xsl:element name="{name()}">
<xsl:apply-templates/>
</xsl:element>
</xsl:if>
</xsl:template>

<!--
Force a specified field to be a global field
-->
<xsl:template name="global">
<xsl:element name="{name() }">
<xsl:attribute name="xfa:match">many</xsl:attribute>
<xsl:apply-templates/>
</xsl:element>
</xsl:template>

<!-- G_MEMBER_DETAILS_both
-->
<xsl:template name="G_MEMBER_DETAILS_both">
<xsl:element name="MEMBER_DETAILS_both">
<xsl:attribute name="xfa:dataNode">dataGroup</xsl:attribute>
<xsl:text>begin</xsl:text>
</xsl:element>
</xsl:template>

<!-- G_MEMBER_DETAILS
-->
<xsl:template name="G_MEMBER_DETAILS">
<xsl:element name="MEMBER_DETAILS">
<xsl:attribute name="xfa:dataNode">dataGroup</xsl:attribute>
<xsl:text>begin</xsl:text>
</xsl:element>
</xsl:template>

</xsl:stylesheet>

fiddes_c
October 30th, 2003, 10:47 AM
hi,
anyone have any idea on this?
cheers
Cormac