Hi,
Need Urgent help..!!!
I have a xsl to display all the xml elements in a html page.
It works fine but i m not able to generate a proper indentation or format.
Even a new line character doesnt work.
I have pasted below the xsl ,Please help me out with this.

<?xml version="1.0"?><!--showtree.xsl-->
<!DOCTYPE xsl:stylesheet [
<!ENTITY nl "&#xa;"><!--new line sequence-->



<!--remove the following empty declaration if namespaces are to be reported-->
<!ENTITY namespace-reporting ''>

<!--the following declaration will only be used if not previously defined-->
<!ENTITY namespace-reporting '
      <xsl:for-each select="namespace::*">
        <xsl:call-template name="namespace">
          <xsl:with-param name="ancestry" select="$this-ancestry"/>
          <xsl:with-param name="node-pos" select="$this-node-pos"/>
        </xsl:call-template>
      </xsl:for-each>
'>
]>
<xsl:stylesheet version="1.0"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns="http://www.w3.org/1999/xhtml">

<xsl:output method="xml"
            indent="yes"/>
             <!--set the following non-empty to reveal element's node values-->
<xsl:param name="show-element-values"/>

<!--========================================================================-->
<!--nodes with children-->
<xsl:template match="/">
    <HTML>
      <HEAD>
     </HEAD>
      <BODY>
        <H1>FIST Scenario Report</H1>
        <UL>
          <xsl:apply-templates select="node()"/>
        </UL>
      </BODY>
    </HTML>
  </xsl:template>  

<xsl:template match="*">                                      <!--an element-->
  <xsl:param name="ancestry"/>
<xsl:param name="node-pos"/>
  <xsl:variable name="this-ancestry">
    <xsl:if test="$ancestry!=''">
      <xsl:value-of select="$ancestry"/><xsl:text>,</xsl:text>,<BR/>
    </xsl:if>
    <xsl:value-of select="name(.)"/>
  </xsl:variable>

  <xsl:variable name="this-node-pos">
    <xsl:if test="$node-pos!=''">
      <xsl:value-of select="$node-pos"/><xsl:text>.</xsl:text>
    </xsl:if>
    <p><xsl:value-of select="position()"/></p>
  </xsl:variable>
  <xsl:call-template name="node">
    <xsl:with-param name="ancestry" select="$ancestry"/>
    <xsl:with-param name="node-pos" select="$this-node-pos"/>
    <xsl:with-param name="type">Element</xsl:with-param>
    <xsl:with-param name="contents">                          <!--node value-->
      <xsl:choose>
        <xsl:when test="not($show-element-values)"/>
        <xsl:when test="node()">
          <xsl:text>{</xsl:text>
          <p><xsl:value-of select="."/></p>
          <xsl:text>}</xsl:text>,<BR/>
    <xsl:text>
    </xsl:text>
        </xsl:when>
        <xsl:otherwise>no child nodes</xsl:otherwise>
      </xsl:choose>
    <xsl:text> </xsl:text>
      &namespace-reporting;           <!--defined in a general entity in DTD-->
      <xsl:for-each select="@*">
        <xsl:call-template name="attribute">
          <xsl:with-param name="ancestry" select="$this-ancestry"/>
          <xsl:with-param name="node-pos" select="$this-node-pos"/>
        </xsl:call-template>
      </xsl:for-each>
      <xsl:choose>                                         <!--node children-->
        <xsl:when test="node()">
          <xsl:apply-templates select="node()">
            <xsl:with-param name="ancestry" select="$this-ancestry"/>
            <xsl:with-param name="node-pos" select="$this-node-pos"/>
          </xsl:apply-templates>
        </xsl:when>
        <xsl:when test="$show-element-values"/>    <!--content already shown-->
      </xsl:choose>
    </xsl:with-param>
  </xsl:call-template>
</xsl:template>

<!--========================================================================-->
<!--for every leaf node, show the value in report-->

<!--child leaf nodes-->

