Apply-templates with-param problem / question
Here should go questions about transforming XML with XSLT and FOP.
-
- Posts: 3
- Joined: Thu Jan 10, 2008 11:49 pm
- Location: Schaffhausen
Apply-templates with-param problem / question
Post by Stefan Messmer »
Hi all,
I observed a problem that seems to be a little strange. I defined a variable "date" with the following content:
<Cluster Name="Time stamp" NumElts="10">
<DBL Name="fractional second">0.13610</DBL>
<I32 Name="second">4</I32>
<I32 Name="minute">21</I32>
<I32 Name="hour">11</I32>
<I32 Name="day of month">4</I32>
<I32 Name="month">4</I32>
<I32 Name="year">2007</I32>
<I32 Name="day of week">4</I32>
<I32 Name="day of year">94</I32>
<I32 Name="DST">1</I32>
</Cluster>
The variable therefore contains a node set. Then I applied a template the following way:
<xsl:apply-template match=".">
<xsl:with-param name="my-date" select="$date"/>
</xsl:apply-template>
The template should replace an element <date/> with the actual date. The template looks the following:
<xsl:template match="date">
<xsl:param name="my-date"/>
.....
.....
</xsl:template>
Now the problem: Saxon 6.5, Xalan, Firefox, Opera will return an error, because the content of the variable my-date is a string and not a node set. Safari (xslt.lib) and Saxon 9 process this code as expected.
Which behavior is correct? Does anybody know a workaround?
Thanks for your help
Stefan Messmer
I observed a problem that seems to be a little strange. I defined a variable "date" with the following content:
<Cluster Name="Time stamp" NumElts="10">
<DBL Name="fractional second">0.13610</DBL>
<I32 Name="second">4</I32>
<I32 Name="minute">21</I32>
<I32 Name="hour">11</I32>
<I32 Name="day of month">4</I32>
<I32 Name="month">4</I32>
<I32 Name="year">2007</I32>
<I32 Name="day of week">4</I32>
<I32 Name="day of year">94</I32>
<I32 Name="DST">1</I32>
</Cluster>
The variable therefore contains a node set. Then I applied a template the following way:
<xsl:apply-template match=".">
<xsl:with-param name="my-date" select="$date"/>
</xsl:apply-template>
The template should replace an element <date/> with the actual date. The template looks the following:
<xsl:template match="date">
<xsl:param name="my-date"/>
.....
.....
</xsl:template>
Now the problem: Saxon 6.5, Xalan, Firefox, Opera will return an error, because the content of the variable my-date is a string and not a node set. Safari (xslt.lib) and Saxon 9 process this code as expected.
Which behavior is correct? Does anybody know a workaround?
Thanks for your help
Stefan Messmer
-
- Posts: 501
- Joined: Mon Feb 03, 2003 10:56 am
How did you defined the variable?
In the stylesheet, like the following, or it was given as a parameter to the XSLT processor?
I have tried this and worked correctly:
Can you give a complete sample? XSL, XML input, parameters?
Cheers,
Dan
In the stylesheet, like the following, or it was given as a parameter to the XSLT processor?
Code: Select all
<xsl:variable name="date">
<Cluster Name="Time stamp" NumElts="10">
<DBL Name="fractional second">0.13610</DBL>
<I32 Name="second">4</I32>
<I32 Name="minute">21</I32>
<I32 Name="hour">11</I32>
<I32 Name="day of month">4</I32>
<I32 Name="month">4</I32>
<I32 Name="year">2007</I32>
<I32 Name="day of week">4</I32>
<I32 Name="day of year">94</I32>
<I32 Name="DST">1</I32>
</Cluster>
</xsl:variable>
Code: Select all
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output indent="yes"/>
<xsl:variable name="date">
<Cluster Name="Time stamp" NumElts="10">
<DBL Name="fractional second">0.13610</DBL>
<I32 Name="second">4</I32>
<I32 Name="minute">21</I32>
<I32 Name="hour">11</I32>
<I32 Name="day of month">4</I32>
<I32 Name="month">4</I32>
<I32 Name="year">2007</I32>
<I32 Name="day of week">4</I32>
<I32 Name="day of year">94</I32>
<I32 Name="DST">1</I32>
</Cluster>
</xsl:variable>
<xsl:template match="/">
<xsl:apply-templates select="//date">
<xsl:with-param name="my-date" select="$date"/>
</xsl:apply-templates>
</xsl:template>
<xsl:template match="date">
<xsl:param name="my-date"/>
<out>
<xsl:copy-of select="$my-date"/>
</out>
</xsl:template>
</xsl:stylesheet>
Cheers,
Dan
-
- Posts: 89
- Joined: Mon Mar 06, 2006 10:13 pm
Saxon 9 is a XSLT 2.0 processor is it not?
As such it would probably ignore these errors.
The behaviour that is correct is throwing the error.
If you're looking for compatibility, why not use the exsl:node-set extension?
Another work-around. Encase in wrapper and use document function to retrieve.
The select attribute xpath ensures that these are treated as actual nodes.
As such it would probably ignore these errors.
The behaviour that is correct is throwing the error.
If you're looking for compatibility, why not use the exsl:node-set extension?
Code: Select all
xmlns:exsl="http://exslt.org/common"
...
<xsl:with-param name="my-date" select="exsl:node-set($date)"/>
The select attribute xpath ensures that these are treated as actual nodes.
Code: Select all
<my:mapping xmlns:my="internal">
<Cluster Name="Time stamp" NumElts="10">
<DBL Name="fractional second">0.13610</DBL>
<I32 Name="second">4</I32>
<I32 Name="minute">21</I32>
<I32 Name="hour">11</I32>
<I32 Name="day of month">4</I32>
<I32 Name="month">4</I32>
<I32 Name="year">2007</I32>
<I32 Name="day of week">4</I32>
<I32 Name="day of year">94</I32>
<I32 Name="DST">1</I32>
</Cluster>
</my:mapping>
<xsl:variable name="date" select="document('')//Cluster"/>
-
- Posts: 3
- Joined: Thu Jan 10, 2008 11:49 pm
- Location: Schaffhausen
Post by Stefan Messmer »
Hi all
I have prepared an example. It should demonstrate my problem and it should be simple enough to understand quickly. First of all, the xml file:
The corresponding stylesheet is as follows:
I hope this helps to clarify the problem.
Best regards
Stefan Messmer[/code]
I have prepared an example. It should demonstrate my problem and it should be simple enough to understand quickly. First of all, the xml file:
Code: Select all
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="test.xsl" ?>
<data>
<Cluster Name="test-date" NumElts="10">
<DBL Name="fractional second">0.13610</DBL>
<I32 Name="second">4</I32>
<I32 Name="minute">21</I32>
<I32 Name="hour">11</I32>
<I32 Name="day of month">4</I32>
<I32 Name="month">4</I32>
<I32 Name="year">2007</I32>
<I32 Name="day of week">4</I32>
<I32 Name="day of year">94</I32>
<I32 Name="DST">1</I32>
</Cluster>
<String Name="rope-name">Zugseil</String>
<String Name="test-advice">Seilverordnung</String>
<String Name="installation-name-nickname">Musteranlage</String>
<Section Name="section-1" Printflag="true">
<Textblock Name="Entspricht Seilverordnung">Das <rope-name/> der Anlage
<installation-name-nickname/> entsprach zum Zeitpunkt der Prüfung am <test-date
format="short"/> in den geprüften Bereichen den Anforderungen der
<test-advice/>.</Textblock>
<Section Name="subsection-11" Printflag="true">
<Textblock Name="Entspricht Seilverordnung">Das <rope-name/> der Anlage
<installation-name-nickname/> entsprach zum Zeitpunkt der Prüfung am <test-date
format="abbreviated"/> in den geprüften Bereichen den Anforderungen der
<test-advice/>.</Textblock>
<Textblock Name="Entspricht Seilverordnung">Das <rope-name/> der Anlage
<installation-name-nickname/> entsprach zum Zeitpunkt der Prüfung am <test-date
format="long"/> in den geprüften Bereichen den Anforderungen der
<test-advice/>.</Textblock>
</Section>
<Textblock Name="Entspricht Seilverordnung">Das <rope-name/> der Anlage
<installation-name-nickname/> entsprach zum Zeitpunkt der Prüfung am <test-date
format="short"/> in den geprüften Bereichen den Anforderungen der
<test-advice/>.</Textblock>
</Section>
</data>
Code: Select all
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:template match="data">
<xsl:variable name="test-date" select="Cluster[@Name='test-date']"/>
<xsl:variable name="test-advice" select="String[@Name='test-advice']"/>
<xsl:variable name="rope-name" select="String[@Name='rope-name']"/>
<xsl:variable name="installation-name-nickname" select="String[@Name='installation-name-nickname']"/>
<htmL>
<title>Report</title>
<body>
<xsl:for-each select="//Textblock"><p>
<xsl:apply-templates select=".">
<xsl:with-param name="my-date" select="$test-date"/>
<xsl:with-param name="my-advice" select="$test-advice"/>
<xsl:with-param name="my-rope-name" select="$rope-name"></xsl:with-param>
<xsl:with-param name="my-installation-name" select="$installation-name-nickname"></xsl:with-param>
</xsl:apply-templates></p>
</xsl:for-each>
</body>
</htmL>
</xsl:template>
<xsl:template match="test-advice">
<xsl:param name="my-advice"/>
<xsl:value-of select="$my-advice"/>
</xsl:template>
<xsl:template match="rope-name">
<xsl:param name="my-rope-name"/>
<xsl:value-of select="$my-rope-name"/>
</xsl:template>
<xsl:template match="installation-name-nickname">
<xsl:param name="my-installation-name"/>
<xsl:value-of select="$my-installation-name"/>
</xsl:template>
<xsl:template match="test-date">
<xsl:param name="my-date"/>
<xsl:variable name="format" select="@format"/>
<xsl:choose>
<xsl:when test="$format = 'short'">
<xsl:value-of select="$my-date/I32[@Name='day of month']"/>.<xsl:value-of
select="$my-date/I32[@Name='month']"/>.<xsl:value-of
select="$my-date/I32[@Name='year']"/>
</xsl:when>
<xsl:when test="$format = 'abbreviated'">
<xsl:value-of select="$my-date/I32[@Name='day of month']"/>.<xsl:choose>
<xsl:when test="$my-date/I32[@Name='month']=1"> Jan </xsl:when>
<xsl:when test="$my-date/I32[@Name='month']=2"> Feb </xsl:when>
<xsl:when test="$my-date/I32[@Name='month']=3"> Mar </xsl:when>
<xsl:when test="$my-date/I32[@Name='month']=4"> Apr </xsl:when>
<xsl:when test="$my-date/I32[@Name='month']=5"> Mai </xsl:when>
<xsl:when test="$my-date/I32[@Name='month']=6"> Jun </xsl:when>
<xsl:when test="$my-date/I32[@Name='month']=7"> Jul </xsl:when>
<xsl:when test="$my-date/I32[@Name='month']=8"> Aug </xsl:when>
<xsl:when test="$my-date/I32[@Name='month']=9"> Sep </xsl:when>
<xsl:when test="$my-date/I32[@Name='month']=10"> Okt </xsl:when>
<xsl:when test="$my-date/I32[@Name='month']=11"> Nov </xsl:when>
<xsl:when test="$my-date/I32[@Name='month']=12"> Dez </xsl:when>
<xsl:otherwise>(Fehler im Datum)</xsl:otherwise>
</xsl:choose><xsl:value-of select="$my-date/I32[@Name='year']"/>
</xsl:when>
<xsl:when test="$format = 'long'">
<xsl:value-of select="$my-date/I32[@Name='day of month']"/>.<xsl:choose>
<xsl:when test="$my-date/I32[@Name='month']=1"> Januar </xsl:when>
<xsl:when test="$my-date/I32[@Name='month']=2"> Februar </xsl:when>
<xsl:when test="$my-date/I32[@Name='month']=3"> März </xsl:when>
<xsl:when test="$my-date/I32[@Name='month']=4"> April </xsl:when>
<xsl:when test="$my-date/I32[@Name='month']=5"> Mai </xsl:when>
<xsl:when test="$my-date/I32[@Name='month']=6"> Juni </xsl:when>
<xsl:when test="$my-date/I32[@Name='month']=7"> Juli </xsl:when>
<xsl:when test="$my-date/I32[@Name='month']=8"> August </xsl:when>
<xsl:when test="$my-date/I32[@Name='month']=9"> September </xsl:when>
<xsl:when test="$my-date/I32[@Name='month']=10"> Oktober </xsl:when>
<xsl:when test="$my-date/I32[@Name='month']=11"> November </xsl:when>
<xsl:when test="$my-date/I32[@Name='month']=12"> Dezember </xsl:when>
<xsl:otherwise>(Fehler im Datum)</xsl:otherwise>
</xsl:choose><xsl:value-of select="$my-date/I32[@Name='year']"/>
</xsl:when>
<xsl:otherwise>(Nicht unterstütztes Format "<xsl:value-of select="$format"
/>")</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
Best regards
Stefan Messmer[/code]
-
- Posts: 501
- Joined: Mon Feb 03, 2003 10:56 am
Changing the stylesheet version to "1.1" and changing the apply-templates select value from "." to "./*" seems to fix the problem when using Saxon 6, Xalan, Firefox (I have not tested IE and Opera):
More reading about the node-sets here:http://www.xml.com/pub/a/2003/07/16/nodeset.html
Code: Select all
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.1">
........
<xsl:apply-templates select="./*">
-
- Posts: 3
- Joined: Thu Jan 10, 2008 11:49 pm
- Location: Schaffhausen
Post by Stefan Messmer »
Hi all,
I found another solution. The stylesheet is attached below.
Many thanks for your help
Stefan Messmer
I found another solution. The stylesheet is attached below.

Many thanks for your help
Stefan Messmer
Code: Select all
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:template match="data">
<xsl:variable name="test-date" select="Cluster[@Name='test-date']"/>
<xsl:variable name="test-advice" select="String[@Name='test-advice']"/>
<xsl:variable name="rope-name" select="String[@Name='rope-name']"/>
<xsl:variable name="installation-name-nickname"
select="String[@Name='installation-name-nickname']"/>
<html>
<title>Report</title>
<body>
<xsl:for-each select="//Textblock">
<p>
<xsl:apply-templates>
<xsl:with-param name="my-date" select="$test-date"/>
<xsl:with-param name="my-advice" select="$test-advice"/>
<xsl:with-param name="my-rope-name" select="$rope-name"/>
<xsl:with-param name="my-installation-name" select="$installation-name-nickname"/>
</xsl:apply-templates>
</p>
</xsl:for-each>
</body>
</html>
</xsl:template>
<xsl:template match="test-advice">
<xsl:param name="my-advice"/>
<xsl:value-of select="$my-advice"/>
</xsl:template>
<xsl:template match="rope-name">
<xsl:param name="my-rope-name"/>
<xsl:value-of select="$my-rope-name"/>
</xsl:template>
<xsl:template match="installation-name-nickname">
<xsl:param name="my-installation-name"/>
<xsl:value-of select="$my-installation-name"/>
</xsl:template>
<xsl:template match="test-date">
<xsl:param name="my-date"/>
<xsl:variable name="format" select="@format"/>
<xsl:choose>
<xsl:when test="$format = 'short'">
<xsl:value-of select="$my-date/I32[@Name='day of month']"/>.<xsl:value-of
select="$my-date/I32[@Name='month']"/>.<xsl:value-of select="$my-date/I32[@Name='year']"/>
</xsl:when>
<xsl:when test="$format = 'abbreviated'">
<xsl:value-of select="$my-date/I32[@Name='day of month']"/>.<xsl:choose>
<xsl:when test="$my-date/I32[@Name='month']=1"> Jan </xsl:when>
<xsl:when test="$my-date/I32[@Name='month']=2"> Feb </xsl:when>
<xsl:when test="$my-date/I32[@Name='month']=3"> Mar </xsl:when>
<xsl:when test="$my-date/I32[@Name='month']=4"> Apr </xsl:when>
<xsl:when test="$my-date/I32[@Name='month']=5"> Mai </xsl:when>
<xsl:when test="$my-date/I32[@Name='month']=6"> Jun </xsl:when>
<xsl:when test="$my-date/I32[@Name='month']=7"> Jul </xsl:when>
<xsl:when test="$my-date/I32[@Name='month']=8"> Aug </xsl:when>
<xsl:when test="$my-date/I32[@Name='month']=9"> Sep </xsl:when>
<xsl:when test="$my-date/I32[@Name='month']=10"> Okt </xsl:when>
<xsl:when test="$my-date/I32[@Name='month']=11"> Nov </xsl:when>
<xsl:when test="$my-date/I32[@Name='month']=12"> Dez </xsl:when>
<xsl:otherwise>(Fehler im Datum)</xsl:otherwise>
</xsl:choose><xsl:value-of select="$my-date/I32[@Name='year']"/>
</xsl:when>
<xsl:when test="$format = 'long'">
<xsl:value-of select="$my-date/I32[@Name='day of month']"/>.<xsl:choose>
<xsl:when test="$my-date/I32[@Name='month']=1"> Januar </xsl:when>
<xsl:when test="$my-date/I32[@Name='month']=2"> Februar </xsl:when>
<xsl:when test="$my-date/I32[@Name='month']=3"> März </xsl:when>
<xsl:when test="$my-date/I32[@Name='month']=4"> April </xsl:when>
<xsl:when test="$my-date/I32[@Name='month']=5"> Mai </xsl:when>
<xsl:when test="$my-date/I32[@Name='month']=6"> Juni </xsl:when>
<xsl:when test="$my-date/I32[@Name='month']=7"> Juli </xsl:when>
<xsl:when test="$my-date/I32[@Name='month']=8"> August </xsl:when>
<xsl:when test="$my-date/I32[@Name='month']=9"> September </xsl:when>
<xsl:when test="$my-date/I32[@Name='month']=10"> Oktober </xsl:when>
<xsl:when test="$my-date/I32[@Name='month']=11"> November </xsl:when>
<xsl:when test="$my-date/I32[@Name='month']=12"> Dezember </xsl:when>
<xsl:otherwise>(Fehler im Datum)</xsl:otherwise>
</xsl:choose><xsl:value-of select="$my-date/I32[@Name='year']"/>
</xsl:when>
<xsl:otherwise>(Nicht unterstütztes Format "<xsl:value-of select="$format"
/>")</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
-
- Posts: 89
- Joined: Mon Mar 06, 2006 10:13 pm
Another alternative to wieldly nested choose clauses is this little trick:
<my:mapping xmlns:my="internal">
<month short="1" abr="Jan" long="Januar" />
<month short="2" abr="Feb" long="Februar" />
<month short="3" abr="Mar" long="März" />
<month short="4" abr="Apr" long="April" />
<month short="5" abr="Mai" long="Mai" />
<month short="6" abr="Jun" long="Juni" />
<month short="7" abr="Jul" long="Juli" />
<month short="8" abr="Aug" long="August" />
<month short="9" abr="Sep" long="September" />
<month short="10" abr="Okt" long="Oktober" />
<month short="11" abr="Nov" long="November" />
<month short="12" abr="Dez" long="Dezember" />
</my:mapping>
<xsl:variable name="monthNum" select="$my-date/I32[@Name='month']"/>
Then in your abbreviated choose clause could have something like
<xsl:value-of select="document('')//month[@short=$monthNum]/@abr"/>
long choose clause:
<xsl:value-of select="document('')//month[@short=$monthNum]/@long"/>
This may be of use to you.
<my:mapping xmlns:my="internal">
<month short="1" abr="Jan" long="Januar" />
<month short="2" abr="Feb" long="Februar" />
<month short="3" abr="Mar" long="März" />
<month short="4" abr="Apr" long="April" />
<month short="5" abr="Mai" long="Mai" />
<month short="6" abr="Jun" long="Juni" />
<month short="7" abr="Jul" long="Juli" />
<month short="8" abr="Aug" long="August" />
<month short="9" abr="Sep" long="September" />
<month short="10" abr="Okt" long="Oktober" />
<month short="11" abr="Nov" long="November" />
<month short="12" abr="Dez" long="Dezember" />
</my:mapping>
<xsl:variable name="monthNum" select="$my-date/I32[@Name='month']"/>
Then in your abbreviated choose clause could have something like
<xsl:value-of select="document('')//month[@short=$monthNum]/@abr"/>
long choose clause:
<xsl:value-of select="document('')//month[@short=$monthNum]/@long"/>
This may be of use to you.
Jump to
- Oxygen XML Editor/Author/Developer
- ↳ Feature Request
- ↳ Common Problems
- ↳ DITA (Editing and Publishing DITA Content)
- ↳ SDK-API, Frameworks - Document Types
- ↳ DocBook
- ↳ TEI
- ↳ XHTML
- ↳ Other Issues
- Oxygen XML Web Author
- ↳ Feature Request
- ↳ Common Problems
- Oxygen Content Fusion
- ↳ Feature Request
- ↳ Common Problems
- Oxygen JSON Editor
- ↳ Feature Request
- ↳ Common Problems
- Oxygen PDF Chemistry
- ↳ Feature Request
- ↳ Common Problems
- Oxygen Feedback
- ↳ Feature Request
- ↳ Common Problems
- Oxygen XML WebHelp
- ↳ Feature Request
- ↳ Common Problems
- XML
- ↳ General XML Questions
- ↳ XSLT and FOP
- ↳ XML Schemas
- ↳ XQuery
- NVDL
- ↳ General NVDL Issues
- ↳ oNVDL Related Issues
- XML Services Market
- ↳ Offer a Service