RE: [xsl] Weird XSLT processor output

Subject: RE: [xsl] Weird XSLT processor output
From: "Michael Kay" <mhk@xxxxxxxxx>
Date: Mon, 10 Nov 2003 23:19:52 -0000
Saxon also produces the output you consider weird, which is actually the
correct output.

When you write:

            <xsl:for-each select="$globalTableNames">
                 <xsl:element name="TABLE">
			  <xsl:attribute name="tableid"><xsl:value-of
select="."/></xsl:attribute>
			  <xsl:variable name="tablename"><xsl:value-of
select="."/></xsl:variable>
     	               <xsl:apply-templates
select="/DGS/BOOKMARKS/TABLEID[BMTABLE = $tablename]"/>
     	          </xsl:element>
     	     </xsl:for-each>

the absolute path expression /DGS/... selects relative to the root node
of the document containing the context node. The context node is an
element in $globalTableNames, which came from document('')/..., that is,
from the stylesheet. The stylesheet does not have a /DGS element as the
outermost element, so this expression selects nothing and the
apply-templates produces no output.

To select from the root of the principal source document, declare a
global variable

<xsl:variable name="root" select="/">

and use 

<xsl:apply-templates select="$root/DGS/BOOKMARKS/TABLEID[BMTABLE =
$tablename]"/>

Michael Kay



