Page 1 of 1

Passing formatted data into an attribute

Posted: Fri Apr 21, 2006 12:43 am
by nam
I am fairly new to XSLT, so this may be simpler than I think.

I need to pass some formatted data into a function to display as a popup when the user hovers over a link element. I have a vendor, price and date that I want formatted as “from x for $9.99 on m/d/yyyy”.

I have templates set up to handle the formatting (price is ignored if the purchase price is not a positive number, for instance) but I cannot figure out how to get it passed to the function, because no matter what I do I eventually have to use an XSLT transform to get the data into the link. I am using it earlier in the document for raw (unformatted) data. This is the code that works:

<xsl:variable name="width" select="string-length(concat('ID:', '@ID'))" />
<a onMouseout="hideddrivetip()">
<xsl:attribute name="onMouseover">
<xsl:value-of select='concat("ddrivetip(", @ID , ", ", $width , ")")' />
</xsl:attribute>
<xsl:value-of select="Subject/Manufacturer" /><![CDATA[ ]]>
<xsl:value-of select="Subject/Name" />
</a>

That works because the @ID variable is simple and doesn't require formatting. To do the other tip, I need to create a variable to store the templates formatted data (datext) and use it to pass the data to the attribute creation.

<xsl:variable name="datext" select='concat("../../Purchase/Vendor", apply-templates("../../Purchase/Price"), apply-templates("../../Purchase/Date")' />

<xsl:variable name="width2" select="string-length($datext)" />

<a onMouseout="hideddrivetip()">
<xsl:attribute name="onMouseover">
<xsl:value-of select='concat("ddrivetip(", $datext , ", ", $width2 , ")")' />
</xsl:attribute>

<xsl:value-of select="../../Brand" /><![CDATA[ ]]>
<xsl:value-of select="../../Type" /><![CDATA[ ]]>
<xsl:value-of select="../../Note" />
</a>

Obviously, the first line doesn't work – I know that. But that's essentially what I need to do before passing the resulting data into the “onMouseover” command.

I cannot for the life of me figure out any way of doing this. I can't get the formatted text into the datext storage variable. Is it even possible?

I'm hoping it is and that someone can help. Thanks in advance.

Posted: Fri Apr 21, 2006 10:12 am
by george
Hi,
<xsl:variable name="datext" select='concat("../../Purchase/Vendor", apply-templates("../../Purchase/Price"), apply-templates("../../Purchase/Date")' />
There is not apply-templates funtion in XSLT, there is an instruction called apply templates. Probably what you want is:

<xsl:variable name="datext">
<xsl:value-of select="../../Purchase/Vendor"/>
<xsl:apply-templates select="../../Purchase/Price"/>
<xsl:apply-templates select="../../Purchase/Date"/>
</xsl:variable>

You can use the XSLT debugger from oXygen to check the values of the variables to make sure they have the expected values.

Best Regards,
George

Posted: Fri Apr 28, 2006 10:31 pm
by nam
George,

Thanks for the reply. Although not a direct answer, it put me on the right track and I'm getting what I want.

I have a different problem now. I am getting extra line breaks right in the middle of the formatted text. They are interfering with the function call. I don't know where they are coming from. The HTML that is being output looks like this:

onMouseover="ddrivetip('American Eagles&nbsp;&#xA;for $5&nbsp;', 36)"

I am using the following code:

<a onMouseout="hideddrivetip()">
<xsl:attribute name="onMouseover">
<xsl:text disable-output-escaping="yes">ddrivetip('</xsl:text>
<xsl:value-of select='$datext' />
<xsl:text disable-output-escaping="yes">', </xsl:text>
<xsl:value-of select='$width2' />
<xsl:text disable-output-escaping="yes">)</xsl:text>
</xsl:attribute>
</a><br />

to create the text using these templates:

<!-- Template to format out the purchase/sale price -->
<xsl:template match="Purchase/Price">
<xsl:if test=". > 0">
for $<xsl:value-of select="." />
</xsl:if>
</xsl:template>

<!-- Template to format out the purchase/sale date -->
<xsl:template match="Purchase/Date">
<xsl:if test=". != ''">
on <xsl:value-of select="." />
</xsl:if>
</xsl:template>

