Shubham Khare
Shubham Khare

Reputation: 113

Cannot get the proper from XSLT for given XML file

I am new to XSLT and first time working on it. I have one XML like below `

<?xml version="1.0" encoding="UTF-8"?>
<configuration_file>
    <source_file>
        <include>
            <global_header header_name="ABCD.H">
                <statement_comment>
                    <text> SIMPLE COMMENT</text>
                </statement_comment>
            </global_header>
            <local_header header_name="EF.H"/>
        </include>
        <const_declarations>
            <declaration_group>
                <declaration name="SimpleVariable">
                    <type>
                        <type_name>INT</type_name>
                    </type>
                    <initializer>
                        <native_initializer>
                            <statement_comment>
                                <text>COMMENT FOR VARIABLE</text>
                            </statement_comment>
                            <code>2</code>
                        </native_initializer>
                    </initializer>
                </declaration>
            </declaration_group>
        </const_declarations>
        <define>
            <macro_definition macro_name="DEFINEVARIABLE" definition="0"/>
        </define>
    </source_file>
</configuration_file>`

I tried below XSLT -

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" 
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
                xmlns:fo="http://www.w3.org/1999/XSL/Format" >
<xsl:output method="text"/>

<xsl:template match="/">   
    <xsl:apply-templates select="/configuration_file/source_file" mode="configuration_file_formatter"/>
</xsl:template>

    <xsl:template match="include" mode="configuration_file_formatter">
        <xsl:for-each select="*">
         <xsl:apply-templates select="." mode="configuration_file_formatter.statement_formatter">
         <xsl:with-param name="statement">
                    <xsl:text>#include </xsl:text>
                    <xsl:choose>
                        <xsl:when test="self::global_header">
                            <xsl:text>&lt;</xsl:text>
                            <xsl:value-of select="@header_name"/>
                            <xsl:text>&gt;</xsl:text>
                            <xsl:text>&#xa;</xsl:text>
                        </xsl:when>
                        <xsl:otherwise>
                            <xsl:text>"</xsl:text>
                            <xsl:value-of select="@header_name"/>
                            <xsl:text>"</xsl:text>
                            <xsl:text>&#xa;</xsl:text>
                        </xsl:otherwise>
                    </xsl:choose>
                     </xsl:with-param>
               </xsl:apply-templates>
        </xsl:for-each>
    </xsl:template>

<xsl:template match="include/global_header|
                     include/local_header"
              mode="configuration_file_formatter.statement_formatter">
    <xsl:param name="statement"/>
    <xsl:param name="line_prefix_three_char">/* </xsl:param>
    <xsl:param name="line_suffix_three_char"> */</xsl:param>
    <xsl:if test="not(statement_comment)">
        <xsl:value-of select="$statement"/>
      <xsl:text>&#xa;</xsl:text>
    </xsl:if>
    <xsl:variable name="white_spaces">
        <xsl:text>                                        </xsl:text>
    </xsl:variable>
    <xsl:for-each select="statement_comment/text">
        <xsl:variable name="line_first_segment">
            <xsl:choose>
                <xsl:when test="position()=1">
                    <xsl:choose>
                        <xsl:when test="string-length($statement) &gt; 40">
                            <xsl:value-of select="$statement"/>
                            <xsl:value-of select="$white_spaces"/>
                        </xsl:when>
                        <xsl:otherwise>
                            <xsl:value-of select="substring(concat($statement, $white_spaces), 1, 40)"/>
                        </xsl:otherwise>
                    </xsl:choose>
                </xsl:when>
                <xsl:otherwise>
                    <xsl:value-of select="$white_spaces"/>
                </xsl:otherwise>
            </xsl:choose>
        </xsl:variable>
        <xsl:value-of select="$line_first_segment"/>
        <xsl:value-of select="$line_prefix_three_char"/>
        <xsl:value-of select="substring(concat(., $white_spaces), 1, 32)"/>
        <xsl:value-of select="$line_suffix_three_char"/>
        <xsl:text>&#xa;</xsl:text>
    </xsl:for-each>
</xsl:template> 
</xsl:stylesheet>

I am getting output like -

        #include <ABCD.H>
                      /*  SIMPLE COMMENT                  */
#include "EF.H"


        
            
                
                    
                        INT
                    
                    
                        
                            
                                COMMENT FOR VARIABLE
                            
                            2
                        

With so many extra spaces

while I am expecting output-

#include <ABCD.H> /* SIMPLE COMMENT */
#include "EF.H"

INT SimpleVariable=2; // COMMENT FOR VARIABLE
#define DEFINEVARIABLE 0    
    

Tried to change XSLT so many times but kinda stuck here.. What am I doing wrong? And please provide any tutorials/notes available for XSLT if available.

Upvotes: 1

Views: 54

Answers (1)

Michael Kay
Michael Kay

Reputation: 163262

With this kind of XML it's usually best to add

<xsl:strip-space elements="*"/>

to the stylesheet, to get rid of all the unwanted whitespace in the input XML. Otherwise, the default action is to copy the whitespace to the output.

There are masses of resources available for learning XSLT. Remember that printed books are of much more reliable quality than online tutorials.

Upvotes: 1

Related Questions