You are viewing a plain text version of this content. The canonical link for it is here.
Posted to j-users@xalan.apache.org by John Nikolai <jn...@mac.com> on 2003/03/06 01:34:31 UTC

[Q] move common xslt to "template" file?

OK, I'm a bit new to Xalan and XSLT so the following may or may not be 
the "proper" way to implement things. So if you see any glaring 
problems, please let me know! =)

Basically I'm sorting an XML document (based on the date element) and  
dumping the contents into another XML document using the same elements 
and structure. Is this the best way to do sorting? We will have a 
rather large (100 to 200 event elements) XML file to walk through and I 
don't see any API in Xerces to sort a Document object...

I also have one more question which requires a look at the XML and XSL 
documents.

I have the following XML document:
------
<?xml version="1.0" encoding="UTF-8"?>
<calendar>
     <event>
         <date>2003-03-26</date>
         <name>BPC conference named event #-1186335162</name>
         <type>BPC conference</type>
         <theme>uh... theme???</theme>
         <description>BPC conference helpful description...</description>
     </event>
     <event>
         <date>2003-02-12</date>
         <name>LEIP conference named event #-1992363215</name>
         <type>LEIP conference</type>
         <theme>uh... theme???</theme>
         <description>LEIP conference helpful 
description...</description>
     </event>
</calendar>
------

and 2 different XSL documents:
-----
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
                 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                 xmlns:xalan="http://xml.apache.org/xslt">

   	<xsl:output method="xml"
   				indent="yes"
				xalan:indent-amount="4" />

	<xsl:template match="/">
		<calendar>
			<xsl:apply-templates />
		</calendar>
	</xsl:template>
	
	<xsl:template match="calendar">
		<xsl:for-each select="event">
				<xsl:choose>
					<xsl:when test="number(substring(date,6,2)) &gt; 2
										and number(substring(date,9,2)) &gt; 1
										and number(substring(date,9,2)) &lt; 5">
										
						<event>
							<date> <xsl:value-of select="date" /> </date>
							<name> <xsl:value-of select="name" /> </name>
							<type> <xsl:value-of select="type" /> </type>
							<theme> <xsl:value-of select="theme" /> </theme>
							<description> <xsl:value-of select="description" /> 
</description>
						</event>
					</xsl:when>
				</xsl:choose>
		</xsl:for-each>
	</xsl:template>
</xsl:stylesheet>
-----
and ...
-----
  <xsl:output method="xml"
   				indent="yes"
				xalan:indent-amount="4" />
				
	<xsl:template match="/">
		<calendar>
			<xsl:apply-templates />
		</calendar>
	</xsl:template>
	
	<xsl:template match="calendar">
		<xsl:for-each select="event">
			<!-- <xsl:apply-templates> -->
				<!-- substring(element, start_index, length) -->
				<xsl:sort select="substring(date,1,4)"/> <!-- year -->
				<xsl:sort select="substring(date,6,2)"/> <!-- month -->
				<xsl:sort select="substring(date,9,2)"/> <!-- day -->
				
				<event>
					<date> <xsl:value-of select="date" /> </date>
					<name> <xsl:value-of select="name" /> </name>
					<type> <xsl:value-of select="type" /> </type>
					<theme> <xsl:value-of select="theme" /> </theme>
					<description> <xsl:value-of select="description" /> </description>
				</event>
			<!-- </xsl:apply-templates> -->
		</xsl:for-each>
	</xsl:template>
</xsl:stylesheet>
-----

I get the output we want but was wondering if its possible to move this 
code:
-----
<event>
   <date> <xsl:value-of select="date" /> </date>
   <name> <xsl:value-of select="name" /> </name>
   <type> <xsl:value-of select="type" /> </type>
   <theme> <xsl:value-of select="theme" /> </theme>
   <description> <xsl:value-of select="description" /> </description>
</event>
-----

... into a template which could be imported to each of the XSL 
documents as needed. I tried using <xsl:import> and <xsl:include> 
thinking these were similar to the JSP counter parts but that's not the 
case. The reason we want to does this  is that if the XML document 
changes we only want to update a single XSL document. Of course if the 
date element name changes we would have to modify the XSL accordingly...

I know the following does not work but this gives you an idea of what 
we want... Note that the only change is hte inclusion of "<xsl:import 
href="event_xml_format.xsl" />"
-------
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
                 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                 xmlns:xalan="http://xml.apache.org/xslt">

   	<xsl:output method="xml"
   				indent="yes"
				xalan:indent-amount="4" />

	<xsl:template match="/">
		<calendar>
			<xsl:apply-templates />
		</calendar>
	</xsl:template>
	
	<xsl:template match="calendar">
		<xsl:for-each select="event">
				<xsl:choose>
					<xsl:when test="number(substring(date,6,2)) &gt; 2
										and number(substring(date,9,2)) &gt; 1
										and number(substring(date,9,2)) &lt; 5">
										
						<xsl:import href="event_xml_format.xsl" />
					</xsl:when>
				</xsl:choose>
		</xsl:for-each>
	</xsl:template>
</xsl:stylesheet>
-------

Sorry for such a huge email...
Thanks much for your help!
  - John



  

Re: [Q] move common xslt to "template" file?

Posted by Christophe Galerne <ch...@earthlink.net>.
Hi,

John Nikolai wrote:
> Basically I'm sorting an XML document (based on the date element) and 
> dumping the contents into another XML document using the same elements 
> and structure.

I think you are trying too hard. Dumping the contents of a XML document
is what <xsl:copy-of> is for.

Try this:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet
	version="1.0"
	xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
	xmlns:xalan="http://xml.apache.org/xslt">

<xsl:output method="xml" indent="yes" xalan:indent-amount="4"/>

<xsl:template match="calendar">
	<calendar>
		<!-- also dump calendar attributes if any -->
		<xsl:copy-of select="@*"/>
		<xsl:apply-templates select="event">
			<xsl:sort select="date"/>
		</xsl:apply-templates>
	</calendar>
</xsl:template>

<xsl:template match="event">
	<xsl:copy-of select="."/>
</xsl:template>

</xsl:stylesheet>

HTH,
Christophe



Re: [Q] move common xslt to "template" file?

Posted by kl...@attbi.com.
For your second question, to handle the 
duplicated piece of <event> 
...
</event>
elements, one way to handle this would be to 
write a named template which spit out this set 
of elements. Put this in the separate 
stylesheet which gets included at the top of 
the other two stylesheets (like a C header 
file). Then use call-template to invoke this 
at the correct spots. You may have to pass the 
current node (.) as a parameter.