【问题标题】:How to modify XSL to insert <BR> from XML如何修改 XSL 以从 XML 插入 <BR>
【发布时间】:2019-02-22 04:32:08
【问题描述】:

我一直在做很多工作,试图弄清楚如何使用样式表查看 XML 文件(在 Internet Explorer 上),并保留文档中的回车符/换行符。

我确实让它工作了,但不想在我的 XML 文件中使用大量带有 [br/] 的 CDATA。我希望在 XML 文本文件中使用保存的回车。

我看到了其他示例,例如:how to convert NEWLINE into <BR/> with XSLT?,但我不太擅长 XML/XSL,不知道如何使其正常工作。我所做的一切都放置了一个“<br/>”或 CR/LF 但不是浏览器可以理解的


XSL 文件:

<?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="/">
    <html>
        <body style="font-family:verdana;">
            <h2>Example</h2>

            <table border="1" bordercolor="#000000" cellspacing="0">
                <tr bgcolor="#000000" style="color:#FFFFFF;text-align:left;font-size:80%">
                    <th>#</th>
                    <th>Has <![CDATA["CDATA[<br/>]"]]> (It Works)</th>
                    <th>Has <![CDATA["&#xA;"]]> (Want this one as worst case)</th>
                    <th>Has Carriage Return (Want this one to work)</th>
                </tr> 

                <xsl:for-each select="report/test">
                    <tr style="text-align:left;font-size:80%">
                        <xsl:choose>
                            <xsl:when test="@type = 'append_text'">
                                <td><b><xsl:value-of select="text"/></b></td>
                            </xsl:when>
                            <xsl:when test="@type = 'test_step'">                   
                                <td id="ref{num}"><xsl:value-of select="num"/></td>

                                <td><xsl:value-of select="hasBR" disable-output-escaping="yes"/></td>
                                <td><xsl:value-of select="hasXA" disable-output-escaping="yes"/></td>
                                <td><xsl:value-of select="hasCR" disable-output-escaping="yes"/></td>

                            </xsl:when>
                        </xsl:choose>
                    </tr>
                </xsl:for-each>

            </table>


        </body>
    </html>
</xsl:template>

</xsl:stylesheet>

XML 文件:

<?xml version="1.0" encoding="ISO-8859-1"?>
<?xml-stylesheet type="text/xsl" href="51380-200.xsl"?>
    <report>

        <test type="test_step">
            <num>1</num>
            <hasXA>Line 1 &#xA; Line 2 &#xA; Line 3</hasXA>
            <hasBR>Line 1 <![CDATA[<br/>]]> Line 2 <![CDATA[<br/>]]> Line 3</hasBR>
            <hasCR>Line 1
            Line2
            Line3</hasCR>
        </test>

        <test type="test_step">
            <num>2</num>
            <hasXA>Line 1 &#xA; Line 2 &#xA; Line 3</hasXA>
            <hasBR>Line 1 <![CDATA[<br/>]]> Line 2 <![CDATA[<br/>]]> Line 3</hasBR>
            <hasCR>Line 1
            Line2
            Line3</hasCR>
        </test>

        <test type="test_step">
            <num>3</num>
            <hasXA>Line 1 &#xA; Line 2 &#xA; Line 3</hasXA>
            <hasBR>Line 1 <![CDATA[<br/>]]> Line 2 <![CDATA[<br/>]]> Line 3</hasBR>
            <hasCR>Line 1
            Line2
            Line3</hasCR>
        </test>

    </report>

非常感谢您的帮助!

注意,我一直在使用 XSL transform.net 来尝试使其工作。我在上面加载了它的一个版本。 http://xsltransform.net/bESZULX

【问题讨论】:


  • 不是有效的 XML,但
    是 .我在整个程序中使用
    没有问题。

标签: xml xslt


【解决方案1】:

假设您可能想要这样的东西:

