Unexpected results from XSLT in Chrome - google-chrome

In a program im writing, parts of the web interface are sent to the client as XML, and transformed into HTML fragments using Javascript and an XSLT. This works fine in Firefox (4.0b12) and Opera (10.63) but in Chrome (9.0.597.107) the results arn't as expected.
The XSLT
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" indent ="yes"/>
<xsl:template match ="/">
<xsl:for-each select="queue/download">
<xsl:choose>
<xsl:when test="status='downloadError'">
<xsl:variable name="rowClass">ui-state-error</xsl:variable>
<xsl:variable name="iconClass">ui-icon ui-icon-alert</xsl:variable>
<xsl:call-template name="download">
<xsl:with-param name="iconClass" select="$iconClass"/>
<xsl:with-param name="rowClass" select ="$rowClass"/>
</xsl:call-template>
</xsl:when>
<xsl:when test="status='downloadRunning'">
<xsl:variable name="rowClass">ui-state-highlight</xsl:variable>
<xsl:variable name="iconClass">ui-icon ui-icon-refresh</xsl:variable>
<xsl:call-template name="download">
<xsl:with-param name="iconClass" select="$iconClass"/>
<xsl:with-param name="rowClass" select ="$rowClass"/>
</xsl:call-template>
</xsl:when>
<xsl:when test="status='downloadComplete'">
<xsl:variable name="rowClass">downloadComplete</xsl:variable>
<xsl:variable name="iconClass">ui-icon ui-icon-circle-check</xsl:variable>
<xsl:call-template name="download">
<xsl:with-param name="iconClass" select="$iconClass"/>
<xsl:with-param name="rowClass" select ="$rowClass"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:variable name="rowClass" select ="status" />
<xsl:variable name="iconClass"/>
<xsl:call-template name="download">
<xsl:with-param name="iconClass" select="$iconClass"/>
<xsl:with-param name="rowClass" select ="$rowClass"/>
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
</xsl:template>
<xsl:template name="download">
<xsl:param name="rowClass"/>
<xsl:param name="iconClass" />
<xsl:variable name="id" select ="id"/>
<xsl:variable name="filename" select ="filename"/>
<xsl:variable name="comment" select ="comment"/>
<tr class="{$rowClass}">
<td class="downloadCheck">
<input type="checkbox" class="downloadCheckbox" value="{$id}" name="downloadCheckbox"/>
</td>
<td class="downloadIcon">
<span class="{$iconClass}"></span>
</td>
<td class="downloadName">
<a href="#" onclick="showDownloadCommentBox('{$id}','{$filename}', '{$comment}');">
<xsl:value-of select="filename"/>
</a>
</td>
<xsl:if test="status='downloadError'">
<td class="dError" colspan="4">
<xsl:value-of select ="errortext"/>
</td>
</xsl:if>
<xsl:if test ="status!='downloadError'">
<xsl:variable name="progress" select ="progress"/>
<td class="downloadProgress">
<div class="jqProgress" value="{$progress}"></div>
</td>
<td class="downloadTimeLeft">
<xsl:value-of select ="timeremaining"/>
</td>
<td class="downloadSize">
<xsl:value-of select ="size"/>
</td>
<td class="downloadSpeed">
<xsl:value-of select ="speed"/>
</td>
</xsl:if>
</tr>
</xsl:template>
</xsl:stylesheet>
The XML
<queue>
<name>test</name>
<renderer>downloadQueue</renderer>
<xsl>/xslt/downloadQueue.xslt</xsl>
<status>suspended</status>
<startMode>manual</startMode>
<downloadDirectory>C:\Users\William\Programming\SCRAMDownloader\Trunk\bin\</downloadDirectory>
<download>
<filename>test.zip</filename>
<progress>0.00%</progress>
<speed>-</speed>
<timeremaining>-</timeremaining>
<status>downloadSuspended</status>
<size>119.68 MB</size>
<id>8976170e-1f4b-4b79-8901-5a4191e2c07d</id>
<comment/>
</download>
</queue>
Expected Results (Firefox)
<tr class="downloadSuspended">
<td class="downloadCheck"><input type="checkbox" class="downloadCheckbox" value="8976170e-1f4b-4b79-8901-5a4191e2c07d" name="downloadCheckbox"></td>
<td class="downloadIcon"><span class=""></span></td>
<td class="downloadName">test.zip</td>
<td class="downloadProgress"><div class="jqProgress ui-progressbar ui-widget ui-widget-content ui-corner-all" value="0.00%" role="progressbar" aria-valuemin="0" aria-valuemax="100" aria-valuenow="0"><div class="ui-progressbar-value ui-widget-header ui-corner-left" style="width: 0%;"></div></div></td>
<td class="downloadTimeLeft">-</td>
<td class="downloadSize">119.68 MB</td>
<td class="downloadSpeed">-</td>
</tr>
Results in Chrome
<input type="checkbox" class="downloadCheckbox" value="8976170e-1f4b-4b79-8901-5a4191e2c07d" name="downloadCheckbox">
<span class=""></span>
test.zip
<div class="jqProgress ui-progressbar ui-widget ui-widget-content ui-corner-all" value="0.00%" role="progressbar" aria-valuemin="0" aria-valuemax="100" aria-valuenow="0"><div class="ui-progressbar-value ui-widget-header ui-corner-left" style="width: 0%; "></div></div>
-
119.68 MB
-
Note the missing <tr> and <td> tags
Any ideas what im doing wrong?
(Apologies for the overly long post)

