XSLT engine removing whitespace from <xsl:text> element in text output - xslt

I have a transformation that outputs a fixed length output, so where data is "missing" I pad the data with spaces.
so using
<xsl:output method="text" encoding="ISO-8859-1"/>
and then using things like
<xsl:text> </xsl:text>
whenever I need to pad for missing data.
This works very nicely in my dev environment (using visual studio).
but when I deploy it to another machine (which also uses MS XSLT engine, but with unknown parameters, allegedly 6.0), some of my whitespace gets "removed" and my data gets misalligned.
If I replace the above with things like
<xsl:text> </xsl:text>
then that doesnt get stripped.
this also works
<xsl:text xml:space="preserve"> </xsl:text>
Is there a way to get the XSLT to 'preserve' standard spaces in the "text" elements globally?
(the transformation is quite big and I don't want to have to go through replacing every space with , plus it worries me that its not doing 'exactly' what I'm asking it to do)
(I've looked at other questions on this, which is where I got the from, but I'd like to turn the XSLT behaviour OFF)

Related

Can we encode URL in .xsl file?

Can we encode URL in .xsl file? If yes, then how we can do that?
I have used below code:
Prompt type="label" pointer="abc.asp?mynumber={my-number}&myname={my-name}"
It works fine for other name, but if name contains &, then it is breaking.
Could someone help me to solve it?
In my experience browsers may treat & and & the same you're likely to end up with a link that doesn't work correctly anyway.
If you're not certain of what the my-name node might contain then it might be better to create a variable from it first. Then you can make sure that any ampersands are removed first.
Actually, the first thing you should try is to agree that the my-name node never contains an ampersand in the first place. But I know that sort of request is often ignored so there is a solution.
If you use a variable, you can include a find and replace to remove/replace the &. There isn't a function for this in xslt 1 but you can use the translate function instead
<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:template match="/Test">
<xsl:variable name="safe-name" select="translate(my-name, '&', '|')"/>
MyName - <xsl:value-of select="$safe-name"/>
</xsl:template>
</xsl:stylesheet>
I've given this a quick test and it works with several & in the node (you can never be too careful). Hope that helps

xsl text and normal string

