Comparing an xs:boolean value in XSLT? - xslt

I have an xml schema with an element defined of type xs:boolean like this:
<xs:element name="useful"
minOccurs="1" maxOccurs="1"
type="xs:boolean"/>
I'm trying to use a choose/when/otherwise block in XSL to output something specific based on the value of that, like this:
<xsl:choose>
<xsl:when test="#useful = 0">No</xsl:when>
<xsl:otherwise>Yes</xsl:otherwise>
</xsl:choose>
I've tried every variation I can think of for that comparison (using true(), false(), 1, 0, removing the #, using //#) and it always prints out 'Yes'. What am I doing wrong here?
EDIT (by request from Martin Honnen):
Here's a sample of XML that's being used:
<?xml version="1.0"?>
<functions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="functions.xsd">
<function>
<name>func1</name>
<useful>0</useful>
</function>
<function>
<name>func2</name>
<useful>1</useful>
</function>
</functions>
This causes problems with using xsl:template I think, so I'm using xsl:for-each to loop through each function, and trying to output something specific for each useful tag. xsl:template can only be used at the top level of the xslt, correct?
The full XSLT file is
<?xml version='1.0' ?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<html><body>
<h2>Functions</h2>
<table border="1">
<tr>
<th>Functions</th>
<th>Useful</th>
</tr>
<xsl:for-each select="functions/function">
<tr>
<td>
<xsl:value-of select="name"/>
</td>
<td>
<xsl:choose>
<xsl:when test="#useful = 0">No</xsl:when>
<xsl:otherwise>Yes</xsl:otherwise>
</xsl:choose>
</td>
</tr>
</xsl:for-each>
</table>
</body></html>
</xsl:template>
</xsl:stylesheet>

