Shai Balassiano
Shai Balassiano

Reputation: 1007

links, xsl and why chrome concatenate a line feed (aka %0A HEX symbol)

I have a funny problem with presenting links in Chrome using XSL: every link concatenated with the HEX symbol "%0A".
so if the link is "www.google.com", it will be presented as "www.google.com%0A".
this problem only occurs in google chrome - Internet Explorer and FireFox present links correctly.
so my question is: how do I prevent google chrome from messing with the links? here is a sample of the XML file:

<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="builtMathCSStatisticsXML.xsl"?>
<channel>
<item>
<title>algrbra
</title>
<type>class notes
</type>
<staff>Noga Alon
</staff>
<semester>
</semester>
<year>2011
</year>
<donor>anonymous
</donor>
<link>https://skydrive.live.com/self.aspx?path=%2f%d7%9e%d7%aa%d7%9e%d7%98%d7%99%d7%a7%d7%94%2f%d7%90%d7%9c%d7%92%d7%91%d7%a8%d7%94%20%d7%911.%d7%a9%d7%99%d7%a2%d7%95%d7%a8%d7%99%d7%9d%20%d7%95%d7%aa%d7%a8%d7%92%d7%99%d7%9c%d7%99%d7%9d.%d7%a0%d7%95%d7%92%d7%94%20%d7%90%d7%9c%d7%95%d7%9f%5e.%d7%aa%d7%a9%d7%a1%5e4%5e4%d7%96%20-%20%d7%a8%d7%95%d7%a2%d7%99%20%d7%a7%d7%9c%d7%99%d7%99%d7%9f.pdf&amp;cid=1f8a5680599afff9
</link>
</item>
...
</channel>

and here is the xsl file:

<?xml version="1.0"?
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
  <html>
  <head>
  <script src="sorttable.js"></script>
  </head>
  <body dir="rtl">
    <h2>Math CS and Statistics</h2>
    <table class="sortable">
    <thead>
      <tr bgcolor="#9acd32">
        <th>course</th>
        <th>type</th>
        <th>proffesor</th>
        <th>semster</th>
        <th>year</th>
        <th>donors</th>
        <th>links</th>
      </tr>
      </thead>
      <tbody>
      <xsl:for-each select="channel/item">
      <xsl:sort select="title" />
      <tr onMouseOver="this.bgColor='yellow';" onMouseOut="this.bgColor='white';">
        <td><xsl:value-of select="title"/></td>
        <td><xsl:value-of select="type"/></td>
        <td><xsl:value-of select="staff"/></td>
        <td><xsl:value-of select="semester"/></td>
        <td><xsl:value-of select="year"/></td>
        <td><xsl:value-of select="donor"/></td>
        <td>
    <a target="_blank"><xsl:attribute name="href">
         <xsl:value-of select="link"/>
        </xsl:attribute>link</a>
        </td>
      </tr>
      </xsl:for-each>
      </tbody>
    </table>
  </body>
  </html>
</xsl:template>
</xsl:stylesheet>

thanks!

Upvotes: 2

Views: 1115

Answers (2)

Dimitre Novatchev
Dimitre Novatchev

Reputation: 243479

This behavior is according to the XSLT 1.0 Spec, and the explanation is rather tricky:

NOTE:When an xsl:attribute contains a text node with a newline, then the XML output must contain a character reference. For example,

<xsl:attribute name="a">x
y</xsl:attribute>

will result in the output

a="x&#xA;y"

(or with any equivalent character reference). The XML output cannot be

a="x
y"

This is because XML 1.0 requires newline characters in attribute values to be normalized into spaces but requires character references to newline characters not to be normalized. The attribute values in the data model represent the attribute value after normalization. If a newline occurring in an attribute value in the tree were output as a newline character rather than as character reference, then the attribute value in the tree created by reparsing the XML would contain a space not a newline, which would mean that the tree had not been output correctly.

So, if you really don't want the character entity, write:

<link>string</link>

and not:

<link>string
</link>

Alternatively, use:

<xsl:attribute name="href">
 <xsl:value-of select="normalize-space(link)"/>
</xsl:attribute>

However, be aware that this will replace any group of non-leading or non-trailing whitespace characters with only a single space.

Upvotes: 2

Fishcake
Fishcake

Reputation: 10764

Clearly Firefox and IE handle it differently but I think it's caused by the newline / carriage return character in your XML. I'm assuming this as </link> is on the line below the rest of the link.

You should be able to prevent this by using normalize-space. Here's a similar question I asked which has more details in the comments. XSLT find and replace carriage returns

Upvotes: 1

Related Questions