Как изменить XSL для вставки <BR> из XML

Я проделал большую работу, пытаясь выяснить, как просмотреть файл XML (в Internet Explorer), используя таблицу стилей, и сохранить возврат каретки / перевод строки из документа.

Я заставил это работать, но не хотел использовать тонны CDATA с [br/] по всему файлу XML. Я надеялся использовать сохраненные возвраты каретки в текстовом файле XML.

Я видел другие примеры, такие как этот: как конвертировать NEWLINE в
с помощью XSLT?
но я не очень хорош в XML/XSL и не могу понять, как заставить его работать правильно. Все, что я делал, было помещено как "& lt;br/& gt;" или 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

2 ответа

Решение

Предполагается, что вы можете захотеть что-то вроде этого:

<?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

Давайте разделим проблему.

Выход

Вы производите 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>

Примечание. Возможно продолжить обработку смешанного контента, если вы используете шаблон преобразования идентификаторов. Смешивая два словаря XML, вы также должны быть очень осторожны с пространствами имен.

Наконец, если ваш входной XML-документ не может использовать смешанный контент, вы всегда можете использовать рекурсивный шаблон для обработки строкового значения, такого как @Vebbie answer. Для более новых версий XSLT есть лучшие решения.

Другие вопросы по тегам