Any ideas what im doing wrong?
Nothing, except perhaps using a buggy XSLT processor (whatever google-chrome uses).
I have tested this transformation with the following nine different XSLT (1.0 and 2.0) processors and the result from all of them is correct:
MSXML 3,4,6
ALtova (XML SPY)
.NET (XslCompiledTransform and XslTransform)
Saxon (6.5.4 and 9.1.05)
XQSharp

I just had the same issue.
I gues the problem is that chrome validates the output of the xslt parsing and expects a surrounding the and . If you put around your 's, I think the problem would be solved (it works for me...)
You can then strip the tag from the result if you don't need it...

Related

How to calculate the test results pass percentage in XSLT

The input is an XML file
<test-results name="project name" total="73" errors="0" failures="43" not-run="0" inconclusive="0" ignored="0" skipped="0" invalid="0" date="2016-01-05" time="20:32:22">
.......
</test-results>
I want to calculate the "No of pass results" and "Pass Percentage". I have done with the No of pass results. It is working fine
<tr>
<td>Number of Passes</td>
<td>
<xsl:variable name="failures" select="#failures"/>
<xsl:variable name="total" select="#total"/>
<xsl:choose>
<xsl:when test="$failures != ''">
<xsl:value-of select="($total - $failures)"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="#total"/>
</xsl:otherwise>
</xsl:choose>
</td>
</tr>
Now I want to calculate the pass percentage(eg :- 87.45%). I tried the below logic. but it is throwing an exception
<tr>
<td>Success Rate</td>
<td>
<xsl:variable name="Pass" select="#total - #failures"/>
<xsl:variable name="totalNo" select="#total"/>
<xsl:value-of select="($Pass/$totalNo)*100"/>
</td>
</tr>
Can anyone help me out to calculate the pass percentage?
Thanks in advance.
Use the div operator instead of the / sign:
<xsl:value-of select="$Pass div $totalNo * 100"/>

Render HTML tags as HTML when read through XML RSS feed Sharepoint 2013

