I have the following source XML:
<?xml version="1.0" encoding="utf-8" ?>
<svg width="800" height="600" xml:id="pg1">
<g class="foreground">
<text transform="translate(163,90)
rotate(0.000,219.664,8.938)
scale(1.000,1.000)"
RotationPoint="(320.000000,240.000000)"
xml:id="anno1"
visible="1" editwidth="439.33" editheight="17.88"
forcewidth="0" forceheight="0" language_direction="1"
textdirection="0" theme_anno_style="0">
<tspan justification="left"
line-spacing="1.00" prepara-spacing="1.00"
bullet="0">
<tspan>
<tspan fill="#000000" font-size="16.000"
font-family="Arial"
char-transform="0.00 1.00 0.00 0.00 0.00 1.00"
textLength="439.33" y="14.48" x="0.00">
It is not a book you can curl up at night with</tspan>
</tspan>
</tspan>
</text>
</g>
</svg>
I want to transform it to this:
<svg:page id="page0.svg">
<svg:rect id="page0.svg_BG_Rect" fill="#ffffff" x="0" y="0" width="800.00" height="600.00"/>
<svg:textarea fill="none" font-weight="normal" font-stretch="normal" font-style="normal" font-family="" font-size="0.00" x="163.00" y="90.00" width="483.26" height="19.66" transform="translate(0,0) rotate(0,320,240)" id="anno1">
<svg:tspan fill="#000000" font-weight="normal" font-stretch="normal" font-style="normal" font-family="Arial" font-size="16.00" id="para1" text-align="start">
<svg:tspan fill="#000000" font-weight="normal" font-stretch="normal" font-style="normal" font-family="Arial" font-size="16.00">
<svg:tspan fill="#000000" font-weight="normal" font-stretch="normal" font-style="normal" font-family="Arial" font-size="16.00">
<![CDATA[ It is not a book you can curl up at night with]]>
</svg:tspan>
</svg:tspan>
<svg:tbreak/>
</svg:tspan>
</svg:textarea>
</svg:page>
I am told this is best done using XSLT, but the example/tutorial I have seen show simple 1 to 1 transforms, that could probably be done using text search/replace (Ok, slight exaggeration).
The above is just one example, there are many more, but I could really do with a starter XSLT to give me a start.
It is a bit ambiguous from your example what you want, as some of the attribute values have no clear origin and would need to be hardcoded or calculated somehow.
That said, I think the following solution gives you the structure you are after. (Note that it's missing the finer details, like number formatting.)
Given the following input XML:
<?xml version="1.0" encoding="utf-8" ?>
<svg width="800" height="600" xml:id="pg1">
<g class="foreground">
<text transform="translate(163,90)
rotate(0.000,219.664,8.938)
scale(1.000,1.000)"
RotationPoint="(320.000000,240.000000)"
xml:id="anno1"
visible="1" editwidth="439.33" editheight="17.88"
forcewidth="0" forceheight="0" language_direction="1"
textdirection="0" theme_anno_style="0">
<tspan justification="left"
line-spacing="1.00" prepara-spacing="1.00"
bullet="0">
<tspan>
<tspan fill="#000000" font-size="16.000"
font-family="Arial"
char-transform="0.00 1.00 0.00 0.00 0.00 1.00"
textLength="439.33" y="14.48" x="0.00">
It is not a book you can curl up at night with
</tspan>
</tspan>
</tspan>
</text>
</g>
</svg>
This XSL stylesheet:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:svg="http://www.w3.org/2000/svg">
<xsl:output method="xml" version="1.0" indent="yes" cdata-section-elements="svg:tspan" omit-xml-declaration="yes"/>
<xsl:strip-space elements="*"/>
<!-- Get the fill attribute for svg:tspan from the innermost tspan element
(i.e. the tspan element with no tspan children). -->
<xsl:variable name="fill">
<xsl:value-of select="//tspan[not(tspan)]/#fill"/>
</xsl:variable>
<!-- Get the font-family attribute for svg:tspan from the innermost tspan element. -->
<xsl:variable name="font-family">
<xsl:value-of select="//tspan[not(tspan)]/#font-family"/>
</xsl:variable>
<!-- Get the font-size attribute for svg:tspan from the innermost tspan element. -->
<xsl:variable name="font-size">
<xsl:value-of select="//tspan[not(tspan)]/#font-size"/>
</xsl:variable>
<!-- Create the transform attribute by parsing the RotationPoint attribute of
the text element. -->
<xsl:variable name="transform">
<xsl:text>translate(0,0) rotate(0,</xsl:text>
<xsl:call-template name="substring-between">
<xsl:with-param name="substr" select="//text/#RotationPoint"/>
<xsl:with-param name="after" select=" '(' "/>
<xsl:with-param name="before" select=" ',' "/>
</xsl:call-template>
<xsl:text>,</xsl:text>
<xsl:call-template name="substring-between">
<xsl:with-param name="substr" select="//text/#RotationPoint"/>
<xsl:with-param name="after" select=" ',' "/>
<xsl:with-param name="before" select=" ')' "/>
</xsl:call-template>
<xsl:text>)</xsl:text>
</xsl:variable>
<!-- A helper function to find the string between two strings. -->
<xsl:template name="substring-between">
<xsl:param name="substr"/>
<xsl:param name="after"/>
<xsl:param name="before"/>
<xsl:value-of select="substring-after(substring-before($substr, $before), $after)"/>
</xsl:template>
<!-- Create the svg:page and svg:rect elements. Attributes hard-coded when it's not clear where they come from. -->
<xsl:template match="svg">
<svg:page xmlns:svg="http://www.w3.org/2000/svg" id="page0.svg">
<svg:rect id="page0.svg_BG_Rect" fill="#ffffff" x="0" y="0" width="{#width}" height="{#height}">
<xsl:apply-templates/>
</svg:rect>
</svg:page>
</xsl:template>
<!-- Create the svg:textarea element. Attributes hardcoded when it's not clear where they come from. -->
<xsl:template match="text">
<svg:textarea fill="none" font-weight="normal" font-stretch="normal" font-style="normal" font-family="" font-size="0.00" x="163.00" y="90.00" width="{#editwidth}" height="{#editheight}" transform="{$transform}" id="{#xml:id}">
<xsl:apply-templates/>
</svg:textarea>
</xsl:template>
<!-- Change the tspan elements to svg:tspan elements, using attributes from the innermost tspan element (which were put into variables earlier). Only the outermost tspan element has the id and text-align attributes. -->
<xsl:template match="tspan">
<svg:tspan fill="{$fill}" font-weight="normal" font-stretch="normal" font-style="normal" font-family="{$font-family}" font-size="{$font-size}">
<xsl:if test="not(parent::tspan)">
<xsl:attribute name="id">para1</xsl:attribute>
<xsl:attribute name="text-align">start</xsl:attribute>
</xsl:if>
<xsl:apply-templates/>
</svg:tspan>
</xsl:template>
</xsl:stylesheet>
Outputs this XML:
<svg:page xmlns:svg="http://www.w3.org/2000/svg" id="page0.svg">
<svg:rect id="page0.svg_BG_Rect"
fill="#ffffff"
x="0"
y="0"
width="800"
height="600">
<svg:textarea fill="none"
font-weight="normal"
font-stretch="normal"
font-style="normal"
font-family=""
font-size="0.00"
x="163.00"
y="90.00"
width="439.33"
height="17.88"
transform="translate(0,0) rotate(0,320.000000,240.000000)"
id="anno1">
<svg:tspan fill="#000000"
font-weight="normal"
font-stretch="normal"
font-style="normal"
font-family="Arial"
font-size="16.000"
id="para1"
text-align="start">
<svg:tspan fill="#000000"
font-weight="normal"
font-stretch="normal"
font-style="normal"
font-family="Arial"
font-size="16.000">
<svg:tspan fill="#000000"
font-weight="normal"
font-stretch="normal"
font-style="normal"
font-family="Arial"
font-size="16.000"><![CDATA[
It is not a book you can curl up at night with
]]></svg:tspan>
</svg:tspan>
</svg:tspan>
</svg:textarea>
</svg:rect>
</svg:page>
Related
I want to Get node position as attribute of a element. I means I want to get id value like Aut-01,Aut-02 inside context element. I mentioned below Input, output and tried code. I am using XSLT 2.0
Input :
<con-group>
<con c-type="aut">
<name>
<fname>Kent-Dennis</fname>
</name>
</con>
<con c-type="aut">
<name>
<fname>dfr-gvfrt</fname>
</name>
</con>
<con c-type="aut">
<con-id con-id-type="ABC11"
>https://wasq.lk/0000-0002-8551-9535</con-id>
<name>
<fname>Glazier</fname>
</name>
</con>
<con c-type="aut">
<con-id con-id-type="ABC12"
>https://wasq.lk/0000-0002-8551-8535</con-id>
<name>
<fname>Glazier</fname>
</name>
</con>
</con-group>
Output should be :
<link ref="https://orcid.org/0000-0002-8551-9535">
<context type="Aut" id="Aut-01">
<image ref="../../../../command/Templates/Template Art/Auth_.jpg"/>
</context><s/>
<link>
<link ref="https://orcid.org/0000-0002-8551-9535">
<context type="Aut" id="Aut-02">
<image ref="../../../../command/Templates/Template Art/Auth_.jpg"/>
</context><s/>
<link>
Tried code :
<xsl:template match="con-id">
<xsl:text> </xsl:text>
<link ref="{.}">
<xsl:variable name="aaa" select="count(self::con-id/preceding-sibling::*)+1"/>
<context type="Aut" id="{$aaa}">
<image ref="../../../../command/Templates/Template Art/Auth_.jpg"/>
<context><s/>
</link>
</xsl:template>
Help me to solve this. I am getting Id value always 1. As my code I don't get output that I want.
You are getting 1 each time because con-id has no preceding-siblings. (Elements are siblings if they have the same parent element). You should count preceding-siblings of the parent (but only if the preceding siblings have con-id it looks like)
<xsl:variable name="aaa" select="count(parent::*/preceding-sibling::*[con-id])+1"/>
Alternatively, you could use the preceding axis
<xsl:variable name="aaa" select="count(preceding::con-id)+1"/>
You could also use xsl:number here
<xsl:variable name="aaa">
<xsl:number count="con[con-id]" />
</xsl:variable>
If you want to use position() you would have to add another template to match con-group and then only select con-id elements (although this would only really work if you didn't have other processing you wanted to do that might clash).
<xsl:template match="con-group">
<xsl:apply-templates select="*/con-id" />
</xsl:template>
<xsl:template match="con-id">
<xsl:text> </xsl:text>
<link ref="{.}">
<xsl:variable name="aaa" select="position()" />
<context type="Aut" id="{$aaa}">
<image ref="../../../../command/Templates/Template Art/Auth_.jpg"/>
</context><s/>
</link>
</xsl:template>
<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<xsl:for-each select="//con-id">
<link ref="{.}">
<xsl:variable name="aaa" select="position()"/>
<context type="Aut" id="{$aaa}">
<image ref="../../../../command/Templates/Template Art/Auth_.jpg"/>
</context>
</link>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
Check this code:-
<xsl:template match="con">
<xsl:variable name="aaa" select="position()"/>
<xsl:for-each select="con-id">
<xsl:text> </xsl:text>
<link ref="{.}">
<context type="Aut" id="{$aaa}">
<image ref="../../../../command/Templates/Template Art/Auth_.jpg"/>
</context>
</link>
</xsl:for-each>
</xsl:template>
I am developing a pdf print publication with xsl-fo (Saxon XSL 2.0, AHF V6.2).
My goal is to have auto-numbered footnotes (excluding duplicates on a single page) with inserted text from referenced static text elements.
So basically inline footnotes (fn) do reference a static footnote text element, create an inline number and print the according footnote text at the bottom of the page.
<?xml version="1.0" encoding="UTF-8"?>
<document>
<chapter>
<paragraph>some description...</paragraph>
<paragraph>some description with a footnote <fn id="fn2"/></paragraph>
<paragraph>some description with a footnote <fn id="fn2"/></paragraph>
<paragraph>some description...</paragraph>
<paragraph>some description with a footnote <fn id="fn1"/></paragraph>
</chapter>
<!-- this is a wrapper element that will not be displayed in the rendered pdf but only contains the needed information for different footnote texts -->
<chapter class="footnoteWrapper">
<footnote id="fn1">
This is the text body of footnote #1.
</footnote>
<footnote id="fn2">
This is the text body of footnote #2.
</footnote>
<footnote id="fn3">
This is the text body of footnote #3.
</footnote>
</chapter>
</document>
Duplicate inline footnotes in a chapter have to show the same number according to the footnote they are pointing to.
This is what the result should look like...
Is it possible to achieve these goals with the AHF footnote extensions and the fo:footnote elements?
The AntennaHouse Formatter extentions do deliver strange behaviour if I´m using them for fn counting. They do continue counting (1, 2, 3) instead of refereing to the correct and current number of the referenced footnote.
This is the XSL so far (just the relevant snippet):
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs"
version="2.0">
<xsl:template match="fn[#id = //footnote/#nodeid]"
mode="content"
priority="7">
<!--+ fn link
|
| basic fn (inline) link template.
|
+-->
<xsl:apply-templates select="//footnote[#id = current()/#id]"
mode="content"/>
</xsl:template>
<xsl:template match="footnote"
mode="content"
priority="5">
<!--+ footnote
|
| basic footnote template.
|
+-->
<fo:footnote xsl:use-attribute-sets="fnt.footnote">
<fo:inline baseline-shift="super">
<axf:footnote-number id="fn_{#id}"/>
</fo:inline>
<fo:footnote-body space-after="1mm">
<fo:list-block provisional-distance-between-starts="5mm"
provisional-label-separation="2mm">
<fo:list-item>
<fo:list-item-label end-indent="label-end()">
<fo:block>
<fo:inline baseline-shift="super">
<axf:footnote-number-citation ref-id="fn_{#id}"/>
</fo:inline>
</fo:block>
</fo:list-item-label>
<fo:list-item-body start-indent="body-start()">
<fo:block>
<xsl:apply-templates mode="content"/>
</fo:block>
</fo:list-item-body>
</fo:list-item>
</fo:list-block>
</fo:footnote-body>
</fo:footnote>
</xsl:template>
</xsl:stylesheet>
These changes generate the footnote the first time that the footnote is used and just generate the number for subsequent times:
<xsl:key name="fn" match="fn[exists(key('footnote', #id))]" use="#id" />
<xsl:key name="fn-first" match="fn[. is key('fn', #id)[1]]" use="#id" />
<xsl:key name="footnote" match="footnote" use="#id" />
<xsl:template match="fn[exists(key('footnote', #id))][. is key('fn-first', #id)]"
mode="content"
priority="7">
<xsl:apply-templates select="key('footnote', #id)"
mode="content">
<xsl:with-param name="number" select="count(preceding::fn[. is key('fn-first', #id)]) + 1"></xsl:with-param>
</xsl:apply-templates>
</xsl:template>
<xsl:template match="fn[exists(key('footnote', #id))][not(. is key('fn-first', #id))]"
mode="content"
priority="7">
<fo:inline baseline-shift="super">
<xsl:value-of select="count(key('fn-first', #id)/preceding::fn[. is key('fn-first', #id)]) + 1"/>
</fo:inline>
</xsl:template>
<xsl:template match="footnote" mode="content" priority="5">
<xsl:param name="number" select="count(preceding-sibling::footnote) + 1" as="xs:integer" />
<fo:footnote xsl:use-attribute-sets="fnt.footnote">
<fo:inline baseline-shift="super">
<xsl:value-of select="$number" />
</fo:inline>
<fo:footnote-body space-after="1mm">
<fo:list-block provisional-distance-between-starts="5mm"
provisional-label-separation="2mm">
<fo:list-item>
<fo:list-item-label end-indent="label-end()">
<fo:block>
<fo:inline baseline-shift="super">
<xsl:value-of select="$number" />
</fo:inline>
</fo:block>
</fo:list-item-label>
<fo:list-item-body start-indent="body-start()">
<fo:block>
<xsl:apply-templates mode="content" />
</fo:block>
</fo:list-item-body>
</fo:list-item>
</fo:list-block>
</fo:footnote-body>
</fo:footnote>
</xsl:template>
You could tidy it up a bit more by, e.g., making a function that returns the count() value for a fn, but this should get you going.
See my other answer for how you can use both axf:suppress-duplicate-footnote and axf:footnote-number so duplicates are suppressed only when the duplicates are on the same page.
The duplicate footnotes also had duplicate IDs. The error from the non-unique IDs was getting in the way of the axf:suppress-duplicate-footnote processing.
If you're not making links to the footnotes, generate a unique ID for each footnote based on the fn that refers to it:
<xsl:template match="fn[exists(key('footnote', #id))]" mode="content" priority="7">
<!--+ fn link
|
| basic fn (inline) link template.
|
+-->
<xsl:apply-templates select="key('footnote', #id)" mode="content">
<xsl:with-param name="id" select="generate-id()" />
</xsl:apply-templates>
</xsl:template>
<xsl:template match="footnote" mode="content" priority="5">
<xsl:param name="id" />
<!--+ footnote
|
| basic footnote template.
|
+-->
<fo:footnote xsl:use-attribute-sets="fnt.footnote" axf:suppress-duplicate-footnote="true">
<fo:inline baseline-shift="super">
<axf:footnote-number id="{$id}" />
</fo:inline>
<fo:footnote-body space-after="1mm">
<fo:list-block provisional-distance-between-starts="5mm"
provisional-label-separation="2mm">
<fo:list-item>
<fo:list-item-label end-indent="label-end()">
<fo:block>
<fo:inline baseline-shift="super">
<axf:footnote-number-citation ref-id="{$id}" />
</fo:inline>
</fo:block>
</fo:list-item-label>
<fo:list-item-body start-indent="body-start()">
<fo:block>
<xsl:apply-templates mode="content" />
</fo:block>
</fo:list-item-body>
</fo:list-item>
</fo:list-block>
</fo:footnote-body>
</fo:footnote>
</xsl:template>
I'm trying to get a better understanding of the Muenchian grouping. I'm restricted to XSL 1.0. I was able to do groupings by attributes but I can't seem to get a grouping by element value to work.
My XML looks like this:
<?xml version="1.0"?>
<orders>
<order date="2015-01-01">
<product amount="8">Apple</product>
<product amount="1">Pear</product>
</order>
<order date="2015-01-01">
<product amount="1">Plum</product>
<product amount="5">Pear</product>
</order>
<order id="01" date="2015-01-03">
<product amount="10">Pear</product>
<product amount="4">Plum</product>
</order>
</orders>
What I'm trying to achieve is building a SVG diagram which shows how many of each fruit were ordered. So that one can easily see which is the top selling fruit per example. This would look like this (NOTE the amount-numbers are not resembling the XML above):
diagram: group by product
The code that I came up with so far is the following:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:svg="http://www.w3.org/2000/svg" >
<xsl:variable name="baseline" select="480"/>
<xsl:key name="group-by-product" match="product" use="." />
<xsl:template match="/orders">
<svg:svg >
<svg:g>
<xsl:apply-templates select="order/product[generate-id(.)=generate-id(key('group-by-product',.)[1])]" />
<!-- draw x- axis and y - axis -->
<svg:path style="stroke-width:2; stroke:black" >
<xsl:attribute name="d">
<xsl:text>M 40 100 L 40 </xsl:text>
<xsl:value-of select="480"/>
<xsl:text> L </xsl:text>
<xsl:value-of select="2* count(order) * 40 + 80" />
<xsl:text> </xsl:text>
<xsl:value-of select="$baseline"/>
<xsl:text> L 40 </xsl:text>
<xsl:value-of select="$baseline"/>
<xsl:text> Z</xsl:text>
</xsl:attribute>
</svg:path>
</svg:g>
</svg:svg>
</xsl:template>
<xsl:template match="order">
<xsl:variable name="y" select="sum(key('order-by-product',product)/#amount)"/>
<svg:rect x="{40 * position()+20}" y="{$baseline - $y}" width="30" height="{$y}" style="fill:blue"/>
<svg:text style="writing-mode:tb" x="{41 * position()+20}" y="{$baseline - $y - 10}">
<xsl:value-of select="$y" />
</svg:text>
<svg:text style="writing-mode:tb" x="{41 * position()+15}" y="{$baseline + 20}">
<xsl:value-of select="product" />
</svg:text>
</xsl:template>
</xsl:stylesheet>
I feel like I have some inconsistencies in my code and confused myself with all the different examples I already looked at..
If possible I would like to avoid "for-each" and use "apply-template" instead.
Thank you for your help!
You've got the Muenchian grouping logic right, but the template wrong - your apply-templates selects product elements:
<xsl:apply-templates select="order/product[generate-id(.)=generate-id(key('group-by-product',.)[1])]" />
but your second template matches order elements so it will never fire. You need to change it to something like
<xsl:template match="product">
<xsl:variable name="y" select="sum(key('order-by-product',.)/#amount)"/>
<svg:rect x="{40 * position()+20}" y="{$baseline - $y}" width="30" height="{$y}" style="fill:blue"/>
<svg:text style="writing-mode:tb" x="{41 * position()+20}" y="{$baseline - $y - 10}">
<xsl:value-of select="$y" />
</svg:text>
<svg:text style="writing-mode:tb" x="{41 * position()+15}" y="{$baseline + 20}">
<xsl:value-of select="." />
</svg:text>
</xsl:template>
I asked a similar question earlier. I have made some changes to the code, but am still stuck.
I have part of an XSLT like this:
<xsl:variable name="y" select="0" />
<xsl:if test="units_display='true'">
<xsl:call-template name="DisplayBox">
<xsl:with-param name="current_y" select="$y" />
<xsl:with-param name="value" select="units" />
<xsl:with-param name="text" select="'Units'" />
</xsl:call-template>
</xsl:if>
<xsl:if test="sensor_display='true'">
<xsl:call-template name="DisplayBox">
<xsl:with-param name="current_y" select="$y" />
<xsl:with-param name="value" select="sensor" />
<xsl:with-param name="text" select="'Type'" />
</xsl:call-template>
</xsl:if>
<xsl:if test="offset_display='true'">
<xsl:call-template name="DisplayBox">
<xsl:with-param name="current_y" select="$y" />
<xsl:with-param name="value" select="offset" />
<xsl:with-param name="text" select="'Offset'" />
</xsl:call-template>
</xsl:if>
My call-template is like this:
<xsl:template name="DisplayBox">
<xsl:param name="current_y" />
<xsl:param name="value" />
<xsl:param name="text" />
<rect x="20" y="{150 + $current_y}" width="220" height="20" fill="#FFFFFF" stroke="black" stroke-width="1" />
<text x="25" y="{168 + $current_y}" font-family="arial" font-size="20px" fill="black">
<xsl:value-of select="$value"/>
</text>
<line x1="90" y1="{150 + $current_y}" x2="90" y2="{170 + $current_y}" stroke="black" stroke-width="1" />
<text x="95" y="{168 + $current_y}" font-family="arial" font-size="20px" fill="black"><xsl:value-of select="$text" /></text>
</xsl:template>
I can't work out how to increase the value of current_y depending on whether the if statements are true or not. E,g, if a statement is true, the y value needs to be increased by 20, but not if the statement is false.
So the output could be empty if all 3 statements are false or could be any of these permutations:
Any help would be greatly appreciated.
You have to move the whole thing into a recursion template. You are passing $y for "current_y" which has the value "0" into each call of the template. That recursive template would take the same arguments and two additional:
(1) The test to perform for that round of recursion
(2) Whether you have any additional tests to perform (or exit the recursion)
Then you do a choose and increment the "y" (or not) depending on the test.
* New Info *
After some more thought based on the comments below, what about using something like this:
<xsl:template match="units_display | sensor_display | offset_display">
<xsl:variable name="y-multiplier">
<xsl:value-of select="count(preceding-sibling::units_display[.='true']) + count(preceding-sibling::sensor_display[.='true']) + count(preceding-sibling::offset_display[.='true'])"/>
</xsl:variable>
<xsl:message>
<xsl:value-of select="$y-multiplier"/>
</xsl:message>
</xsl:template>
This counts all of the elements that meet you criteria as you go through the document. This should get you started toward writing the result without recursion.
What i'm trying to do is to use call-template:SpecialRadio on a Radio elements by looping through each one of them, extracting the data by position and then performing XSLT on them. For some reason, the radio buttons show up, but the Caption data for the StaticLabel is not showing up, i.e. 'Postanschrift' and 'SMS / MMS'. Where did i go wrong in my XSL?
Given jsp-include.xsl
<xsl:template name="SpecialRadio">
<xsl:param name="name"/>
<xsl:param name="map"/>
<xsl:param name="radio"/>
<xsl:param name="radioStyle"/>
<xsl:param name="radioLabel"/>
<xsl:param name="i"/>
<StaticLabel>
<xsl:attribute name="style">
<xsl:copy-of select="$radioStyle[position()=$i]/#style"/>
<xsl:text>; margin-left:500px</xsl:text>
</xsl:attribute>
<xsl:copy-of select="$radioLabel[position()=$i]/#Caption"/>
</StaticLabel>
<Radio>
<ReadOnly>false</ReadOnly>
<Map rtexprvalue="true">mb.getLookup("YES_NO")</Map>
<Name rtexprvalue="true"><xsl:value-of select="$radio/Name"/></Name>
<Default rtexprvalue="true">mb.getValue("<xsl:value-of select="Name"/>")/Default>
</Radio>
</xsl:template>
Given Main.xsl
<div id="head">
<xsl:call-template name="JspInclude">
<xsl:with-param name="flush" select="'true'"/>
<xsl:with-param name="file" select="'Header_1_D.jsp'"/>
</xsl:call-template>
<xsl:for-each select="$radio[position() <= 4]">
<xsl:call-template name="SpecialRadio">
<xsl:with-param name="i" select="position()"/>
<xsl:with-param name="name" select="FieldList[#group='2']/Radio/Name"/>
<xsl:with-param name="map" select="FieldList[#group='2']/Radio/Map"/>
<xsl:with-param name="radio" select="FieldList[#group='2']/Radio"/>
<xsl:with-param name="radioStyle" select="FieldList[#group='2']/StaticLabel"/>
<xsl:with-param name="radioLabel" select="FieldList[#group='2']/StaticLabel"/>
</xsl:call-template>
Given XML
<FieldList group="2">
<StaticLabel style="font-family:Arial;color:#330000;font-size:9pt">
<Caption><![CDATA[Postanschrift]]></Caption>
<Name><![CDATA[APPLICATION_CUSTOMER.APPLICATION_TYPE]]></Name>
</StaticLabel>
<Radio>
<EntityID><![CDATA[6100]]></EntityID>
<Name><![CDATA[APPLICATION_CUSTOMER.APPLICATION_TYPE]]></Name>
<FieldType><![CDATA[]]></FieldType>
<Default rtexprvalue="true"><![CDATA[mb.getValue("APPLICATION_CUSTOMER.APPLICATION_TYPE", "")]]></Default>
<Map rtexprvalue="true"><![CDATA[mb.getLookup("YES_NO", "CODE", "NAME", "EN", false,"")]]></Map>
<ReadOnly rtexprvalue="true"><![CDATA[mb.isReadonly(2)]]></ReadOnly>
<AccessType><![CDATA[2]]></AccessType>
<SearchMatchFlag><![CDATA[]]></SearchMatchFlag>
<InvalidatePlanFlag><![CDATA[false]]></InvalidatePlanFlag>
</Radio>
<StaticLabel style="font-family:Arial;color:#330000;font-size:9pt">
<Caption><![CDATA[SMS / MMS]]></Caption>
<Name><![CDATA[APPLICATION_CUSTOMER.APPLICATION_TYPE]]></Name>
</StaticLabel>
<Radio>
<EntityID><![CDATA[6101]]></EntityID>
<Name><![CDATA[APPLICATION_CUSTOMER.APPLICATION_TYPE]]></Name>
<FieldType><![CDATA[]]></FieldType>
<Default rtexprvalue="true"><![CDATA[mb.getValue("APPLICATION_CUSTOMER.APPLICATION_TYPE", "")]]></Default>
<Map rtexprvalue="true"><![CDATA[mb.getLookup("YES_NO", "CODE", "NAME", "EN", false,"")]]></Map>
<ReadOnly rtexprvalue="true"><![CDATA[mb.isReadonly(2)]]></ReadOnly>
<AccessType><![CDATA[2]]></AccessType>
<SearchMatchFlag><![CDATA[]]></SearchMatchFlag>
<InvalidatePlanFlag><![CDATA[false]]></InvalidatePlanFlag>
</Radio>
</FieldList>
Resulting XSLT using Altova
<div id="head">
<HtmlCode xmlns:jsp="http://www.microforum.com/calms/tags/jsptag-1">
<jsp:include flush="true" page="Header_1_D.jsp"/>
</HtmlCode>
<StaticLabel xmlns:jsp="http://www.microforum.com/calms/tags/jsptag-1" style="; margin-left:500px"/>
<Radio xmlns:jsp="http://www.microforum.com/calms/tags/jsptag-1">
<ReadOnly>false</ReadOnly>
<Map rtexprvalue="true">mb.getLookup("YES_NO")</Map>
<Name rtexprvalue="true"/>
<Default rtexprvalue="true">mb.getValue("APPLICATION_CUSTOMER.APPLICATION_TYPE")</Default>
</Radio>
<StaticLabel xmlns:jsp="http://www.microforum.com/calms/tags/jsptag-1" style="; margin-left:500px"/>
<Radio xmlns:jsp="http://www.microforum.com/calms/tags/jsptag-1">
<ReadOnly>false</ReadOnly>
<Map rtexprvalue="true">mb.getLookup("YES_NO")</Map>
<Name rtexprvalue="true"/>
<Default rtexprvalue="true">mb.getValue("APPLICATION_CUSTOMER.APPLICATION_TYPE")</Default>
</Radio>
<HtmlCode>
<br/>
<br/>
<br/>
</HtmlCode>
</div>
Shouldn't it be along the lines of this -
<xsl:copy-of select="$radioLabel[position()=$i]/Caption"/>
since Caption is an element, not an attribute?