将<br/>标签添加到XML,然后通过XSL显示

时间:2014-07-27 22:29:04

标签: html xml xslt

我正在使用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标签将评估分数放在两行......

2 个答案:

答案 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。如果你不熟悉命名空间,那就行得通 请注意这些是不同的方法,不要混淆它们,而是知道你做了什么。