2009-03-14 2 views
8

Я пишу это, потому что я действительно ударил стену и не могу идти вперед. В моей базе данных я сбежал с HTML следующим образом: "<p>My name is Freddy and I was".Проблема с побегом персонажа XSL

Я хочу показать это как HTML или разбить теги HTML в моем XSL-шаблоне. Оба решения будут работать для меня, и я выберу более быстрое решение.

Я читал несколько сообщений в Интернете, но не могу найти решение. Я также попытался отключить вывод-выход без успеха. В основном, похоже, проблема заключается в том, что где-то в XSL-исполнении двигатель меняет этот <p> на этот: <p>.

Он преобразует & в &. Если это поможет, вот мой XSL-код. Я попробовал несколько комбинаций с и без выходного тега сверху.

Любая помощь будет оценена по достоинству. Заранее спасибо.

<?xml version="1.0" encoding="utf-8"?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 

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

    <xsl:template match="DocumentElement"> 
    <div> 
     <xsl:attribute name="id">mySlides</xsl:attribute> 
     <xsl:apply-templates> 
     <xsl:with-param name="templatenumber" select="0"/> 
     </xsl:apply-templates> 
    </div> 

    <div> 
     <xsl:attribute name="id">myController</xsl:attribute> 
     <xsl:apply-templates> 
     <xsl:with-param name="templatenumber" select="1"/> 
     </xsl:apply-templates> 
    </div> 
    </xsl:template> 

    <xsl:template match="DocumentElement/QueryResults"> 
    <xsl:param name="templatenumber">tobereplace</xsl:param> 

    <xsl:if test="$templatenumber=0"> 
     <div> 
     <xsl:attribute name="id">myController</xsl:attribute> 
     <div> 
      <xsl:attribute name="class">article</xsl:attribute> 
      <h2> 
      <a> 
       <xsl:attribute name="class">title</xsl:attribute> 
       <xsl:attribute name="title"><xsl:value-of select="Title"/></xsl:attribute> 
       <xsl:attribute name="href">/stories/stories-details/articletype/articleview/articleid/<xsl:value-of select="ArticleId"/>/<xsl:value-of select="SEOTitle"/>.aspx</xsl:attribute> 
       <xsl:value-of select="Title"/> 
      </a> 
      </h2> 
      <div> 
      <xsl:attribute name="style">text-indent: 25px;</xsl:attribute> 
      <xsl:attribute name="class">articlesummary</xsl:attribute> 
      <xsl:call-template name="removeHtmlTags"> 
       <xsl:with-param name="html" select="Summary" /> 
      </xsl:call-template> 
      </div> 
     </div> 
     </div> 
    </xsl:if> 
    <xsl:if test="$templatenumber=1"> 
     <div> 
     <xsl:attribute name="id">myController</xsl:attribute> 
     <span> 
      <xsl:attribute name="class">jFlowControl</xsl:attribute> 
      aa 
     </span> 
     </div> 
    </xsl:if> 
    </xsl:template> 

    <xsl:template name="removeHtmlTags"> 
    <xsl:param name="html"/> 
    <xsl:choose> 
     <xsl:when test="contains($html, '&lt;')"> 
     <xsl:value-of select="substring-before($html, '&lt;')"/> 
     <!-- Recurse through HTML --> 
     <xsl:call-template name="removeHtmlTags"> 
      <xsl:with-param name="html" select="substring-after($html, '&gt;')"/> 
     </xsl:call-template> 
     </xsl:when> 
     <xsl:otherwise> 
     <xsl:value-of select="$html"/> 
     </xsl:otherwise> 
    </xsl:choose> 
    </xsl:template> 
</xsl:stylesheet> 
+0

@Marcos, мне нужна помощь, чтобы понять, что вы пытаетесь сделать. Ваш XSLT указывает на его попытку вывода HTML, но затем у вас есть шаблон, указывающий, что вы удаляете теги HTML. Не знаете, почему вы пытаетесь это сделать. Если хотите, укажите дополнительную информацию. – Nick

+0

Чтобы иметь возможность сказать что-нибудь о проблеме, было бы действительно полезно иметь пример ввода XML, который будет запускаться через таблицу стилей, и который обнаруживает эту проблему, а также знать, какой XSLT-процессор вы используете ... – Laurent

ответ

6

Вы не должны хранить скрытый HTML в своей базе данных. Если ваша база данных содержит фактический символ «<», команда «disable-output-escaping» будет делать то, что вы хотели.

Если вы не можете изменить данные, вам нужно будет удалить данные перед выполнением преобразования.

