Re: [xsl] Saxon & xsltproc giving different output

Subject: Re: [xsl] Saxon & xsltproc giving different output
From: Russell Urquhart <russurquhart1@xxxxxxxxxxx>
Date: Sat, 17 Dec 2011 15:36:11 -0600
Thanks for your reply Michael.

On Sat, Dec 17, 2011 at 07:05:46PM +0000, Michael Kay wrote:
>
> There are two ways people can help you with this. Either they can check  
> the code by visual inspection and hope to find the errors that way, or  
> they can run it and debug it. You've provided far too much code for the  
> first approach to be practical, and not enough for the second.

I suspected that I might have done that. The entire xslt is very large and does a lot, and the rest works quite well. I also wasn't trying to get someone to debug the whole thing.

>
> You're also doing your best to confuse the reader by starting with an  
> anecdote about a different problem from the one you are asking for help  
> with.

Sorry again. Just trying to provide info, to capture the context of the problem as i encountered it.

>
> There are legitimate reasons, incidentally, why two XSLT processors can  
> produce different results on the same input. This is especially true if  
> one of them is an XSLT 2.0 processor and the other is an XSLT 1.0  
> processor, 


This is what i thought. As i am using Saxon 9, and xsltproc, as i understand it, is 1.0 only? 



> but it can also happen with two conformant XSLT 1.0  
> processors, because some aspects of behaviour (such as collating  
> sequences) are explicitly implementation-defined.

Thinking this was a 1.0 issue, i downloaded Saxon 6.5.5, the last 1.0 processor Saxon made, and tried it, but got identical results as i was getting from Saxon 9. 

Let me try and recast my request.

As the variable is defined:

<xsl:variable name="is_module_in_device">
          <xsl:for-each select="//errata_section/devices_impacted[device_name=$device_to_output]">
	    <xsl:choose>
	    	<!-- Start Patch part 1(removing modules having and arch attribute containing a different than the current device) -->
	    	<xsl:when test='../module_impacted[@arch!=$device_to_output]'>
	    	   <xsl:if test='../module_impacted/text()[.=$current_module]'>
		   	<xsl:text></xsl:text>
		   </xsl:if>
	    	</xsl:when>
		<!-- End Patch part 1 -->
	    	<xsl:otherwise>
		   <xsl:if test='../module_impacted/text()[.=$current_module]'><xsl:text>o</xsl:text></xsl:if>
	    	</xsl:otherwise>
	    </xsl:choose>
          </xsl:for-each>
        </xsl:variable>

And the table is generated because:

<xsl:if test='contains($is_module_in_device, "o")'>
          <xsl:variable name="num_of_sections">
	    <!-- Start Patch part 3 -->
            <xsl:value-of select="string-length($is_module_in_device) + string-length($removed_modules)"/>
	    <!-- End Patch part 3 -->
          </xsl:variable>
        
          <table>


How could is_module_in_device have different values for xslt processors?

Thanks,

Russ

