Визуализировать экранированный XML в браузере - PullRequest
2 голосов
/ 20 июля 2010

Для приведенного ниже XML я хочу визуализировать неэкранированные части текста в браузере из xslt, например:

<one>
&lt;text&gt;
</one>

Я хочу, чтобы разметка в браузере была:когда я использую шаблоны применения, которые выглядят следующим образом:

<xsl:template match="text()" mode="literalHTML">
    <xsl:copy-of select=".">
    </xsl:copy-of>
</xsl:template>

Приведенный выше XML отображается как:

<text>

Как изменить этот шаблон так, чтобы он печатал браузер?

С наилучшими пожеланиями, Кешав

Ответы [ 3 ]

2 голосов
/ 20 июля 2010

«Хитрая рекурсивная обработка»

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" omit-xml-declaration="yes"/>
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>
    <xsl:template match="text()" name="text">
        <xsl:param name="text" select="."/>
        <xsl:if test="$text != ''">
            <xsl:variable name="first" select="substring($text,1,1)"/>
            <xsl:choose>
                <xsl:when test="$first = '&lt;'">&amp;lt;</xsl:when>
                <xsl:when test="$first = '&gt;'">&amp;gt;</xsl:when>
                <xsl:otherwise>
                    <xsl:value-of select="$first"/>
                </xsl:otherwise>
            </xsl:choose>
            <xsl:call-template name="text">
                <xsl:with-param name="text" select="substring($text,2,(string-length($text)-1) div 2 + 1)"/>
            </xsl:call-template>
            <xsl:call-template name="text">
                <xsl:with-param name="text" select="substring($text,(string-length($text)-1) div 2 + 3)"/>
            </xsl:call-template>
        </xsl:if>
    </xsl:template>
</xsl:stylesheet>

Результат:

<one>
&amp;lt;text&amp;gt;
</one>

РЕДАКТИРОВАТЬ : шаблон DVC во избежание переполнения.

2 голосов
/ 20 июля 2010

Этого можно добиться в XSLT 1.0 с помощью довольно сложной рекурсивной обработки.

К счастью, можно использовать FXSL (библиотека шаблонов XSLT) для решенията же задача всего за несколько минут:

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:f="http://fxsl.sf.net/"
xmlns:testmap="testmap"
exclude-result-prefixes="xsl f testmap">
   <xsl:import href="str-dvc-map.xsl"/>

   <testmap:testmap/>

   <xsl:output omit-xml-declaration="yes" indent="yes"/>

   <xsl:template match="/">
     <xsl:variable name="vTestMap" select="document('')/*/testmap:*[1]"/>
     <xsl:call-template name="str-map">
       <xsl:with-param name="pFun" select="$vTestMap"/>
       <xsl:with-param name="pStr" select="/*/text()"/>
     </xsl:call-template>
   </xsl:template>

    <xsl:template name="escape" mode="f:FXSL"
     match="*[namespace-uri() = 'testmap']">
      <xsl:param name="arg1"/>

      <xsl:choose>
       <xsl:when test="$arg1 = '&lt;'">&amp;lt;</xsl:when>
       <xsl:when test="$arg1 = '&gt;'">&amp;gt;</xsl:when>
       <xsl:otherwise><xsl:value-of select="$arg1"/></xsl:otherwise>
      </xsl:choose>
    </xsl:template>

</xsl:stylesheet>

когда это преобразование применяется к следующему документу XML :

<one>
&lt;text&gt;
</one>

желаемый результатпроизводится :

&amp;lt;text&amp;gt;

и отображается в браузере как : &lt;text&gt;

0 голосов
/ 20 июля 2010

Я также написал решение с использованием рекурсии ранее, но меня беспокоило только производительность, и если из-за этого будет какая-то память или какой-то стекопоток.Мне было интересно, будет ли какое-либо решение с использованиемили же?Также, пожалуйста, дайте мне знать, есть ли какие-либо улучшения в приведенном ниже решении, если рекурсия может быть преобразована в цикл и т. Д.

<xsl:template match="text()" mode="literalHTML">
    <xsl:variable name="txt" select="."/>
    <xsl:value-of select="smc:escapeChar(smc:escapeChar(smc:escapeChar($txt,'&amp;','&amp;amp;'),'&lt;','&amp;lt;'),'&gt;','&amp;gt;')"/>
</xsl:template>
<xsl:function name="smc:escapeChar">
    <xsl:param name="txt"/>
    <xsl:param name="char"/>
    <xsl:param name="subs"/>
    <xsl:result>
        <xsl:variable name="result">
            <xsl:choose>
                <xsl:when test="contains($txt, $char)">
                    <xsl:variable name="after" select="substring-after($txt,$char)"/>
                    <xsl:value-of select="substring-before($txt,$char)"/>
                    <xsl:value-of select="$subs"/>
                    <xsl:value-of select="smc:escapeChar($after,$char,$subs)"/>
                </xsl:when>
                <xsl:otherwise>
                    <xsl:value-of select="$txt"/>
                </xsl:otherwise>
            </xsl:choose>
        </xsl:variable>
        <xsl:value-of select="$result"></xsl:value-of>
        </xsl:result>
</xsl:function>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...