+0

Thks! У меня было это понимание прямо сейчас: вместо того, чтобы пытаться unescape <с шаблоном HTML STRIP, я действительно сделал STRIP с этим: & lt; и это сработало. К сожалению, я извлекаю информацию из таблицы другого приложения, и я не могу изменить способ ее работы. Я использую DotNetNuke. –

+0

+1. Ненавижу, когда люди хранят подобные структуры в базах данных. Его кошмар управления. –

18

Основываясь на предположении, что у вас есть это HTML строка,

<p>My name is Freddy &amp; I was 

затем, если вы избежать его и хранить его в базе данных он стал бы это:

&lt;p&gt;My name is Freddy &amp;amp; I was 

Следовательно , если вы извлечете его как XML (без его незакрепления заранее), результатом будет this:

&amp;lt;p&amp;gt;My name is Freddy &amp;amp;amp; I was 

<xsl:value-of select="." disable-output-escaping="yes" /> и будет производить:

&lt;p&gt;My name is Freddy &amp;amp; I was 

Вы получаете именно то же самое, у вас есть в вашей базе данных, но, конечно, вы видите HTML-теги в выходных данных.Так что вам нужно, это механизм, который выполняет следующие строки замены:

  • "&amp;lt;" с "&lt;" (эффективно меняющимся &lt; к < в немаскированном выводе)
  • "&amp;gt;" с "&gt;" (эффективно меняющимся &gt; к > в немаскированном выводе)
  • "&amp;quot;" с "&quot;" (эффективно меняющегося &quot; к " в немаскированном)
  • выводе
  • "&amp;amp;" с "&amp;" (эффективно меняющимся &amp; к & в немаскированном выводе)

С вашей XSL я выведенный следующий тестом входного XML:

<DocumentElement> 
    <QueryResults> 
    <Title>Article 1</Title> 
    <ArticleId>1</ArticleId> 
    <SEOTitle>Article_1</SEOTitle> 
    <Summary>&amp;lt;p&amp;gt;Article 1 summary &amp;amp;amp; description.&amp;lt;/p&amp;gt;</Summary> 
    </QueryResults> 
    <QueryResults> 
    <Title>Article 2</Title> 
    <ArticleId>2</ArticleId> 
    <SEOTitle>Article_2</SEOTitle> 
    <Summary>&amp;lt;p&amp;gt;Article 2 summary &amp;amp;amp; description.&amp;lt;/p&amp;gt;</Summary> 
    </QueryResults> 
</DocumentElement> 

Я изменил таблицу стилей в комплекте поставки и реализован такой механизм замены. Если применить следующий XSLT 1.0 шаблон к нему:

<xsl:stylesheet 
    version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:my="my:namespace" 
    exclude-result-prefixes="my" 
> 

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

    <my:unescape> 
    <my:char literal="&lt;" escaped="&amp;lt;" /> 
    <my:char literal="&gt;" escaped="&amp;gt;" /> 
    <my:char literal="&quot;" escaped="&amp;quot;" /> 
    <my:char literal="&amp;" escaped="&amp;amp;" /> 
    </my:unescape> 

    <xsl:template match="DocumentElement"> 
    <div id="mySlides"> 
     <xsl:apply-templates mode="slides" /> 
    </div> 
    <div id="myController"> 
     <xsl:apply-templates mode="controller" /> 
    </div> 
    </xsl:template> 

    <xsl:template match="DocumentElement/QueryResults" mode="slides"> 
    <div class="article"> 
     <h2> 
     <a class="title" title="{Title}" href="{concat('/stories/stories-details/articletype/articleview/articleid/', ArticleId, '/', SEOTitle, '.aspx')}"> 
      <xsl:value-of select="Title"/> 
     </a> 
     </h2> 
     <div class="articlesummary" style="text-indent: 25px;"> 
     <xsl:apply-templates select="document('')/*/my:unescape/my:char[1]"> 
      <xsl:with-param name="html" select="Summary" /> 
     </xsl:apply-templates> 
     </div> 
    </div> 
    </xsl:template> 

    <xsl:template match="DocumentElement/QueryResults" mode="controller"> 
    <span class="jFlowControl"> 
     <xsl:text>aa </xsl:text> 
     <xsl:value-of select="Title" /> 
    </span> 
    </xsl:template> 

    <xsl:template match="my:char"> 
    <xsl:param name="html" /> 
    <xsl:variable name="intermediate"> 
     <xsl:choose> 
     <xsl:when test="following-sibling::my:char"> 
      <xsl:apply-templates select="following-sibling::my:char[1]"> 
      <xsl:with-param name="html" select="$html" /> 
      </xsl:apply-templates> 
     </xsl:when> 
     <xsl:otherwise> 
      <xsl:value-of select="$html" disable-output-escaping="yes" /> 
     </xsl:otherwise> 
     </xsl:choose> 
    </xsl:variable> 
    <xsl:call-template name="unescape"> 
     <xsl:with-param name="html" select="$intermediate" /> 
    </xsl:call-template> 
    </xsl:template> 

    <xsl:template name="unescape"> 
    <xsl:param name="html" /> 
    <xsl:choose> 
     <xsl:when test="contains($html, @escaped)"> 
     <xsl:value-of select="substring-before($html, @escaped)" disable-output-escaping="yes"/> 
     <xsl:value-of select="@literal" disable-output-escaping="yes" /> 
     <xsl:call-template name="unescape"> 
      <xsl:with-param name="html" select="substring-after($html, @escaped)"/> 
     </xsl:call-template> 
     </xsl:when> 
     <xsl:otherwise> 
     <xsl:value-of select="$html" disable-output-escaping="yes"/> 
     </xsl:otherwise> 
    </xsl:choose> 
    </xsl:template> 

</xsl:stylesheet> 

Затем производится этот вывод HTML:

<div id="mySlides"> 
    <div class="article"> 
    <h2> 
     <a class="title" title="Article 1" href="/stories/stories-details/articletype/articleview/articleid/1/Article_1.aspx">Article 1</a> 
    </h2> 
    <div class="articlesummary" style="text-indent: 25px;"> 
     <p>Article 1 summary &amp; description.</p> 
    </div> 
    </div> 
    <div class="article"> 
    <h2> 
     <a class="title" title="Article 2" href="/stories/stories-details/articletype/articleview/articleid/2/Article_2.aspx">Article 2</a> 
    </h2> 
    <div class="articlesummary" style="text-indent: 25px;"> 
     <p>Article 2 summary &amp; description.</p> 
    </div> 
    </div> 
</div> 
<div id="myController"> 
    <span class="jFlowControl">aa Article 1</span> 
    <span class="jFlowControl">aa Article 2</span> 
</div> 

Примечание

  • использование временного пространства имен и встроенных элементов (<my:unescape>), чтобы создать список символов для замены
  • использование рекурсии для эмуляции итеративной замены всех затронутых символов cters во входном
  • использование неявного контекста в unescape шаблона для транспортировки информации, какой символ должен быть заменен на данный момент

Кроме того, обратите внимание:

  • использование режимов шаблона для получения разного выхода для одного входа (это заменяет ваш параметр templatenumber)
  • большую часть времени не нужно для <xsl:attribute> элементов. Они могут быть безопасно заменены инлайн нотации (attributename="{attributevalue}")
  • использование функции concat() для создания URL

Вообще говоря, это плохая идея, чтобы хранить спасся HTML в базе данных (в более общем плане: Плохая идея хранить HTML в базе данных.). Вы задаете себе все проблемы, это один из них. Если вы не можете изменить эту настройку, я надеюсь, что решение поможет вам.

Я не могу гарантировать, что он поступает правильно во всех ситуациях, и он может открыть дыры в безопасности (думаю, XSS), но дело с этим не было частью вопроса. В любом случае, подумайте о себе.

Мне нужен перерыв.;-)

+0

Отличное объяснение! –

+0

Спасибо, у меня была такая же проблема :) +1 за отличный ответ. – EinLama

1

Это плохая идея, чтобы сохранить HTML в базе данных

Что? Как вы должны его хранить? В XML-документе, чтобы использовать XSLT? Как веб-разработчик, мы всегда использовали базы данных SQL для хранения пользовательских данных HTML. Нет ничего плохого в этом методе, если он правильно очищается для ваших целей.

+0

Это не хорошая практика. Если вам это удалось, вы просто не работали над системой, которая должна была масштабироваться. – itsbruce

+0

Плохая идея или нет, почти весь веб-сайт управляется хранящимся в базе данных HTML в наши дни. WordPress - очевидный пример. –

+0

Возможно, было бы труднее использовать MarkDown вместо разметки HTML. В любом случае, ** являются ** случаями использования, в которых вы хотите, чтобы какая-либо разметка хранилась в базе данных. – CoDEmanX

2

Добавьте эту строку в таблицу стилей

<xsl:output method="html" indent="yes" version="4.0"/> 
Смежные вопросы