>
>
>
> On 17/12/2011 17:05, Russell Urquhart wrote:
>>
>> Hi,
>>
>> I have to support a legacy xslt that transforms an xml flle, organizes it, and then outputs a docbook style xml file.
>>
>> When i took over this, i was running Saxon on the xslt, without incident. Recently i noticted that some elements were not being caught and output. I determined that the previous users had been using xsltproc, so i used that and the output i was getting was in sync with what they had had.
>>
>> I know that Saxon is the standard, but i didn't have the time or knowledge to discern the differecnes in the xslt.
>>
>> I am now experiencing a related problem, where stange values are being generated by the xslt, while Saxon does not output any of these specific elements.
>>
>> The input data, is of the following:
>>
>> errata_section id="i707" errata_type="caution">
>>        <title>Adaptive Body Bias Strategy</title>
>>     <devices_impacted>
>>          <device_name>xxxx2345</device_name>
>>          <device_es>1.0</device_es>
>>          <device_es>1.1</device_es>
>> 	</devices_impacted>
>> <devices_impacted>
>>          <device_name>xxxx2346</device_name>
>>          <device_es>1.0</device_es>
>>        </devices_impacted>
>>
>>        <module_impacted>PRCM</module_impacted>
>>      </errata_section>
>>
>> The code is called to generate a table of modules impacted, for a given device impacted.
>>
>> It's called like this:
>>
>>        <xsl:call-template name="authoring">
>>            <xsl:with-param name="device_to_output">xxxx2345</xsl:with-param>
>>        </xsl:call-template>
>>
>> A key is created:
>>
>> xsl:key name="module-index" match="errata_section" use="module_impacted"/>
>>
>>
>> The code in question i think is the following, with original comments in tact (Sorry if there is unnecessary code here):
>>
>> xsl:template name="table_of_section_per_module">
>>       <xsl:param name="device_to_output"/>
>>
>>       <xsl:element name="article">
>>       <xsl:attribute name="id">errata_module_impacted</xsl:attribute>
>>       <xsl:attribute name="arch"><xsl:value-of select='$device_to_output'/></xsl:attribute>
>>       <title>Modules Impacted</title>
>> <!--     This para element is being deleted here because it causes an error. Para elements cannot contain stuff.-->
>> <!--<para>-->
>>       <!-- A little complicated but seems to work fine ! -->
>>       <xsl:for-each select="//errata_section[generate-id(.)=generate-id(key('module-index', module_impacted)[1])]">
>>          <xsl:sort select="module_impacted"/>
>>          <xsl:variable name="current_module"><xsl:value-of select="module_impacted"/></xsl:variable>
>>          <!-- The is an ugly kludge: we check each section that applies to current chip and update the "is_module_in_device"
>>              variable if we find it impacts the current module. In the end we have either an empty variable (module is not in
>>              current device) or a variable containing lots of "o" concatenated (module is in current device) -->
>>
>>          <xsl:variable name="is_module_in_device">
>>            <xsl:for-each select="//errata_section/devices_impacted[device_name=$device_to_output]">
>> 	<xsl:choose>
>> 	    	<!-- Start Patch part 1(removing modules having and arch attribute containing a different than the current device) -->
>> 	    	<xsl:when test='../module_impacted[@arch!=$device_to_output]'>
>> 	    	<xsl:if test='../module_impacted/text()[.=$current_module]'>
>> 		   	<xsl:text></xsl:text>
>> 		</xsl:if>
>> 	    	</xsl:when>
>> 		<!-- End Patch part 1 -->
>> 	    	<xsl:otherwise>
>> 		<xsl:if test='../module_impacted/text()[.=$current_module]'><xsl:text>o</xsl:text></xsl:if>
>> 	    	</xsl:otherwise>
>> 	</xsl:choose>
>>            </xsl:for-each>
>>          </xsl:variable>
>> 	
>> 	<!-- Start Patch part 2 -->
>> 	<xsl:variable name="removed_modules">
>>            <xsl:for-each select="//errata_section/devices_impacted[device_name=$device_to_output]">
>> 	<xsl:choose>
>> 	    	<xsl:when test='../module_impacted[@arch!=$device_to_output]'>
>> 	    	<xsl:if test='../module_impacted/text()[.=$current_module]'>
>> 		   	<xsl:text>r</xsl:text>
>> 		</xsl:if>
>> 	    	</xsl:when>
>> 	</xsl:choose>
>>            </xsl:for-each>
>>          </xsl:variable>
>> 	<!-- End Patch part 2 -->
>> 	
>>          <xsl:if test='contains($is_module_in_device, "o")'>
>>            <xsl:variable name="num_of_sections">
>> 	<!-- Start Patch part 3 -->
>>              <xsl:value-of select="string-length($is_module_in_device) + string-length($removed_modules)"/>
>> 	<!-- End Patch part 3 -->
>>            </xsl:variable>
>>
>>            <table>
>>             <xsl:attribute name="id">
>>             <xsl:value-of select="generate-id(module_impacted)"/>
>>             </xsl:attribute>
>>              <title>
>>              <xsl:text>Module</xsl:text>
>>              <xsl:value-of select="module_impacted"/>
>>              <xsl:text>  (</xsl:text><xsl:value-of select="$num_of_sections"/><xsl:text>  section</xsl:text>
>>              <!-- a little grammar ! -->
>>              <xsl:if test="$num_of_sections&gt;1"><xsl:text>s</xsl:text></xsl:if><xsl:text>)</xsl:text>
>>              </title>
>>              <xsl:element name="tgroup">
>>              <xsl:attribute name="cols">
>>              <xsl:choose>
>>                <xsl:when test='$show_review="yes"'>3</xsl:when>
>>                <xsl:otherwise>2</xsl:otherwise>
>>              </xsl:choose>
>>              </xsl:attribute>
>>              <xsl:element name="colspec">
>>                <xsl:attribute name="colwidth">1*</xsl:attribute>
>>                <xsl:attribute name="colname">_1</xsl:attribute>
>>              </xsl:element>
>>              <xsl:choose>
>>                  <xsl:when test='$show_review="yes"'>
>>                     <xsl:element name="colspec">
>>                        <xsl:attribute name="colwidth">6*</xsl:attribute>
>>                        <xsl:attribute name="colname">_2</xsl:attribute>
>>                     </xsl:element>
>>                     <xsl:element name="colspec">
>>                        <xsl:attribute name="colwidth">1*</xsl:attribute>
>>                        <xsl:attribute name="colname">_3</xsl:attribute>
>>                     </xsl:element>
>>                  </xsl:when>
>>                  <xsl:otherwise>
>>                     <xsl:element name="colspec">
>>                        <xsl:attribute name="colwidth">8*</xsl:attribute>
>>                        <xsl:attribute name="colname">_2</xsl:attribute>
>>                     </xsl:element>
>>                  </xsl:otherwise>
>>              </xsl:choose>
>>              <tbody>
>>              <row>
>>              <xsl:element name="entry">
>>              <xsl:attribute name="morerows"><xsl:value-of select="$num_of_sections"/></xsl:attribute>
>>              <xsl:value-of select="module_impacted"/>
>>              </xsl:element>
>>              <entry>Section</entry>
>>              <xsl:if test='$show_review="yes"'>
>>              <entry>Review status</entry>
>>              </xsl:if>
>>              </row>
>>                <xsl:for-each select="key('module-index', module_impacted)">
>>                  <xsl:if test="devices_impacted/device_name/text()[.=$device_to_output]">
>>                    <row>
>>                    <entry>
>> 		<xsl:value-of select="@id" /><xsl:text>:</xsl:text>
>>                    <xsl:element name="xref">
>>                    <xsl:attribute name="linkend">sect_<xsl:value-of select="@id" />
>>                    </xsl:attribute></xsl:element>
>>                    </entry>
>>                    <xsl:if test='$show_review="yes"'>
>>                    <entry>
>>                    <xsl:value-of select="review_status" />
>>                    </entry>
>>                    </xsl:if>
>>                     </row>
>>
>>
>> My issue is, Saxon doesn't find ALL the modules impacted for a given device. Xsltproc, in the past has found all moduls impacted for a given device, but, recently, has incorrectly found unrelated modules impacted, for a given device.
>>
>> I suspect, by their own admission, that the code at this point is kludgey, and they are taking advantage of some aspect of how xsltproc handles xslt 1.0 style code?
>>
>> Please any help on this would be great. I want to only have to use Saxon to do this transform!
>>
>> Thanks again,
>>
>> Russ

Current Thread