Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

xsl trying to ouput '<' as opposed to '&lt;'

Update:

The issue still persists although it is not quite the same as before. Below is an example of what is being input, what is being output and what I want to have output

An example of the input:

&amp;lt;p&amp;gt;&amp;lt;span style=&amp;quot;font-size: medium&amp;quot;&amp;gt;Product description text&amp;lt;/span&amp;gt;&amp;lt;/p&amp;gt;

Current output:

&lt;p&gt;&lt;span style="font-size: medium"&gt;Product description text&lt;/span&gt;&lt;/p&gt;

Intended output:

<p><span style="font-size: medium">Product description text</span></p>

.

Using CDATA has helped as it allows me to input '<' but as seen in the output above, even when using disable-output-escaping, it has changed in the output

.

.

Original question:

The error I'm getting is "'<', hexadecimal value 0x3C, is an invalid attribute character"

What I'm trying to do is replace all occurrences of &lt ; and &gt ; with < and > respectively.

To keep this as simple as possible, here is the code for just lt;:

<xsl:variable name="lt">
  <xsl:text><</xsl:text>
</xsl:variable>
<xsl:variable name="lthex">&amp;lt;</xsl:variable>
<xsl:copy-of select="ew:replacestring(products_description/node(),$lthex,$lt)"/>

I've tried various things in place of text e.g. value-of etc.

I know there's nothing wrong with the code format and the vb code linked to it because I'm using it multiple times to replace and output elsewhere

The problem with this though is that I want < and > to literally be ouput, not a code which is then seen by the browser and changed

.

If you need more information just ask (I'm struggling to explain this very well)

Any help will be appreciated

like image 856
dudledok Avatar asked Jul 12 '11 11:07

dudledok


2 Answers

<xsl:text disable-output-escaping="yes"><![CDATA[<]]></xsl:text>

This is because < is illegal (and that's why your app is complaining). For >, you can use:

<xsl:text disable-output-escaping="yes">></xsl:text>
like image 51
Emiliano Poggi Avatar answered Nov 14 '22 05:11

Emiliano Poggi


The original problem

An example of the input:

&amp;lt;p&amp;gt;&amp;lt;span style=&amp;quot;font-size: medium&amp;quot;&amp;gt;Product description text&amp;lt;/span&amp;gt;&amp;lt;/p&amp;gt;

Intended output:

<p><span style="font-size: medium">Product description text</span></p>

What you really seem to have is double escaped input so instead of just simple outputting the text with disable-output-escaping="yes" you need some ways to do string replacing. Clearly it seems that you do the replacing with ew:replacestring() extension function. The problem is that even if you manage to replace &amp;lt; with <, the result is still only a string and the < character gets escaped on output.

Your original replacement text code was not well-formed because < as such is seen as markup. Using

<xsl:variable name="lt">
  <xsl:text><![CDATA[<]]></xsl:text>
</xsl:variable>

or

<xsl:variable name="lt">
  <xsl:text>&lt;</xsl:text>
</xsl:variable>

are equivalent and fix that problem. However this doesn't help in the problem that the replacement character still is outputted as an entity reference. Using disable-output-escaping="yes" here in the variable definition has no effect on that problem either.

<xsl:variable name="lt">
  <xsl:text disable-output-escaping="yes">&lt;</xsl:text>
</xsl:variable>

<xsl:variable name="lt">
  <xsl:value-of select="&lt;" disable-output-escaping="yes">
</xsl:variable>

These code examples don't work because disable-output-escaping="yes" only has an effect when the value is serialized, not when a variable gets assigned.

A possible fix

What you could try to do is to store the result of your text replacing into a variable

<xsl:variable name="replaced-text">
    <xsl:copy-of select="ew:replacestring(products_description/node(),$lthex,$lt)"/>
</xsl:variable>

and then output the value of this variable with disable-output-escaping="yes"

<xsl:value-of select="$replaced-text" disable-output-escaping="yes"/>

Another solution without extension functions

I was able to transform your input

&amp;lt;p&amp;gt;&amp;lt;span style=&amp;quot;font-size: medium&amp;quot;&amp;gt;Product description text&amp;lt;/span&amp;gt;&amp;lt;/p&amp;gt;

to this output

<p><span style="font-size: medium">Product description text</span></p>

with a slightly modified version of Jeni Tennison's acronym replacement template. In your case the document containing the acronym titles would look like this

<acronyms>
    <acronym acronym="&amp;lt;">&lt;</acronym>
    <acronym acronym="&amp;gt;">></acronym>
    <acronym acronym="&amp;amp;">&amp;</acronym>
    <acronym acronym="&amp;apos;">'</acronym>
    <acronym acronym="&amp;quot;">"</acronym>
</acronyms>

The required modification would be to change this part of the code example

<acronym title="{$acronyms[1]}">
    <xsl:value-of select="$acronym" />
</acronym>

to look like this

<xsl:value-of select="$acronyms[1]" disable-output-escaping="yes"/>

That template should work in every environment because it is XSLT 1.0 and it doesn't require any extension functions.

like image 37
jasso Avatar answered Nov 14 '22 03:11

jasso