<?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="/">
    <html>
        <body style="font-family:verdana;">
            <h2>Example</h2>

            <table border="1" bordercolor="#000000" cellspacing="0">
                <tr bgcolor="#000000" style="color:#FFFFFF;text-align:left;font-size:80%">
                    <th>#</th>
                    <th>Has <![CDATA["CDATA[<br/>]"]]> (It Works)</th>
                    <th>Has <![CDATA["&#xA;"]]> (Want this one as worst case)</th>
                    <th>Has Carriage Return (Want this one to work)</th>
                </tr> 

                <xsl:for-each select="report/test">
                    <tr style="text-align:left;font-size:80%">
                        <xsl:choose>
                            <xsl:when test="@type = 'append_text'">
                                <td><b><xsl:value-of select="text"/></b></td>
                            </xsl:when>
                            <xsl:when test="@type = 'test_step'">                   
                                <td id="ref{num}"><xsl:value-of select="num"/></td>

                                <td><xsl:value-of select="hasBR" disable-output-escaping="yes"/></td>
                                <td><xsl:value-of select="hasXA" disable-output-escaping="yes"/></td>
                                <td>
                                    <xsl:call-template name="insertBreaks">
                                        <xsl:with-param name="pText" select="hasCR" />
                                    </xsl:call-template>
                                </td>
                            </xsl:when>
                        </xsl:choose>
                    </tr>
                </xsl:for-each>
            </table>
        </body>
    </html>
</xsl:template>

<xsl:template match="hasCR" name="insertBreaks">
    <xsl:param name="pText" select="." />

    <xsl:choose>
        <xsl:when test="not(contains($pText, '&#xA;'))">
            <xsl:copy-of select="$pText" />
        </xsl:when>
        <xsl:otherwise>
            <xsl:value-of select="substring-before($pText, '&#xA;')" />
            <br />
            <xsl:call-template name="insertBreaks">
                <xsl:with-param name="pText" select="substring-after($pText, '&#xA;')" />
            </xsl:call-template>
        </xsl:otherwise>
    </xsl:choose>
</xsl:template>

</xsl:stylesheet>

http://xsltransform.net/eieE3PZ

【讨论】:

  • 这看起来就像我想要的那样。我将不得不处理我实际的 XSL 文件,该文件实际上比我发布的文件要大得多。 (希望保持简单以找到解决方案)。再次感谢您的帮助!
  • 那么从你的例子来看,我需要为每个模板制作一个模板(即insertBreaks)吗?例如,如果“hasXA”实际上有像“hasCR”这样的carrage return,我需要制作一个针对“hasXA”的新模板“insertBreaks2”?我只是尝试制作一个并且它有效,但想知道是否有更简单的方法可以做到这一点,因为我有多个列我想执行此功能。谢谢。
  • 没有。那是不需要的。您可以在同一个中匹配多个节点。例如。 ''
  • 我在玩它,我不能只删除模板匹配,即将&lt;xsl:template match="hasCR" name="insertBreaks"&gt; 更改为&lt;xsl:template name="insertBreaks"&gt;。然后通过以下方式调用它:&lt;xsl:call-template name="insertBreaks"&gt;&lt;xsl:with-param name="pText" select="hasXA" /&gt;?当我尝试它时,它似乎有效。
【解决方案2】:

让我们拆分问题。

输出

您正在生成 HTML。它有自己的关于在渲染时保留换行符的规则:在 td 元素内,您需要一个 br 元素。

输入

您有一个 XML 文档。没有什么禁止您使用混合内容。示例:

<hasBR>Line 1 <br />Line 2 <br />Line 3</hasBR> 

转型

如果您不打算对混合内容执行任何其他处理,最好的解决方案就是复制该内容。所以,而不是

<td><xsl:value-of select="hasBR" disable-output-escaping="yes"/></td>

... 使用xsl:copy-of 类似指令

<td><xsl:copy-of select="hasBR/node()"/></td>

注意:如果您使用identity transformation 模式,则可以继续处理您的混合内容。在混合两个 XML 词汇表时,还必须非常小心命名空间。

最后,如果您的 XML 输入文档无法从混合内容中受益,那么您始终可以使用递归模板来处理您的字符串值,例如 @Vebbie 答案。对于较新版本的 XSLT,有更好的解决方案。

【讨论】:

  • 我正在寻找 hasCR 的解决方案。维比似乎有一个适合我的。由于我对 XML XSL 的东西非常陌生,所以我试图弄清楚这一点。如果有更好的方法,我很想听听。
  • @Rhidium 对于较新版本的 XSLT,有更好的方法。我回答了你的问题,因为我想强调没有充分的理由不使用混合内容:如果你可以序列化一个 xA 字符,你也可以序列化一个元素 &lt;br/&gt;
猜你喜欢
  • 2011-02-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-11-21
  • 2016-01-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多