There have been similar questions but none working with SharePoint and the XSL editor.
I have an RSS feed which is pulling in article titles, along with accompanying html tags as shown below:
<i>Wall Street Journal</i> Article on Competition in the Dental Industry
I would like to have those <i> (and any other HTML tags) be read as HTML, not text..i.e an end result of:
Wall Street Journal Article on Competition in the Dental Industry
I can read and semi-reverse engineer XML, but writing it is another story.
Any help will be greatly appreciated.
A sample of my code where I think the changes is needed, below:
<xsl:template name="RSSMainTemplate.body" xmlns:ddwrt="http://schemas.microsoft.com/WebParts/v2/DataView/runtime" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt">
<xsl:param name="Rows"/>
<xsl:param name="RowCount"/>
<xsl:for-each select="$Rows">
<xsl:variable name="CurPosition" select="position()" />
<xsl:variable name="RssFeedLink" select="$rss_WebPartID" />
<xsl:variable name="CurrentElement" select="concat($RssFeedLink,$CurPosition)" />
<xsl:if test="($CurPosition <= $rss_FeedLimit)">
<div class="item link-item" >
<a href="{concat("javascript:ToggleItemDescription('",$CurrentElement,"')")}" >
<xsl:value-of select="title"/>
</a>
<xsl:if test="$rss_ExpandFeed = true()">
<xsl:call-template name="RSSMainTemplate.description">
<xsl:with-param name="DescriptionStyle" select="string('display:block;')"/>
<xsl:with-param name="CurrentElement" select="$CurrentElement"/>
</xsl:call-template>
</xsl:if>
<xsl:if test="$rss_ExpandFeed = false()">
<xsl:call-template name="RSSMainTemplate.description">
<xsl:with-param name="DescriptionStyle" select="string('display:none;')"/>
<xsl:with-param name="CurrentElement" select="$CurrentElement"/>
</xsl:call-template>
</xsl:if>
</div>
</xsl:if>
</xsl:for-each>
</xsl:template>
Figured it out.
The key to this issue is the disable-output-escaping attribute. I was correct about the location of the issue. Below is my adjusted code. Notice lines 10-15
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt">
<xsl:param name="Rows"/>
<xsl:param name="RowCount"/>
<xsl:for-each select="$Rows">
<xsl:variable name="CurPosition" select="position()" />
<xsl:variable name="RssFeedLink" select="$rss_WebPartID" />
<xsl:variable name="CurrentElement" select="concat($RssFeedLink,$CurPosition)" />
<xsl:if test="($CurPosition <= $rss_FeedLimit)">
<div class="item link-item" >
<a href="{concat("javascript:ToggleItemDescription('",$CurrentElement,"')")}" >
<xsl:variable name="SafeHtml">
<xsl:call-template name="GetSafeHtml">
<xsl:with-param name="Html" select="title"/>
</xsl:call-template>
</xsl:variable>
<xsl:value-of select="$SafeHtml" disable-output-escaping="yes"/>
</a>
<xsl:if test="$rss_ExpandFeed = true()">
<xsl:call-template name="RSSMainTemplate.description">
<xsl:with-param name="DescriptionStyle" select="string('display:block;')"/>
<xsl:with-param name="CurrentElement" select="$CurrentElement"/>
</xsl:call-template>
</xsl:if>
<xsl:if test="$rss_ExpandFeed = false()">
<xsl:call-template name="RSSMainTemplate.description">
<xsl:with-param name="DescriptionStyle" select="string('display:none;')"/>
<xsl:with-param name="CurrentElement" select="$CurrentElement"/>
</xsl:call-template>
</xsl:if>
</div>
</xsl:if>
</xsl:for-each>
<div class="description">
<h4 class="ms-rteElement-H4B">
<span class="ms-rteStyle-Emphasis">
<br></br>View More Articles <img alt="more-icon-1.png" src="/BHiveImageGallery/Stock-Images/more-icon-1.png"/>
</span>
<span class="ms-rteStyle-Emphasis"> </span>
</h4>
</div>
My full code is too long and formatted too uniquely to get it to display as I want in the window. It is 3/20/2015 right now, if you message me within the next 5 years i'll be able to send you the code, beyond that, no guarantees haha.
Generally though I used the SharePoint 2013 standard RSS viewer webpart code, and only modified the piece above

How to transform a CSV matrix to a HTML table via XSLT 1.0?

The XML matrix with csv rows
<matrix ROWS="3" COLS="4">
<row>"1,2,3,4"</row>
<row>"5,6,7,8"</row>
<row>"9,10,11,12"</row>
</matrix>
is to be transformed with XSLT 1.0 without extensions into a HTML table
<table>
<tr><td>1</td><td>2</td><td>3</td><td>4</td></tr>
<tr><td>5</td><td>6</td><td>7</td><td>8</td></tr>
<tr><td>9</td><td>10</td><td>11</td><td>12</td></tr>
</table>
The number of rows and columns (ROWS, COLS) are variable.
I appreciate any help.
How about:
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" omit-xml-declaration="yes" version="1.0" encoding="utf-8" indent="yes"/>
<xsl:template match="/matrix">
<table>
<xsl:for-each select="row">
<tr>
<xsl:call-template name="tokenize">
<xsl:with-param name="text" select="substring(., 2, string-length(.) - 2)"/>
</xsl:call-template>
</tr>
</xsl:for-each>
</table>
</xsl:template>
<xsl:template name="tokenize">
<xsl:param name="text"/>
<xsl:param name="delimiter" select="','"/>
<xsl:variable name="token" select="substring-before(concat($text, $delimiter), $delimiter)" />
<xsl:if test="$token">
<td>
<xsl:value-of select="$token"/>
</td>
</xsl:if>
<xsl:if test="contains($text, $delimiter)">
<!-- recursive call -->
<xsl:call-template name="tokenize">
<xsl:with-param name="text" select="substring-after($text, $delimiter)"/>
</xsl:call-template>
</xsl:if>
</xsl:template>
</xsl:stylesheet>

Generic xml -> html conversion using xslt and convention?

