Producing a new line in XSLT

2019-01-03 12:34发布

I want to produce a newline for text output in XSLT. Any ideas?

标签: xslt
12条回答
爱情/是我丢掉的垃圾
2楼-- · 2019-01-03 13:22

just add this tag:

<br/>

it works for me ;) .

查看更多
干净又极端
3楼-- · 2019-01-03 13:28

I added the DOCTYPE directive you see here:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE xsl:stylesheet [
  <!ENTITY nl "&#xa;">
]>
<xsl:stylesheet xmlns:x="http://www.w3.org/2005/02/query-test-XQTSCatalog"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                version="2.0">

This allows me to use &nl; instead of &#xa; to produce a newline in the output. Like other solutions, this is typically placed inside a <xsl:text> tag.

查看更多
Rolldiameter
4楼-- · 2019-01-03 13:29

I have found a difference between literal newlines in <xsl:text> and literal newlines using &#xA;.

While literal newlines worked fine in my environment (using both Saxon and the default Java XSLT processor) my code failed when it was executed by another group running in a .NET environment.

Changing to entities (&#xA;) got my file generation code running consistently on both Java and .NET.

Also, literal newlines are vulnerable to being reformatted by IDEs and can inadvertently get lost when the file is maintained by someone 'not in the know'.

查看更多
Explosion°爆炸
5楼-- · 2019-01-03 13:32

You can use: <xsl:text>&#10;</xsl:text>

see the example

<xsl:variable name="module-info">
  <xsl:value-of select="@name" /> = <xsl:value-of select="@rev" />
  <xsl:text>&#10;</xsl:text>
</xsl:variable>

if you write this in file e.g.

<redirect:write file="temp.prop" append="true">
  <xsl:value-of select="$module-info" />
</redirect:write>

this variable will produce a new line infile as:

commons-dbcp_commons-dbcp = 1.2.2
junit_junit = 4.4
org.easymock_easymock = 2.4
查看更多
狗以群分
6楼-- · 2019-01-03 13:32

IMHO no more info than @Florjon gave is needed. Maybe some small details are left to understand why it might not work for us sometimes.

First of all, the &#xa (hex) or &#10 (dec) inside a <xsl:text/> will always work, but you may not see it.

  1. There is no newline in a HTML markup. Using a simple <br/> will do fine. Otherwise you'll see a white space. Viewing the source from the browser will tell you what really happened. However, there are cases you expect this behaviour, especially if the consumer is not directly a browser. For instance, you want to create an HTML page and view its structure formatted nicely with empty lines and idents before serving it to the browser.
  2. Remember where you need to use disable-output-escaping and where you don't. Take the following example where I had to create an xml from another and declare its DTD from a stylesheet.

The first version does escape the characters (default for xsl:text)

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:output method="xml" indent="yes" encoding="utf-8"/>

    <xsl:template match="/">
        <xsl:text>&lt;!DOCTYPE Subscriptions SYSTEM "Subscriptions.dtd"&gt;&#xa;&#xa;&#xd;</xsl:text>
        <xsl:copy>
            <xsl:apply-templates select="*" mode="copy"/>
        </xsl:copy>
    </xsl:template>
    <xsl:template match="@*|node()" mode="copy">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()" mode="copy"/>
        </xsl:copy>
    </xsl:template>

</xsl:stylesheet>

and here is the result:

<?xml version="1.0" encoding="utf-8"?>
&lt;!DOCTYPE Subscriptions SYSTEM "Subscriptions.dtd"&gt;

&#13;<Subscriptions>
    <User id="1"/>   
</Subscriptions>

Ok, it does what we expect, escaping is done so that the characters we used are displayed properly. The XML part formatting inside the root node is handled by ident="yes". But with a closer look we see that the newline character &#xa was not escaped and translated as is, performing a double linefeed! I don't have an explanation on this, will be good to know. Anyone?

The second version does not escape the characters so they're producing what they're meant for. The change made was:

<xsl:text disable-output-escaping="yes">&lt;!DOCTYPE Subscriptions SYSTEM "Subscriptions.dtd"&gt;&#xa;&#xa;&#xd;</xsl:text>

and here is the result:

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE Subscriptions SYSTEM "Subscriptions.dtd">

<Subscriptions>
    <User id="1"/>   
</Subscriptions>

and that will be ok. Both cr and lf are properly rendered.

  1. Don't forget we're talking about nl, not crlf (nl=lf). My first attempt was to use only cr:&#xd and while the output xml was validated by DOM properly.

I was viewing a corrupted xml:

<?xml version="1.0" encoding="utf-8"?>
<Subscriptions>riptions SYSTEM "Subscriptions.dtd">
    <User id="1"/>   
</Subscriptions>

DOM parser disregarded control characters but the rendered didn't. I spent quite some time bumping my head before I realised how silly I was not seeing this!

For the record, I do use a variable inside the body with both CRLF just to be 100% sure it will work everywhere.

查看更多
够拽才男人
7楼-- · 2019-01-03 13:35

Include the attribute Method="text" on the xsl:output tag and include newlines in your literal content in the XSL at the appropriate points. If you prefer to keep the source code of your XSL tidy use the entity &#10; where you want a new line.

查看更多
登录 后发表回答