<xsl:template match="comment()">                               <!--a comment-->
  <xsl:param name="ancestry"/>
  <xsl:param name="node-pos"/>
  <xsl:variable name="this-node-pos">
    <xsl:if test="$node-pos!=''">
      <xsl:value-of select="$node-pos"/><xsl:text>.</xsl:text>
    </xsl:if>
    <xsl:value-of select="position()"/>
  </xsl:variable>
  <xsl:call-template name="node">
    <xsl:with-param name="ancestry" select="$ancestry"/>
    <xsl:with-param name="node-pos" select="$this-node-pos"/>
    <xsl:with-param name="type">Comment</xsl:with-param>
    <xsl:with-param name="contents">
      <p><xsl:text>{</xsl:text><xsl:value-of select="."/><xsl:text>}</xsl:text></p>,<BR/>
<xsl:text>
</xsl:text>
    </xsl:with-param>
  </xsl:call-template>
</xsl:template>

<xsl:template match="processing-instruction()">       <!--a processing inst.-->
  <xsl:param name="ancestry"/>
  <xsl:param name="node-pos"/>
  <xsl:variable name="this-node-pos">
    <xsl:if test="$node-pos!=''">
      <xsl:value-of select="$node-pos"/><xsl:text>.</xsl:text>
    </xsl:if>
    <xsl:value-of select="position()"/>
  </xsl:variable>
  <xsl:call-template name="node">
    <xsl:with-param name="ancestry" select="$ancestry"/>
    <xsl:with-param name="node-pos" select="$this-node-pos"/>
    <xsl:with-param name="type">Proc. Inst.</xsl:with-param>
    <xsl:with-param name="contents">
      <xsl:text>{</xsl:text><xsl:value-of select="."/><xsl:text>}</xsl:text>,<BR/>
    </xsl:with-param>
  </xsl:call-template>
</xsl:template>

<xsl:template match="text()">                                <!--a text node-->
  <xsl:param name="ancestry"/>
  <xsl:param name="node-pos"/>
  <xsl:variable name="this-node-pos">
    <xsl:value-of select="$node-pos"/><xsl:text>.</xsl:text>
    <xsl:value-of select="position()"/>
  </xsl:variable>
  <xsl:call-template name="node">
    <xsl:with-param name="ancestry" select="$ancestry"/>
    <xsl:with-param name="node-pos" select="$this-node-pos"/>
    <xsl:with-param name="type">Text</xsl:with-param>
    <xsl:with-param name="contents">
          <xsl:text>{</xsl:text><xsl:value-of select="."/><xsl:text>}</xsl:text>,<BR/>
<xsl:text>
</xsl:text>
    </xsl:with-param>
  </xsl:call-template>
</xsl:template>

<!--attached leaf nodes-->

<xsl:template name="attribute">  
  <xsl:param name="node-pos"/>
                           <!--an attribute-->
  <xsl:variable name="ancestry"/><!--change to xsl:param to include ancestry-->
  <xsl:variable name="this-node-pos">
    <xsl:value-of select="$node-pos"/><xsl:text>.</xsl:text>
    <xsl:number value="position()" format="A"/>
  </xsl:variable>
  <xsl:call-template name="node">
    <xsl:with-param name="ancestry" select="$ancestry"/>
    <xsl:with-param name="node-pos" select="$this-node-pos"/>
    <xsl:with-param name="type">Attribute </xsl:with-param>
    <xsl:with-param name="contents">
<xsl:text>&nl;</xsl:text>
      <xsl:text>{</xsl:text><xsl:value-of select="."/><xsl:text>}</xsl:text>,<BR/>
    </xsl:with-param>
  </xsl:call-template>
</xsl:template>

