Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

XSLT formatting

Status
Not open for further replies.

GuardianOfTheFlame

Programmer
Sep 4, 2007
31
IT
Hi all!
I have an XML file representing the definition of a page (a list of items such as radio, check, paragraph and textbox with their properties) and an XSL Tranformation used to visualize the page as HTML.
The problem is the formatting of the output (HTML), full of tabs, spaces and carriage returns that makes the output difficult to read and, more important, makes some problems with default values of textbox (tabs at the beginning hide the values that aren't displayed in the box if you don't move the cursor).

A simple example:
I create a form with a single textbox and this is the XML file in input:
Code:
<xml>
	<layout name="my_layout" pages="1" w="600" h="800" format="A4" style="nubistyle_1.css">
		<page domid="container" name="container" orientation="portrait">
			<items>
				<item type="text" x="50" y="100" w="100" h="20" name="text_1" domid="text_1" tooltip="" group="" tabindex="" datatype="" minlen="" maxlen="" bordercolor="" bgcolor="" forecolor="" unique="0" required="0" disabled="0" multiline="0">
					<content>
						<![CDATA[Default value]]>
					</content>
				</item>
			</items>
		</page>
	</layout>
</xml>

This is the fragment of XSLT applied to textbox:
Code:
...
              <input type="text">
                <xsl:call-template name="input_attributes">
                  <xsl:with-param name="type">text</xsl:with-param>
                </xsl:call-template>
              </input>
...

 <!--Create the list of attributes for simple items-->
  <xsl:template name="input_attributes">
    <xsl:param name="type">text</xsl:param>
    <xsl:if test="$type='text'">
      <xsl:attribute name="value">
        <xsl:value-of select="." />
      </xsl:attribute>
    </xsl:if>
    <xsl:attribute name="name">
      <xsl:value-of select="@name" />
    </xsl:attribute>
    <xsl:attribute name="id">
      <xsl:value-of select="@domid" />
    </xsl:attribute>
    <xsl:attribute name="title">
      <xsl:value-of select="@tooltip" />
    </xsl:attribute>
    <xsl:attribute name="maxlength">
      <xsl:value-of select="@maxlen" />
    </xsl:attribute>
    <xsl:attribute name="tabindex">
      <xsl:value-of select="@tabindex" />
    </xsl:attribute>
    <xsl:if test="@disabled='1'">
      <xsl:attribute name="disabled"/>
    </xsl:if>
    <xsl:attribute name="style">
      position: absolute;
      top: <xsl:value-of select="@y" />px;
      left: <xsl:value-of select="@x" />px;
      width: <xsl:value-of select="@w" />px;
      height: <xsl:value-of select="@h" />px;
      <xsl:if test="@bgcolor!=''">background: <xsl:value-of select="@bgcolor" />;</xsl:if>
      <xsl:choose>
        <xsl:when test="@bordercolor=''">border: 1px solid black;</xsl:when>
        <xsl:otherwise>border: 1px solid <xsl:value-of select="@bordercolor" />;</xsl:otherwise>
      </xsl:choose>
      <xsl:choose>
        <xsl:when test="$type='text'">
          <xsl:if test="@forecolor!=''">
            color: <xsl:value-of select="@forecolor" />;
          </xsl:if>
        </xsl:when>
      </xsl:choose>
    </xsl:attribute>
  </xsl:template>

and this is the HTML in output:

Code:
<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><title>Actide - my_layout</title><link rel="stylesheet" type="text/css" media="screen" href="css/nubistyle_1.css"></head><body><form><input type="text" value="
					
						Default value
					
				" name="text_1" id="text_1" title="" maxlength="" tabindex="" style="
      position: absolute;
      top: 100px;
      left: 50px;
      width: 100px;
      height: 20px;
      border: 1px solid black;"></form></body></html>

I can't understand why the tabs are added in the value property of the textbox!
and how can I specify the indentation of the output?
Thanks,
Salo
P.S.: I hope that the question is clear... it's simple but difficult to explain :-/
 
You need to use <xsl:text> to surround your 'constant' text values in the attribute definition. Another way to combine constant text and varible data is concat(). For example:
Code:
    <xsl:attribute name="style">
      <xsl:text>position: absolute;<xsl:text>
      <xsl:value-of select="concat('top:',@y, 'px;'" />
      <xsl:value-of select="concat('left: ',@x, 'px;'" />
and so forth. See if the application of these techniques helps.


Tom Morrison
 
><xsl:attribute name="value">
<xsl:value-of select="." />
</xsl:attribute>

[tt]<xsl:attribute name="value">
<xsl:value-of select="[blue]normalize-space(.)[/blue]" />
</xsl:attribute>[/tt]
 
Thank you guys!
The <xsl:text> tag will be usefull in order to indent my output, but I finally understand what's the problem (regarding the tabs characters in the value attribute): the formatting of the XML in input (as you see in the following fragment).
Code:
<content>
						<![CDATA[  Default Value  ]]>
					</content>

How can I tell the XSLT to consider only the text between <![CDATA[]]> ignoring the previous and following tabs?

the fragment of XSLT that makes the transformation is the following:
Code:
    <xsl:if test="$type='text'">
      <xsl:attribute name="value"><xsl:value-of select="./content" /></xsl:attribute>
    </xsl:if>

I cannot use normalize-space() cause I don't want to normalize the spaces in CDATA.

Thanks again!
Salo
 
[1]
>I cannot use normalize-space() cause I don't want to normalize the spaces in CDATA.

<content>
<![CDATA[ Default Value ]]>
</content>

How can I tell the XSLT to consider only the text between <![CDATA[]]> ignoring the previous and following tabs?

I am not sure that you understand and think according to the design of xml. The location where you start <![CDATA[ and end ]]> is absolutely immaterial to the xml parsing engine. The content is from the point of view of xml document infoset, the same as the following.
[tt]
<content><![CDATA[
Default Value
]]></content>
[/tt]
if I make sure the number of whitespace inside the content angle bracket be the same - it may not be from what show above because I simply cut-and-paste without adjusting. This is the point major.

[2] What effectively you are asking is to leave 2 blankspace in front and 2 after the "Default Value". That information must be stored not like that in [1] but through some other means, such as an attribute to the content tag. For instance, like this.
[tt]<content leadtrailspace="2">[/tt]

[3] In any case, you have to use normalize-space() (and in particular, and the more so, you want to set the value attribute of html input element) as I show. Only this time you must add that 2-space info adhoc.
[tt]
<xsl:attribute name="value">
<xsl:value-of select="concat(' ',normalize-space(.),' ')" />
</xsl:attribute>
[/tt]
I won't bother any more of your time and it takes mine enough.
 
sorry for the stupid question about CDATA, I start to work with XML and XSLT few weeks ago... I was confused by the wrong indentation added in the javascript that create the XML and I don't notice the evident error: the CDATA is not an element tag so we mustn't add the tab to indent it! :-/ d'oh!
Now that we have correct the javascript it's ok! Thanks to all
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top