I have been scouring the web for something like this and being a lazy programmer, before I attempt to do so myself, I thought I would ask here.
What I would like is a method to take any xml with node names following a convention (like cakephp or ruby) and then for that data to be presented in a ready to print format.
ie:
<xml>
<home_address>The Street</home_address>
</xml>
to:
<tr><td>Home Address</td><td>The Street</td></tr>
etc. with children having separate tables.
It seems pretty straightforward and something that would have been desired many times before. I found one useful discussion, but with no conclusion.
http://www.daniweb.com/software-development/xml-xslt-and-xpath/threads/363621/xml-to-html-using-xslt-without-hardcoding-node-names-in-xslt
Have I missed something here? Is there a simple generic xslt/css method for doing this? Or is this work being repeated hundreds of times a day in cubicles around the world?
Thanks in advance,
F
use the following XSL stylesheet. I have tested it and it works.
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl">
<xsl:template match="/">
<xsl:for-each select="*">
<xsl:for-each select="*">
<tr>
<xsl:variable name="NodeNameClearText">
<xsl:call-template name="repalceNodeName">
<xsl:with-param name="value" select="local-name(.)"/>
</xsl:call-template>
</xsl:variable>
<td>
<xsl:value-of select="$NodeNameClearText" />
</td>
<td>
<xsl:value-of select="." />
</td>
</tr>
</xsl:for-each>
</xsl:for-each>
</xsl:template>
<xsl:template name="repalceNodeName">
<xsl:param name="value"/>
<xsl:variable name="valueWithoutUnderscores">
<xsl:value-of select="translate($value, '_',' ')"/>
</xsl:variable>
<xsl:call-template name="caseLowerAcceptFirstWord">
<xsl:with-param name="data" select="$valueWithoutUnderscores"/>
</xsl:call-template>
</xsl:template>
<xsl:template name="caseDown">
<xsl:param name="data"/>
<xsl:if test="$data">
<xsl:choose>
<xsl:when test="starts-with($data,' ')">
<xsl:text> </xsl:text>
<xsl:call-template name="caseLowerAcceptFirstWord">
<xsl:with-param name="data" select="normalize-space(substring($data,2))"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="translate(substring($data,1,1),
'ABCDEFGHIJKLMNOPQRSTUVWXYZ','abcdefghijklmnopqrstuvwxyz')"/>
<!-- put all the chars you want to change
into the last two strings -->
<xsl:call-template name="caseDown">
<xsl:with-param name="data" select="substring($data,2)"/>
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:if>
</xsl:template>
<xsl:template name="caseUP">
<xsl:param name="data"/>
<xsl:if test="$data">
<xsl:choose>
<xsl:when test="starts-with($data,' ')">
<xsl:text> </xsl:text>
<xsl:call-template name="caseLowerAcceptFirstWord">
<xsl:with-param name="data" select="substring($data,2)"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="translate(substring($data,1,1),
'abcdefghijklmnopqrstuvwxyz','ABCDEFGHIJKLMNOPQRSTUVWXYZ')"/>
<!-- put all the chars you want to change
into the last two strings -->
<xsl:call-template name="caseDown">
<xsl:with-param name="data" select="substring($data,2)"/>
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:if>
</xsl:template>
<xsl:template name="caseLowerAcceptFirstWord">
<xsl:param name="data"/>
<xsl:variable name="upperData">
<xsl:call-template name="caseUP">
<xsl:with-param name="data" select="$data"/>
</xsl:call-template>
</xsl:variable>
<xsl:if test="$upperData">
<xsl:value-of select="substring($upperData,1,1)"/>
<xsl:call-template name="caseDown">
<xsl:with-param name="data" select="substring($data,2)"/>
</xsl:call-template>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
A little more info on what I tested. The following XML:
<xml>
<home_address>The Street</home_address>
<po_box>474</po_box>
</xml>
Was output to
<tr><td>Home Address</td><td>The Street</td></tr>
<tr><td>Po Box</td><td>474</td></tr>
If thats not what you wanted your question is to vague

How to transform xml and keep newlines?

I'm trying to preserve row breaks in an xml file when transforming it to html, but I cant find a way that works.
<meta>
<name>Message</name>
<value>Hi!
I need info!
Mr Test</value>
</meta>
And I use this xsl:
<xsl:if test="name='Message'">
<tr>
<th align="left" colspan="2">Message:</th>
</tr>
<tr>
<td colspan="2"><xsl:value-of select="value"/></td>
</tr>
</xsl:if>
But the new line (cr/lf) characters dissapear, and everything becomes one single line in html. Is is possible to match the cr/lf and replace them with html "<_br >", or any other method?
Add the following template to your XSL:-
<xsl:template name="LFsToBRs">
<xsl:param name="input" />
<xsl:choose>
<xsl:when test="contains($input, '
')">
<xsl:value-of select="substring-before($input, '
')" /><br />
<xsl:call-template name="LFsToBRs">
<xsl:with-param name="input" select="substring-after($input, '
')" />
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$input" />
</xsl:otherwise>
</xsl:choose>
</xsl:template>
Now replace where select the value with a call to this template:-
<td colspan="2">
<xsl:call-template name="LFsToBRs">
<xsl:with-param name="input" select="value"/>
</xsl:call-template>
</td>
Greetings, if you already have LF or CR in the source xml (looks like you have),
try putting in a with "white-space: pre" style.
i.e:
<div style="white-space: pre;">
<xsl:value-of select="value"/>
</div>