<xsl:template name="namespace">                        <!--a namespace node-->
 <xsl:param name="node-pos"/>
  <xsl:variable name="ancestry"/><!--change to xsl:param to include ancestry-->

  <xsl:variable name="this-node-pos">
    <xsl:value-of select="$node-pos"/><xsl:text>.</xsl:text>
    <xsl:number value="position()" format="I"/>
  </xsl:variable>
  <xsl:call-template name="node">
    <xsl:with-param name="ancestry" select="$ancestry"/>
    <xsl:with-param name="node-pos" select="$this-node-pos"/>
    <xsl:with-param name="type">Namespace</xsl:with-param>
    <xsl:with-param name="contents">
      <xsl:text>{</xsl:text><xsl:value-of select="."/><xsl:text>}</xsl:text>,<BR/>
    </xsl:with-param>
  </xsl:call-template>
</xsl:template>

<!--========================================================================-->
<!--display the content of a node-->

<xsl:template name="node">
  <xsl:param name="ancestry"/>
  <xsl:param name="node-pos"/>
  <xsl:param name="type"/>
  <xsl:param name="contents"/>
  <xsl:text>&nl;</xsl:text>
  <xsl:value-of select="$node-pos"/>                     <!--report location-->
  <xsl:text>  </xsl:text>
    <xsl:text>&nl;</xsl:text>
  <xsl:value-of select="$type"/>                               <!--node type-->
  <xsl:if test="not(name(.)='')">                   <!--node name (if appl.)-->
    <xsl:text> '</xsl:text>
    <xsl:if test="namespace-uri(.)!=''">  
                <!--with namespace-->
<span style="color:#00ff00">
      <xsl:text>  {</xsl:text>
      <xsl:value-of select="namespace-uri(.)"/>
      <xsl:text>}  </xsl:text>,<BR/>
</span>

    </xsl:if>
    <xsl:value-of select="name(.)"/>
    <xsl:text>'</xsl:text>
  </xsl:if>                                                            <!--node context-->
  <xsl:if test="$ancestry"> (<xsl:value-of select="$ancestry"/>)</xsl:if>
  <xsl:text> ==== </xsl:text>
<xsl:text>   </xsl:text>

  <xsl:value-of select="$contents"/>
</xsl:template>

</xsl:stylesheet>

Dani AI

Generated

Brief expert note.

Browsers collapse plain whitespace and ignore raw newline characters when rendering HTML, so emitting newlines from XSLT won’t produce visible indentation unless the output is placed into a whitespace‑preserving context. ' suggestion to render the tree inside a preformatted container is the simplest fix; alternatively, a CSS rule that preserves line breaks can be used when wrapping in <pre> is not desirable.

A few practical points not shown in the original thread:

  • xsl:output indent="yes" affects how the XSLT serializer formats the XML source it writes — it helps when inspecting the generated source but does not force visible indentation in a browser.
  • If the stylesheet declares the XHTML namespace (default xmlns="http://www.w3.org/1999/xhtml") while using method="xml", the result is namespaced XHTML; how the browser parses that result depends on the MIME type it is served with (application/xhtml+xml vs text/html), which can affect rendering.
  • Emitting real line breaks from XSLT is most portable using an explicit newline character inside xsl:text, rather than relying on external DTD entities or disable-output-escaping.

Example CSS option (preserves newlines and wraps long lines):

.tree { white-space: pre-wrap; font-family: monospace; }

Quick debugging checklist: inspect the transformed output with View Source to confirm whether <br/> elements or newline characters are actually present; if present but not visible, check CSS rules and container elements; if absent, adjust the XSLT to emit element breaks or newline characters. ’ approach (preformatted output) was confirmed to resolve the original poster’s issue by .

Recommended Answers

All 6 Replies

You output html, so using spaces won't have the desired effect, unless you use the <pre> tag. For newlines, you need to add <br/> tags.

Hi..thanks for the reply..I tried adding <br/> tags even then there was no change in the output.

What happens if you try another tag, like <hr/> ? Do you see that one in the output ? Perhaps the problem lies elsewhere.

I tried even <hr/>. But too no changes in the output

It has to change, perhaps the file is cached ?

Thanks a lot pritaeas.. I had forgotten the <pre> tag. Now i m able to generate desired format.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.