This is a sample of the original XML:
<Accessory ID="14270616" Scale="1/72">
<Note>B-29/B-50 Wheel Set. Contains all 6 wheels & tires.</Note>
<Type>Resin</Type>
<Brand>True Details</Brand>
<Purchase>
<Price>5</Price>
<Date/>
<Vendor>American Eagles</Vendor>
</Purchase>
<Links>
<Kit ID="7"/>
</Links>
</Accessory>

I don't see where the line feeds, non-breaking spaces and ampersands are being created.

Can you (or anybody else) help?

Thanks.

Posted: Tue May 02, 2006 10:56 am
by sorin_ristache
Hello,

Run the transformation in the Debugger perspective and use the output to source mapping feature of the debugger: click in the Text output view on the fragment of the output that you want to know where is created and you will see highlighted the element of the XML input and the template of the XSLT stylesheet that created the output fragment.

Regards,
Sorin

Don't understand where the extreaneous text is coming from

Posted: Tue May 02, 2006 5:25 pm
by nam
I have run it in debugger mode, and the value of the $datext variable as shown in the Variables view is "American Eagles&nbsp;for $5&nbsp;", but the output is "American Eagles&nbsp;&#xA;for $5&nbsp;" It's the &#xA that's screwing me all up - it prevents the data from being passed to the function. It is not being inserted by the template - only when the text is output to HTML in this code:

<a onMouseout="hideddrivetip()">
<xsl:attribute name="onMouseover">
<xsl:text disable-output-escaping="yes">ddrivetip('</xsl:text>
<xsl:value-of select='$datext' />
<xsl:text disable-output-escaping="yes">', </xsl:text>
<xsl:value-of select='$width2' />
<xsl:text disable-output-escaping="yes">)</xsl:text>
</xsl:attribute>

<font color="#000000" face="arial, sans-serif" size="2" style="font-size: 9pt">

<xsl:value-of select="../../Brand" />
<xsl:text disable-output-escaping="yes">&nbsp;</xsl:text>
<xsl:value-of select="../../Type" />
<xsl:text disable-output-escaping="yes">&nbsp;</xsl:text>
<xsl:value-of select="../../Note" />.
</font>
</a>

I even tried this: <xsl:value-of disable-output-escaping="yes" select='$datext' /> but it makes no difference.

Since the output isn't written to the results pane until the tag is closed, I can't see what's happening at each step, but I don't see anything that should create a line break.

Can anyone tell me what's happening here?

Posted: Tue May 02, 2006 5:38 pm
by george
The debugger presents the values on one row so the new line are normalized when rendered... Instead of using a variable $x use translate($x, '&#xA;', ''), that is remove new lines from it.

Hope that helps,
George

Thanks!

Posted: Tue May 02, 2006 6:21 pm
by nam
The translate worked, but I'm really curious as to where the line feeds were coming from. The thing I never liked about scripting or macro languages is what they would do to you - not for you, and this is an example.

How do I make any progress writing this stuff when it adds stuff I don't want?

Posted: Wed May 03, 2006 12:34 pm
by george
The new line appears when you define the variable. From the code you posted the variable definition cannot be seen.

Best Regards,
George

Newline/variable definition

Posted: Wed May 03, 2006 5:20 pm
by nam
You mean to tell me that every time you create a variable, a newline is added to:

a) the end of the variable itself, or
b) the output stream

I wonder who thunk up that one?

Thanks for the info.

Posted: Wed May 03, 2006 5:34 pm
by george
No, I did not said that. Variables in XSLT are immutable so if it contains a new line that new line appears where the variable is declared. For instance if you have something like

Code: Select all


<xsl:variable name="test">
2
</xsl:variable>
Then the variable contains two new lines.

Best Regards,
George

NLs in variables

Posted: Wed May 03, 2006 5:55 pm
by nam
So to create that one without the NLs, the code would be

<xsl:variable name="test">2</xsl:variable>

Right?

Posted: Wed May 03, 2006 5:57 pm
by george
Right.

Best Regards,
George

Thanks

Posted: Wed May 03, 2006 6:02 pm
by nam
Thanks. That helps.