Passing formatted data into an attribute

Here should go questions about transforming XML with XSLT and FOP.
nam
Posts: 18
Joined: Fri Apr 21, 2006 12:41 am

Passing formatted data into an attribute

Post 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.
Neil in Washington
george
Site Admin
Posts: 2095
Joined: Thu Jan 09, 2003 2:58 pm

Post 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
nam
Posts: 18
Joined: Fri Apr 21, 2006 12:41 am

Post 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.
Neil in Washington
sorin_ristache
Posts: 4141
Joined: Fri Mar 28, 2003 2:12 pm

Post 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
nam
Posts: 18
Joined: Fri Apr 21, 2006 12:41 am

Don't understand where the extreaneous text is coming from

Post 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?
Neil in Washington
george
Site Admin
Posts: 2095
Joined: Thu Jan 09, 2003 2:58 pm

Post 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
nam
Posts: 18
Joined: Fri Apr 21, 2006 12:41 am

Thanks!

Post 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?
Neil in Washington
george
Site Admin
Posts: 2095
Joined: Thu Jan 09, 2003 2:58 pm

Post 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
nam
Posts: 18
Joined: Fri Apr 21, 2006 12:41 am

Newline/variable definition

Post 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.
Neil in Washington
george
Site Admin
Posts: 2095
Joined: Thu Jan 09, 2003 2:58 pm

Post 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
nam
Posts: 18
Joined: Fri Apr 21, 2006 12:41 am

NLs in variables

Post by nam »

So to create that one without the NLs, the code would be

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

Right?
Neil in Washington
george
Site Admin
Posts: 2095
Joined: Thu Jan 09, 2003 2:58 pm

Post by george »

Right.

Best Regards,
George
nam
Posts: 18
Joined: Fri Apr 21, 2006 12:41 am

Thanks

Post by nam »

Thanks. That helps.
Neil in Washington
Post Reply