Search code examples
xmlxsltcommentssaxon

xslt ignore comments when testing position


How do I write XSLT so that the processor ignores comments when calculating the position of other elements?

I expect that the XSLT processor will filter out comments before applying the other template rules, but with a comment after the last list item, the test not(position()=last()) fails. How can I remove the comments before that test?

XML input:

<?xml version="1.0" encoding="utf-8"?>                                                                                                                                       
<html xmlns="http://www.w3.org/1999/xhtml">                                                                                                                                  
  <ul>                                                                                                                                                                       
    <li>fish1</li>                                                                                                                                                           
    <li>fish2</li>                                                                                                                                                           
    <li>fish3</li>                                                                                                                                                           
    <li>fish4</li>                                                                                                                                                           
    <!--                                                                                                                                                                     
      <li>fish5</li>                                                                                                                                                         
    -->                                                                                                                                                                      
  </ul>                                                                                                                                                                      
</html>

XSLT:

<?xml version="1.0" encoding="utf-8"?>                                                                                                                                       
<xsl:stylesheet                                                                                                                                                              
  version="2.0"                                                                                                                                                              
  xmlns:xhtml="http://www.w3.org/1999/xhtml"                                                                                                                                 
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform">                                                                                                                          
                                                                                                                                                                             
  <xsl:output method="text" encoding="utf-8" indent="no" />                                                                                                                  
                                                                                                                                                                             
  <xsl:strip-space elements="*" />                                                                                                                                           
                                                                                                                                                                             
  <xsl:template match="comment()" />                                                                                                                                         
                                                                                 
  <xsl:template match="/">                                                                                                                                                   
    <xsl:apply-templates />                                                                                                                                                  
  </xsl:template>
                                                                                                                                                                                                                                                                                                                                        
  <xsl:template match="xhtml:ul">                                                                                                                                            
    <xsl:apply-templates />                                                                                                                                                  
  </xsl:template>                                                                                                                                                            
                                                                                                                                                                             
  <xsl:template match="xhtml:li">                                                                                                                                            
    <xsl:apply-templates />                                                                                                                                                  
    <xsl:if test="not(position()=last())">                                                                                                                                   
      <xsl:text>, </xsl:text>                                                                                                                                                
    </xsl:if>                                                                                                                                                                
  </xsl:template>                                                                                                                                                            
                                                                                                                                                                             
</xsl:stylesheet>                        

Output with SaxonJ-HE 12.1:

fish1, fish2, fish3, fish4, 

Solution

  • You could replace test="not(position()=last())" with test="following-sibling::*".