What is the differnce between
<xsl:param name="abc">123</xsl:param>
<xsl:param name="def"><xsl:text>123</xsl:text></xsl:param>
They both work same but is there some difference between the two.
<xsl:text> will allow you to manipulate the text (escape as well as white space):
<xsl:text disable-output-escaping="yes|no">
From http://msdn.microsoft.com/en-us/library/ms256107(v=vs.110).aspx:
In a style sheet, text can be generated to the literal result tree
with or without <xsl:text>. However, with this element you can exert
some control over the white space created by the style sheet. For
example, to make your style sheet more readable, you might want to
write one element per line in a template, and indent some lines. Doing
so introduces white space as part of the template rule. This might or
might not be a desired effect of the transformation. Sometimes you
might want to introduce a white space character to separate two data
values. You can use an <xsl:text> element to accomplish this. White
space enclosed within <xsl:text> is output to the result tree.
The main reason for using <xsl:text> is that whitespace arount text XSLT stylesheets is normally discarded/stripped (http://www.w3.org/TR/xslt#strip). Text enclosed in <xsl:text> is the exception to that rule. So if you want to explicitly output spaces, tabs, or newlines you may need to use <xsl:text>
<xsl:text> also allows case-by-case control over the output escaping mode. That's less frequently used; disabling output escaping is usually the wrong solution unless you're generating non-XML/non-HTML output.
[Apologies for the confusion, now corrected above. I just noticed that I had indeed been looking at a Working Draft of XSLT 1.0, not the final RECcomendation. Mea culpa, mea culpa, mea maxima culpa.]

XSLT: keeping whitespaces when copying attributes

I'm trying to sort Microsoft Visual Studio's vcproj so that a diff would show something meaningful after e.g. deleting a file from a project. Besides the sorting, I want to keep everything intact, including whitespaces. The input looks like
space<File
spacespaceRelativePath="filename"
spacespace>
...
The xslt fragment below can add the spaces around elements, but I can't find out how to deal with those around attributes, so my output looks like
space<File RelativePath="filename">
xslt I use for the msxsl 4.0 processor:
<xsl:for-each select="File">
<xsl:sort select="#RelativePath"/>
<xsl:value-of select="preceding-sibling::text()[1]"/>
<xsl:copy>
<xsl:for-each select="text()|#*">
<xsl:copy/>
</xsl:for-each>
Those spaces are always insignificant in XML, and I believe that there is no option to control this behavior in a general way for any XML/XSLT library.
XSLT works on a tree representation of the input XML. Many of the irrelevant detail of the original XML has been abstracted away in this tree - for example the order of attributes, insignificant whitespace between attributes, or the distinction between " and ' as an attribute delimiter. I can't see any conceivable reason for wanting to write a program that treats these distinctions as significant.

How to check XML has a node or it is an empty file using XSLT?

Please help on this issue.
I want to check an XML contains a node or not [OR] it is an empty file using XSLT.
My XML is:
<mynode>
<node1>testing</node1>
</mynode>
I want to write XSLT code something like this:
<xsl:choose>
<xsl:when test="document('')/mynode">
file is empty
</xsl:when>
<xsl:otherwise>
file has nodes
</xsl:otherwise>
</xsl:choose>
Please any one can help me on this.....
If the file doesn't contain an element, then it is not an XML file, and XML parsing will therefore fail. Different XSLT 1.0 processors react differently to this (as permitted by the spec). In XSLT 2.0 you can use doc-available() to protect yourself, but this is not available in 1.0. In fact, there's nothing you can do about this in 1.0 without knowing details of your particular XSLT processor.

Automatically converting escaped characters to string literals

I am working on an XSLT transformation to re-arrange XML blocks to validate NewsML files. Some of these files contains encoded characters (such as & " etc...). The problem is the XSLT transformation is converting these characters to their literal string (ie "and", "'"). This is causing problems. I do not want this to happen.
I have experimented with various techniques (uses of <xsl:text>, <xsl:value-of> and the disable-output-escaping flag, <xsl:output method='xml|html|xhtml|text'>) to no avail. These methods either, convert the characters, or simply leave them out.
eg, a string which starts with "stars on PM&apos;s cards" can end up as
stars on PM's cards
stars on PMs cards
I am using the Saxonica (http://www.saxonica.com/) processing app.
The basic XSLT I am using is provided below. (There are other things but the problem exists even with this simplest stylesheet)
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="no" />
<xsl:template match="#*|node()">
<xsl:copy>
<xsl:apply-templates select="#*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Any ideas on how to prevent this conversion would be most appreciated. The requirement is to keep the original text as it appears.
I think you need to do both the disable-output-escaping="yes" and set the document to HTML at the same time.
FROM W3C (emphasis mine):
It is an error for output escaping to be disabled for a text node that is used for something other than a text node in the result tree. Thus, it is an error to disable output escaping for an xsl:value-of or xsl:text element that is used to generate the string-value of a comment, processing instruction or attribute node; it is also an error to convert a result tree fragment to a number or a string if the result tree fragment contains a text node for which escaping was disabled. In both cases, an XSLT processor may signal the error; if it does not signal the error, it must recover by ignoring the disable-output-escaping attribute.
The disable-output-escaping attribute may be used with the html output method as well as with the xml output method. The text output method ignores the disable-output-escaping attribute, since it does not perform any output escaping.
An XSLT processor will only be able to disable output escaping if it controls how the result tree is output. This may not always be the case. For example, the result tree may be used as the source tree for another XSLT transformation instead of being output. An XSLT processor is not required to support disabling output escaping. If an xsl:value-of or xsl:text specifies that output escaping should be disabled and the XSLT processor does not support this, the XSLT processor may signal an error; if it does not signal an error, it must recover by not disabling output escaping.
If output escaping is disabled for a character that is not representable in the encoding that the XSLT processor is using for output, then the XSLT processor may signal an error; if it does not signal an error, it must recover by not disabling output escaping.
Since disabling output escaping may not work with all XSLT processors and can result in XML that is not well-formed, it should be used only when there is no alternative.
These are entities. Usually they get mapped to a unicode representation of that entity. The final stream will just contain the characters. If you output the stream it's up to the serializer to escape the characters depending on the output type (which is what you can disable with disable-output-escaping). So a proper serializer should turn this
<xsl:output method="html" encoding="UTF-8"/>
<xsl:text>some test</xsl:text>
into
some test
See section 5 on this article.
So I would check that with your XSLT processor first.