我正在使用SimpleXMLElement编写XML文件,但我无法使我的br标签生效。输出的XML是:
<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="scoreboard.xsl"?>
<scoreboard scoreboard_title="Scoreboard for: (lesson) a/an">
<header>
<item>User name</item>
<item>Assessment</item>
</header>
<rows>
<row>
<item><![CDATA[mega blue]]></item>
<item><![CDATA[03/03/14: 20% (21.02 sec)<br />07/03/14: 100% (42.56 sec)]]></item>
</row>
</rows>
</scoreboard>
我的XSL文件是:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="html" />
<xsl:template match="/">
<html>
<body>
<xsl:for-each select="scoreboard">
<table width="100%" border="0" align="center" cellpadding="0" cellspacing="0">
<thead>
<tr>
<xsl:for-each select="header/item">
<th align="left">
<xsl:value-of select="." />
</th>
</xsl:for-each>
</tr>
</thead>
<tbody>
<xsl:for-each select="rows/row">
<tr>
<xsl:for-each select="item">
<td align="left">
<xsl:value-of select="." />
</td>
</xsl:for-each>
</tr>
</xsl:for-each>
</tbody>
</table>
</xsl:for-each>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
但我得到了我的输出:
User name Assessment
mega blue Spanish 03/03/14: 20% (21.02 sec)<br />07/03/14: 100% (42.56 sec)
我需要br标签将评估分数放在两行......
答案 0 :(得分:0)
样式表中的深度嵌套非常不灵活。每当您发现自己编写xsl:for-each
时,请考虑将其替换为xsl:apply-templates
,这将为您现在和将来节省许多麻烦:基于模板的处理,这是XSLT的全部内容,而不是告诉处理器需要如何完成,只需告诉处理器遇到某个节点时你想做什么。
我已经重写了你的样式表。现在它更易读,更容易理解。另外,我向相应的disable-output-escaping="yes"
添加了必要的xsl:value-of
。这适用于我尝试的所有处理器。但是在浏览器中,这并不总是有效,因为这个disable-output-escaping的实际定义与序列化有关,而这与浏览器不同。唯一忽略这一事实的浏览器(实际上是你想做的事情)并将<br />
解释为换行符是Internet Explorer(错误地说,它们适合你;)。
这是样式表。在服务器端处理它,这样您就不必处理浏览器怪癖,您将获得所需的输出:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="html" />
<xsl:template match="/">
<html>
<body>
<xsl:apply-templates select="scoreboard" />
</body>
</html>
</xsl:template>
<xsl:template match="scoreboard">
<table width="100%" border="0" align="center" cellpadding="0" cellspacing="0">
<thead>
<tr>
<xsl:apply-templates select="header/item" />
</tr>
</thead>
<tbody>
<xsl:apply-templates select="rows/row" />
</tbody>
</table>
</xsl:template>
<xsl:template match="header/item">
<th align="left">
<xsl:value-of select="." />
</th>
</xsl:template>
<xsl:template match="rows/row">
<tr>
<xsl:apply-templates select="item" />
</tr>
</xsl:template>
<xsl:template match="item">
<td align="left">
<xsl:value-of select="." disable-output-escaping="yes" />
</td>
</xsl:template>
</xsl:stylesheet>
您将在输入中输出以下内容:
<html>
<body>
<table width="100%" border="0" align="center" cellpadding="0" cellspacing="0">
<thead>
<tr>
<th align="left">User name</th>
<th align="left">Assessment</th>
</tr>
</thead>
<tbody>
<tr>
<td align="left">mega blue</td>
<td align="left">03/03/14: 20% (21.02 sec)<br />07/03/14: 100% (42.56 sec)</td>
</tr>
</tbody>
</table>
</body>
</html>
或者,根据您的问题发表上一条评论后,如果您可以在源文件中进行修改,请将<td>
拆分为多个文本节点,并在其间放置<br />
。然后,在匹配模板中,将xsl:value-of
更改为xsl:copy-of
,即更改最后一个模板,如下所示:
<xsl:template match="item">
<td align="left">
<xsl:copy-of select="." />
</td>
</xsl:template>
请注意,为此,请确保您的输入如下所示:
<item>03/03/14: 20% (21.02 sec)<br />07/03/14: 100% (42.56 sec)</item>
答案 1 :(得分:0)
有不同的方法可以实现这一目标:
1.告诉转换引擎输出而不转义(disable-output-escaping =&#34; yes&#34;)。这可能会破坏您的输出,因为输入不会被解析并且可能包含错误。
2.使用xml元素触发中断。您甚至可以将其命名为&lt; br /&gt;,但它必须位于xml元素树中,而不是CDATA内部。请注意&lt; br /&gt;添加到xml文件中的标记不会被识别为html元素。您可以根据需要自由命名元素,甚至可以使用html中已知的名称,但它们不会自动成为html。如果您希望将它们添加到输出中,则必须在模板中对其进行编码,就像编写&#34;项目&#34;应存在于&#34; td&#34;元素。
3.如果你的大部分商品都包含休息时间,甚至可能超过一个,那么将&#34;项目&#34;分开是很有用的。元素进入&#34;线&#34;元素并输出它们,例如as&#34; div&#34;或添加&#34; br&#34;在每条&#34;线前面#34;这不是第一个(需要xpath)。
4.使用html风格命名的元素并将它们复制到输出中(xsl:copy-of,由Abel提及)。通过复制,它们成为输出树的一部分,即html。如果你不熟悉命名空间,那就行得通
请注意这些是不同的方法,不要混淆它们,而是知道你做了什么。