> -----Original Message-----
> From: owner-xsl-list@xxxxxxxxxxxxxxxxxxxxxx 
> [mailto:owner-xsl-list@xxxxxxxxxxxxxxxxxxxxxx] On Behalf Of 
> David Carver
> Sent: 10 November 2003 22:27
> To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx
> Subject: [xsl] Weird XSLT processor output
> 
> 
> Okay here is the situation, given the following input XML: <DGS>
> 	<BOOKMARKS>
> 		<TABLEID>
> 			<BMTABLE>CLAIMANT</BMTABLE>
> 			<BMDESC>Address 1</BMDESC>
> 			<BMFIELD>ADDRESS1</BMFIELD>
> 			<XSLTEMP>&lt;xsl:template 
> match=&quot;CLAIMANT/ADDRESS1&quot;&gt;&lt;xsl:value-of
> select=&quot;.&quot;/&gt;&lt;/xsl:template&gt;</XSLTEMP>
> 		</TABLEID>
> 		<TABLEID>
> 			<BMTABLE>CLAIMANT</BMTABLE>
> 			<BMDESC>Address 2</BMDESC>
> 			<BMFIELD>ADDRESS2</BMFIELD>
> 			<XSLTEMP>&lt;xsl:template 
> match=&quot;CLAIMANT/ADDRESS2&quot;&gt;&lt;xsl:value-of
> select=&quot;.&quot;/&gt;&lt;/xsl:template&gt;</XSLTEMP>
> 		</TABLEID>
> 		<TABLEID>
> 			<BMTABLE>CLAIMANT</BMTABLE>
> 			<BMDESC>ANUMBER</BMDESC>
> 			<BMFIELD>ANUMBER</BMFIELD>
> 			<XSLTEMP>&lt;xsl:template 
> match=&quot;CLAIMANT/ANUMBER&quot;&gt;&lt;xsl:value-of
> select=&quot;.&quot;/&gt;&lt;/xsl:template&gt;</XSLTEMP>
> 		</TABLEID>
> 		<TABLEID>
> 			<BMTABLE>CLMREP</BMTABLE>
> 			<BMDESC>State</BMDESC>
> 			<BMFIELD>STATE</BMFIELD>
> 			<XSLTEMP>&lt;xsl:template 
> match=&quot;CLMREP/STATE&quot;&gt;&lt;xsl:value-of
> select=&quot;.&quot;/&gt;&lt;/xsl:template&gt;</XSLTEMP>
> 		</TABLEID>
> 		<TABLEID>
> 			<BMTABLE>CLMREP</BMTABLE>
> 			<BMDESC>ID</BMDESC>
> 			<BMFIELD>REPID</BMFIELD>
> 			<XSLTEMP>&lt;xsl:template 
> match=&quot;CLMREP/REPID&quot;&gt;&lt;xsl:value-of
> select=&quot;.&quot;/&gt;&lt;/xsl:template&gt;</XSLTEMP>
> 		</TABLEID>
> </BOOKMARKS>
> </DGS>
> 
> Desired Output format:
> <DGS>
>    <BOOKMARKS>
>         <TABLE tableid="tablename">
>             <FIELD fieldid="fieldname">
>                  <DESC>description</DESC>
>                  <XSLTEMP> </XSLTEMP>
>             </FIELD>
>         </TABLE>
>    </BOOKMARKS>
> </DGS>
> 
> And the following XSLT's:
> 
> (XSLTA)
> 
> <xsl:stylesheet version="1.0" 
> xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
> xmlns:lookup="urn:some.urn" exclude-result-prefixes="lookup">
> 	<xsl:output method="xml" version="1.0" encoding="UTF-8" 
> indent="yes"/>
> 	<lookup:table>
> 		<BMTABLE>CMSCASE</BMTABLE>
> 		<BMTABLE>CLAIMANT</BMTABLE>
> 		<BMTABLE>CLMREP</BMTABLE>
> 		<BMTABLE>CMSGROUP</BMTABLE>
> 		<BMTABLE>EMPLOYER</BMTABLE>
> 		<BMTABLE>EMPREP</BMTABLE>
> 		<BMTABLE>HEARING</BMTABLE>
> 		<BMTABLE>HEAROFFCR</BMTABLE>
> 		<BMTABLE>OTHERCPT</BMTABLE>
> 		<BMTABLE>SUBPOENA</BMTABLE>
> 	</lookup:table>
> 	<xsl:variable name="globalTableNames" 
> select="document('')/*/lookup:table/*"/>
> 
> 	<xsl:template match="DGS">
> 	<xsl:element name="DGS">
> 	    <xsl:apply-templates select="BOOKMARKS" />
>       </xsl:element>
>     	</xsl:template>
>     	
>     	<xsl:template match="BOOKMARKS">
>        <xsl:element name="BOOKMARKS">
>             <xsl:for-each select="$globalTableNames">
>                  <xsl:element name="TABLE">
> 			  <xsl:attribute 
> name="tableid"><xsl:value-of select="."/></xsl:attribute>
> 			  <xsl:variable 
> name="tablename"><xsl:value-of select="."/></xsl:variable>
>      	               <xsl:apply-templates 
> select="/DGS/BOOKMARKS/TABLEID[BMTABLE = $tablename]"/>
>      	          </xsl:element>
>      	     </xsl:for-each>
>       </xsl:element>
>     	</xsl:template>
>     	
>     	<xsl:template match="TABLEID">
>     	   <test/>
>     	       <xsl:element name="FIELD">
>     	              <xsl:attribute name="fieldid">
>     	                  <xsl:value-of select="BMFIELD"/>
>     	              </xsl:attribute>
>     	              <xsl:element name="DESC">
>     	                     <xsl:value-of select="BMDESC"/>
>     	               </xsl:element>
>     	               <xsl:element name="XSLTEMP">
>     	                   <xsl:value-of select="XSLTEMP"/>
>     	               </xsl:element>
>            </xsl:element>
>     	</xsl:template>
> </xsl:stylesheet>
> 
> (XSLTB)
> 
> <xsl:stylesheet version="1.0" 
> xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
> xmlns:lookup="urn:some.urn" exclude-result-prefixes="lookup">
> 	<xsl:output method="xml" version="1.0" encoding="UTF-8" 
> indent="yes"/>
> 	<lookup:table>
> 		<BMTABLE>CMSCASE</BMTABLE>
> 		<BMTABLE>CLAIMANT</BMTABLE>
> 		<BMTABLE>CLMREP</BMTABLE>
> 		<BMTABLE>CMSGROUP</BMTABLE>
> 		<BMTABLE>EMPLOYER</BMTABLE>
> 		<BMTABLE>EMPREP</BMTABLE>
> 		<BMTABLE>HEARING</BMTABLE>
> 		<BMTABLE>HEAROFFCR</BMTABLE>
> 		<BMTABLE>OTHERCPT</BMTABLE>
> 		<BMTABLE>SUBPOENA</BMTABLE>
> 	</lookup:table>
> 	<xsl:variable name="globalTableNames" 
> select="document('')/*/lookup:table/*"/>
> 	<xsl:template match="DGS">
> 		<xsl:element name="DGS">
> 			<xsl:apply-templates select="BOOKMARKS"/>
> 		</xsl:element>
> 	</xsl:template>
> 	<xsl:template match="BOOKMARKS">
> 		<xsl:element name="BOOKMARKS">
> 			<xsl:variable name="bookmarks" 
> select="TABLEID"/>
> 			<xsl:for-each select="$globalTableNames">
> 				<xsl:element name="TABLE">
> 					<xsl:attribute 
> name="tableid"><xsl:value-of select="."/></xsl:attribute>
> 					<xsl:variable name="tablename">
> 						<xsl:value-of 
> select="."/>
> 					</xsl:variable>
> 					<xsl:variable 
> name="tempNodeset" select="$bookmarks[BMTABLE = $tablename]"/>
> 					<xsl:apply-templates 
> select="$tempNodeset"/>
> 				</xsl:element>
> 			</xsl:for-each>
> 		</xsl:element>
> 	</xsl:template>
> 	
> 	<xsl:template match="TABLEID">
> 		<xsl:element name="FIELD">
> 			<xsl:attribute 
> name="fieldid"><xsl:value-of select="BMFIELD"/></xsl:attribute>
> 			<xsl:element name="DESC">
> 				<xsl:value-of select="BMDESC"/>
> 			</xsl:element>
> 			<xsl:element name="XSLTEMP">
> 				<xsl:value-of select="XSLTEMP"/>
> 			</xsl:element>
> 		</xsl:element>
> 	</xsl:template>
> </xsl:stylesheet>
> 
> 
> When run under XML Spy Enterprise 2004, XSLTA and XSLTB both 
> produce the same desired output.  However, when XSLTA is run 
> under LibXSLT, Sablotron, and MSXML (have not tested xalan or 
> saxon), the following output is produced:
> 
> <DGS>
>    <BOOKMARKS>
>       <TABLE tableid="tablename"/>
>       <TABLE tableid="tablename"/>
>    </BOOKMARKS>
> </DGS>
> 
> My question is, is XML Spy producing the correct output for 
> XSLTA or are the other three processors not implementing the 
> transformation correctly?
> 
> Dave
> 
> 
> =====
> "...there is nothing stranger than people." - Anonymous
> 
>  XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list
> 


 XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list


Current Thread