Reputation: 2081
I need control over the output of an XSL transformation process in terms of (not) setting newlines before certain result elements. Take this input
<text>
<line>My text uses <hi>highlighting</hi> methods</line>
<line>Next line uses <hi>two </hi><hi>highlighter</hi> elements...</line>
</text>
transformed by this simple stylesheet:
<?xml version="1.0" encoding="utf-8"?>
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:output indent="yes" method="xml"/>
<xsl:template match="line">
<p>
<xsl:apply-templates/>
</p>
</xsl:template>
<xsl:template match="hi">
<span>
<xsl:apply-templates/>
</span>
</xsl:template>
</xsl:transform>
The undesirable result of the transformation is:
<p>My text uses <span>highlighting</span> methods</p>
<p>Next line uses <span>two </span>
<span>highlighter</span> elements...</p>
The second <span>
within <p>
produces a newline, which is not what I want.
What's the reason for this behaviour and how to avoid it, meaning: how to achieve this result:
<p>My text uses <span>highlighting</span> methods</p>
<p>Next line uses <span>two </span><span>highlighter</span> elements...</p>
(Yes, I need <xsl:output indent="yes">
and the transformation method has to be "xml".)
Upvotes: 1
Views: 506
Reputation: 122364
The only way I can see to get around this with the constraints you specify in the last line of your question (method="xml"
and indent="yes"
) is to add xml:space="preserve"
to the p
elements you create, as
Whitespace characters MUST NOT be inserted in a part of the result document that is controlled by an
xml:space
attribute with valuepreserve
.
(Source)
<?xml version="1.0" encoding="utf-8"?>
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:output indent="yes" method="xml"/>
<xsl:template match="line">
<p xml:space="preserve"><xsl:apply-templates/></p>
</xsl:template>
<xsl:template match="hi">
<span>
<xsl:apply-templates/>
</span>
</xsl:template>
</xsl:transform>
Note that because of the xml:space="preserve"
you also have to remove the whitespace between the opening and closing tags of the p
element and the child xsl:apply-templates
. When run on your example input using Saxon 9 HE this produces the output
<?xml version="1.0" encoding="UTF-8"?>
<p xml:space="preserve">My text uses <span>highlighting</span> methods</p>
<p xml:space="preserve">Next line uses <span>two </span><span>highlighter</span> elements...</p>
If you could instead use the xhtml
output method (and the XHTML namespace) then the XHTML indenter is not allowed to add space around tags that start or end elements that XHTML specifies to be "inline" markup, and this includes span
.
<?xml version="1.0" encoding="utf-8"?>
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0"
xmlns="http://www.w3.org/1999/xhtml">
<xsl:output indent="yes" method="xhtml"/>
<xsl:template match="/">
<html><body><xsl:apply-templates/></body></html>
</xsl:template>
<xsl:template match="line">
<p>
<xsl:apply-templates/>
</p>
</xsl:template>
<xsl:template match="hi">
<span>
<xsl:apply-templates/>
</span>
</xsl:template>
</xsl:transform>
when run on the same input would produce
<?xml version="1.0" encoding="UTF-8"?><html xmlns="http://www.w3.org/1999/xhtml">
<body>
<p>My text uses <span>highlighting</span> methods
</p>
<p>Next line uses <span>two </span><span>highlighter</span> elements...
</p>
</body>
</html>
without space between the two span
elements.
Upvotes: 4