I think the schema defines an element, but you are testing the value of an attribute -- this may be your main problem.
<xsl:choose>
<xsl:when test="#useful = 0">No</xsl:when>
<xsl:otherwise>Yes</xsl:otherwise>
</xsl:choose>
I've tried every variation I can think
of for that comparison (using
true(), false(), 1, 0,
removing the #, using //#) and it
always prints out 'Yes'. What am I
doing wrong here?
Most probably the current node is not an element that has an attribute named useful.
Here is how to work in XSLT 1.0 with the useful element type as defined by the schema:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="node()|#*">
<xsl:copy>
<xsl:apply-templates select="node()|#*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="useful/text()[. = 'true' or .='1']">
Yes
</xsl:template>
<xsl:template match="useful/text()[. = 'false' or .='0']">
No
</xsl:template>
</xsl:stylesheet>
when this transformation is applied to the following XML document:
<t>
<useful>true</useful>
<useful>false</useful>
<useful>1</useful>
<useful>0</useful>
</t>
the wanted, correct result is produced:
<t>
<useful>
Yes
</useful>
<useful>
No
</useful>
<useful>
Yes
</useful>
<useful>
No
</useful>
</t>
In XSLT 2.0 (Schema-aware processor), you need to import the schema (use <xsl:import-schema>) then you can simply use:
('no', 'yes')[number(useful)+1]
where the current node is the parent of the useful element.

Your schema defines an element named "useful" but the schema is not relevant at all unless you are trying to use schema aware XSLT 2.0.
Doing #useful in XPath selects an attribute of that name of the context node which does not make any sense with the schema you have, as that defines an element.
So show us your instance XML the XSLT is processing, then we can show you some XSLT code:
<xsl:template match="useful">
<xsl:choose>
<xsl:when test=". = 'false' or . = 0">No</xsl:when>
<xsl:otherwise>Yes</xsl:otherwise>
</xsl:choose>
</xsl:template>
With schema-aware XSLT 2.0 you could do
<xsl:template match="useful">
<xsl:value-of select="if (data(.)) then 'Yes' else 'No'"/>
</xsl:template>

Related

XSLT - how to find sum of attribute of one node list where attribute value exists in different node list

I have a problem I am running in to with a XSLT 1.0 stylesheet that I imagine is probably fairly simple but I can't seem to quite wrap my mind around it. So I have XML that looks something like this
<Components>
<Component Quantity="2.0" MaterialCode="1111"/>
<DispensingInstructions/>
<ChargeContainers>
<ChargeContainer BarcodeValue="def"/>
<ChargeContainer BarcodeValue="jkl"/>
</ChargeContainers>
<Comments/>
<Transactions/>
<DispenseContainers>
<Container BarcodeValue="abc" Quantity="1.0"></Container>
<Container BarcodeValue="def" Quantity="2.0"></Container>
<Container BarcodeValue="ghi" Quantity="3.0"></Container>
<Container BarcodeValue="jkl" Quantity="4.0"></Container>
</DispenseContainers>
</Component>
<Component Quantity="1.0" MaterialCode="12345"/>
<DispensingInstructions/>
<ChargeContainers/>
<Comments/>
<Transactions/>
<DispenseContainers/>
</Component>
</Components>
I am trying to get a sum of the "quantity" attribute of DispenseContainers, but only if the container barcode exists in ChargeContainers. So for this example, I would want a function that returned 6 because ChargeContainers has both a node with barcode "def" and a node with barcode "jkl" and DispenseContainers those have quantities of 2 and 4 which sum to 6.
I had some XSL that looks something like this:
<xsl:for-each select="//Component">
<!--
Place holder for code to make table row with a bunch of info from nodelists of component
-->
<td>
<xsl:variable name="TotalDispensedQuantity" select="sum(DispenseContainers/Container/#Quantity)" />
<xsl:if test="$TotalDispensedQuantity != number(#Quantity)">
<xsl:attribute name="style">background-color: red;</xsl:attribute>
</xsl:if>
</td>
</xsl:for-each>
but now I have to cross reference the dispense containers to ensure they exist in charge containers before I add their quantity to the sum. I attempted to add the key as stated in the answers like so:
<xsl:for-each select="//Component">
<!--Get sum of dispensed containers quantities if they exist in charged containers list-->
<xsl:key name="k1" match="//ChargeContainers/ChargeContainer" use="#BarcodeValue" />
<xsl:template match=".">
<result>
<xsl:variable name="TotalChargedQuantity" select = "sum(DispenseContainers/Container[key('k1', #BarcodeValue)]/#Quantity)"/>
</result>
</xsl:template>
<!--
Place holder for code to make table row with a bunch of info from nodelists of component
-->
<td>
<xsl:if test="$TotalChargeQuantity != number(#Quantity)">
<xsl:attribute name="style">background-color: red;</xsl:attribute>
</xsl:if>
</td>
</xsl:for-each>
however, I get an error stating that key can't be a child element of for-each. Is there a...loop friendly way of doing this?
Edit1: I'm going to rewrite the XML to be a bit closer to real as well as give a bit more context. The solution given is probably correct, but I'm getting an error that key can't be a child of for-each
Use a key to resolve cross-references - for example:
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:key name="k1" match="NodeList1/Node" use="#name" />
<xsl:template match="/Root">
<result>
<xsl:value-of select="sum(NodeList2/Node[key('k1', #name)]/#value)"/>
</result>
</xsl:template>
</xsl:stylesheet>
Added:
Your edited question is so different from the original, it should have been posted as a new one.
In order to limit the action of the key to the current Component node, you need to add a unique identifier of the current Component to the key:
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:key name="k1" match="ChargeContainer" use="concat(generate-id(ancestor::Component), '|', #BarcodeValue)" />
<xsl:template match="/Components">
<table>
<tr>
<th>Material Code</th>
<th>Your Result</th>
</tr>
<xsl:for-each select="Component">
<xsl:variable name="component-id" select="generate-id()" />
<tr>
<td>
<xsl:value-of select="#MaterialCode"/>
</td>
<td>
<xsl:value-of select="sum(DispenseContainers/Container[key('k1', concat($component-id, '|', #BarcodeValue))]/#Quantity)"/>
</td>
</tr>
</xsl:for-each>
</table>
</xsl:template>
</xsl:stylesheet>
Demo (using a well-formed (!) XML as the input): https://xsltfiddle.liberty-development.net/nb9PtDR

XSLT List attributes in the order they appear in the xml file

I have a large number of xml files with a structure similar to the following, although they are far larger:
<?xml version="1.0" encoding="UTF-8"?>
<a a1="3.0" a2="ABC">
<b b1="P1" b2="123">first
</b>
<b b1="P2" b2="456" b3="xyz">second
</b>
</a>
I want to get the following output:
1|1|b1
1|2|b2
2|1|b1
2|2|b2
2|3|b3
where:
Field 1 is the sequence number for nodes /a/b
Field 2 is the sequence number of the attribute as it appears in the xml file
Field 3 is the attribute name (not value)
I don't quite know how to calculate field 2 correctly.
I've prepared the following xslt file:
<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="#*|node()">
<xsl:copy>
<xsl:apply-templates select="#*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="/">
<xsl:for-each select="a/b/#*">
<xsl:value-of select="count(../preceding-sibling::*)+1"/>
<xsl:text>|</xsl:text>
<!-- TODO: This is not correct -->
<xsl:value-of select="count(preceding-sibling::*)+1"/>
<xsl:text>|</xsl:text>
<xsl:value-of select="name()"/>
<xsl:text>
</xsl:text>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
but when I run the following command:
xsltproc a.xslt a.xml > a.csv
I get an incorrect output, as field 2 does not represent the attribute sequence number:
1|1|b1
1|1|b2
2|1|b1
2|1|b2
2|1|b3
Do you have any suggestions on how to get the correct output please?
Please notice that the answers provided in XSLT to order attributes do not provide a solution to this problem.
The order of attributes is irrelevant in XML. For instance, <a a1="3.0" a2="ABC"> and <a a1="3.0" a2="ABC"> are equivalent.
However this specific question is part of a larger application where it is essential to establish the order in which attributes appear in given xml files (and not in xml files that are equivalent to them).
Although, as kjhughes says in comments, attribute order is insignificant. However, you can still select them, and use the position() element to get the numbers you are after (You just can't be sure the order they are output will be the order they appear in the XML, although generally this will be the case).
Try this XSLT. Do note the nested use of xsl:for-each to select only b elements first, to get their position, before getting the attributes, which then have their own separate position.
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" />
<xsl:template match="/">
<xsl:for-each select="a/b">
<xsl:variable name="bPosition" select="position()"/>
<xsl:for-each select="#*">
<xsl:value-of select="$bPosition"/>
<xsl:text>|</xsl:text>
<xsl:value-of select="position()"/>
<xsl:text>|</xsl:text>
<xsl:value-of select="name()"/>
<xsl:text>
</xsl:text>
</xsl:for-each>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
You could use the position() of the items in the sequence of attributes that you are iterating over and combine with logic for the position of its parent element.
<xsl:template match="/">
<xsl:for-each select="a/b/#*">
<xsl:value-of select="count(../preceding-sibling::*)+1"/>
<xsl:text>|</xsl:text>
<!-- TODO: This is not correct -->
<xsl:value-of select="position() -
(if (count(../preceding-sibling::*)) then count(../preceding-sibling::*)+1 else 0)"/>
<xsl:text>|</xsl:text>
<xsl:value-of select="name()"/>
<xsl:text>
</xsl:text>
</xsl:for-each>
</xsl:template>
Which produces the following output:
1|1|b1
1|2|b2
2|1|b1
2|2|b2
2|3|b3

xsl: when two nodes are equal, display child of first node

I'm using XML Editor 19.1, Saxon P.E 9.7.
For each selected div, I'm looking to display a graphic/#url, following each <surface> if surface/#xml:id = div/#facs.
XSL
<xsl:for-each select="descendant-or-self::div3[#type='col']/div4[#n]">
<xsl:variable name="div4tablet" select="#facs"/>
<xsl:choose>
<xsl:when test="translate(.[#n]/$div4tablet, '#', '') = preceding::facsimile/surfaceGrp[#type='tablet']/surface[#n]/#xml:id">
<xsl:value-of select=""/> <!-- DISPLAY graphic/#url that follows facsimile/surfaceGrp/surface -->
</xsl:when>
<xsl:otherwise/>
</xsl:choose>
[....]
</xsl:for-each>
TEI example
<facsimile>
<surfaceGrp n="1" type="tablet">
<surface n="1.1" xml:id="ktu1-2_i_1_to_10_img">
<graphic url="../img/KTU-1-2-1-10-recto.jpg"/>
<zone xml:id=""/>
<zone xml:id=""/>
</surface>
<surface n="1.2" xml:id="ktu1-2_i_10_to_30_img">
<graphic url="../img/KTU-1-2-10-30-recto.jpg"/>
<zone xml:id=""/>
</surface>
[...]
</surfaceGrp>
<surfaceGrp n="2">
[...]
</surfaceGrp>
</facsimile>
<text>
[...]
<div3 type="col">
<div4 n="1.2.1-10" xml:id="ktu1-2_i_1_to_10" facs="#ktu1-2_i_1_to_10_img">
[...]
</div4>
<div4 n="1.2.10-30" xml:id="ktu1-2_i_10_to_30" facs="#ktu1-2_i_10_to_30_img">
[...]
</div4>
</div3>
</text>
I have tried <xsl:value-of select="preceding::facsimile/surfaceGrp[#type='tablet']/surface[#n, #xml:id]/graphic/#url"/>, but it displays all graphic/#url and not only the one that follows fascsimile/surfaceGrp/surface.
So my question: how to display only surface/graphic/#url for each div3[#type='col']/div4[#n]?
In advance, thank you for your kind help.
As you use XSLT 2 or 3 and the elements have the xml:id attribute you do not even need a key but can use the id function:
<xsl:template match="div4">
<div>
<xsl:value-of select="id(substring(#facs, 2))/graphic/#url"/>
</div>
</xsl:template>
I put the use of id into a template matching the div4 element but you can of course use it the same way inside of your for-each selecting those elements.
See a minimal but complete sample at https://xsltfiddle.liberty-development.net/bdxtpR.
you should use xsl:key for this type of problem.
First, we must declare a key for the target node
<xsl:key name="kSurface" match="surface" use="concat('#', #xml:id)"/>
notice the concat function being used here, an # was being added to the xml:id so that the keys would appear as:
#ktu1-2_i_1_to_10_img
#ktu1-2_i_10_to_30_img
now in this loop:
<xsl:for-each select="descendant-or-self::div3[#type='col']/div4[#n]">
we can access the key that matches the #facs attribute by having:
<xsl:value-of select="key('kSurface', #facs)/graphic/#url"/>
The whole stylesheet is below:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs"
version="1.0">
<xsl:output omit-xml-declaration="yes"/>
<xsl:key name="kSurface" match="surface" use="concat('#', #xml:id)"/>
<xsl:template match="/">
<xsl:for-each select="descendant-or-self::div3[#type='col']/div4[#n]">
<xsl:value-of select="key('kSurface', #facs)/graphic/#url"/>
<xsl:text>
</xsl:text>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
see it in action here.

Setting disable-output-escaping="yes" for every xsl:text tag in the xml

say I have the following xml:
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/*">
<display>
<xsl:for-each select="logline_t">
<xsl:text disable-output-escaping="yes"><</xsl:text> <xsl:value-of select="./line_1" <xsl:text disable-output-escaping="yes">></xsl:text>
<xsl:text disable-output-escaping="yes"><</xsl:text> <xsl:value-of select="./line_2" <xsl:text disable-output-escaping="yes">></xsl:text>
<xsl:text disable-output-escaping="yes"><</xsl:text> <xsl:value-of select="./line_3" <xsl:text disable-output-escaping="yes">></xsl:text>
</xsl:for-each>
</display>
</xsl:template>
</xsl:stylesheet>
Is there a way to set disable-output-escaping="yes" to all of the xsl:text that appear in the document?
I know there is an option to put
< xsl:output method="text"/ >
and every time something like
& lt;
appears, a < will appear, but the thing is that sometimes in the values of line_1, line_2 or line_3, there is a "$lt;" that I don't want changed (this is, I only need whatever is between to be changed)
This is what I'm trying to accomplish. I have this xml:
<readlog_l>
<logline_t>
<hora>16:01:09</hora>
<texto>Call-ID: 663903<hola>396#127.0.0.1</texto>
</logline_t>
</readlog_l>
And this translation:
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/*">
<display>
<screen name="<xsl:value-of select="name(.)"/>">
<xsl:for-each select="logline_t">
< field name="<xsl:for-each select="*"><xsl:value-of select="."/></xsl:for-each>" value="" type="label"/>
</xsl:for-each>
</screen>
</display>
</xsl:template>
</xsl:stylesheet>
I want this to be the output:
<?xml version="1.0"?>
<display>
<screen name="readlog_l">
<field name="16:01:09 Call-ID: 663903<hola>396#127.0.0.1 " value="" type="label">
</screen>
</display>
Note that I need the "<" inside the field name not to be escaped, this is why I can't use output method text.
Also, note that this is an example and the translations are much bigger, so this is why I'm trying to find out how not to write disable-output-escaping for every '<' or '>' I need.
Thanks!
Thanks for clarifying the question. In this case, I'm fairly sure there's no need to disable output escaping. XSLT was designed to accomplish what you're doing:
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/*">
<display>
<screen name="{name(.)}">
<xsl:for-each select="logline_t">
<xsl:variable name="nameContent">
<xsl:for-each select="*">
<xsl:if test="position() > 1"><xsl:text> </xsl:text></xsl:if>
<xsl:value-of select="."/>
</xsl:for-each>
</xsl:variable>
<field name="{$nameContent}" value="" type="label" />
</xsl:for-each>
</screen>
</display>
</xsl:template>
</xsl:stylesheet>
I'm a bit unclear on this point:
Note that I need the "<" inside the field name not to be escaped, this is why I can't use output method text.
Which < are you referring to? Is it the < and > around "hola"? If you left those unescaped you would wind up with invalid XML. It also looks like the name attribute in your sample output have a lot of values that aren't in the input XML. Where did those come from?
Given your expected output you don't need d-o-e at all for this. Here is a possible solution that doesn't use d-o-e, and is based on templates rather than for-each:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes" />
<xsl:template match="/*">
<display>
<screen name="{name(.)}">
<xsl:apply-templates select="logline_t"/>
</screen>
</display>
</xsl:template>
<xsl:template match="logline_t">
<field value="" type="label">
<xsl:attribute name="name">
<xsl:apply-templates select="*" mode="fieldvalue"/>
</xsl:attribute>
</field>
</xsl:template>
<xsl:template match="*[last()]" mode="fieldvalue">
<xsl:value-of select="." />
</xsl:template>
<xsl:template match="*" mode="fieldvalue">
<xsl:value-of select="." />
<xsl:text> </xsl:text>
</xsl:template>
</xsl:stylesheet>
If you want to set d-o-e on everything, that suggests you are trying to generate markup "by hand". I don't think that's a particularly good idea (in fact, I think it's a lousy idea), but if it's what you want to do, I would suggest using the text output method instead of the xml output method. That way, no escaping of special characters takes place, and therefore it doesn't need to be disabled.

How to apply an XSLT transformation that includes spaces to an XML doc using tDOM?

I have some XML of the form:
<definitions devices="myDevice">
<reg offset="0x0000" mnem="someRegister">
<field mnem="someField" msb="31" lsb="24 />
...
</reg>
...
</definitions>
I want the XML to be the definitive reference and use XSLT to transform it to HTML for documentation, .h for building (and maybe other forms too).
The HTML version is working fine and produces a table per register, with a row per field:
... (header boilerplate removed)
<xsl:for-each select="definitions/reg">
<table>
<tr>
<th><xsl:value-of select="#offset"/></th>
<th><xsl:value-of select="#mnem"/></th>
</tr>
<xsl:for-each select="field">
<tr>
<td><xsl:value-of select="#msb"/>..<xsl:value-of select="#lsb"/></td>
<td><xsl:value-of select="#mnem"/></td>
</tr>
</xsl:for-each>
</table>
</xsl:for-each>
Converting to a .h isn't going so well. I'm completely failing to generate the required spaces in the output:
<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<xsl:for-each select="definitions/reg">
#define <xsl:value-of select="translate(#mnem,'abcdefghijklmnopqrstuvwxyz','ABCDEFGHIJKLMNOPQRSTUVWXYZ')"/>
<xsl:text> </xsl:text>
<xsl:value-of select="#offset"/>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
I'd hope for that to produce the output:
#define SOMEREGISTER 0x0000
But I actually get:
#define SOMEREGISTER0x0000
I don't understand why I get the space after the '#define', but not the one after the transformed mnemonic. I've tried a simpler solution with just an inline space, with the same results.
I'm too new to this (XSLT) to know whether I'm a) doing it wrong or b) finding a limitation in tDOM.
Testing with this:
# I could have read these from a file I suppose...
set in {<definitions devices="myDevice">
<reg offset="0x0000" mnem="someRegister">
<field mnem="someField" msb="31" lsb="24" />
</reg>
</definitions>}
set ss {<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<xsl:for-each select="definitions/reg">
<xsl:text>#define </xsl:text>
<xsl:value-of select="translate(#mnem,'abcdefghijklmnopqrstuvwxyz','ABCDEFGHIJKLMNOPQRSTUVWXYZ')"/>
<xsl:text xml:space="preserve"> </xsl:text>
<xsl:value-of select="#offset"/>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>}
# Interesting code starts here
package require tdom
set indoc [dom parse $in]
set xslt [dom parse -keepEmpties $ss]
set outdoc [$indoc xslt $xslt]
puts [$outdoc asText]
I find that this works. The issue is that the tDOM parser doesn't handle the xml:space attribute correctly; without the magical -keepEmpties option, all the empty strings are stripped from the stylesheet and that leads to a wrong XSLT stylesheet being applied. But with the option, it appears to do the right thing.
Note that the XSLT engine itself is doing the right thing. It's the XML parser/DOM builder. (I think it's a bug; I'll look up where to report it.)
Per:
http://www.ibm.com/developerworks/xml/library/x-tipwhitesp/index.html
Try using the preserve space directive:
<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<xsl:for-each select="definitions/reg">
<xsl:text xml:space="preserve">#define </xsl:text>
<xsl:value-of select="translate(#mnem,'abcdefghijklmnopqrstuvwxyz','ABCDEFGHIJKLMNOPQRSTUVWXYZ')"/>
<xsl:text xml:space="preserve"> </xsl:text>
<xsl:value-of select="#offset"/>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
You don't have an output method specified in your second stylesheet, so the default is gonna be XML. I'd advice you to use output method "text", then use <xsl:text> elements for any literal output. Check this example:
<?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="/">
<xsl:for-each select="definitions/reg"><xsl:text>#define </xsl:text><xsl:value-of select="translate(#mnem,'abcdefghijklmnopqrstuvwxyz','ABCDEFGHIJKLMNOPQRSTUVWXYZ')"/><xsl:text> </xsl:text><xsl:value-of select="#offset"/><xsl:text>
</xsl:text>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
EDIT: by the way, that
at the end is a character code. It's simply the decimal value of the ASCII code for a line feed. This makes sure you start a new line for the next reg entry. If you need the Windows/DOS convention (carriage return + line feed), use
instead.