можно ли дважды отключить экранирование вывода в XSLT

#html #xml #xslt

#HTML #xml #xslt

Вопрос:

У меня есть XML, в котором закодированы данные HTML. Я пытаюсь отобразить данные, но, похоже, не могу понять, как это сделать. Лучшее, что я могу сказать, это то, что мне нужно disable-output-escaping="yes" дважды, но я не уверен, как это сделать.

Например, это фрагмент моего XML:

 <root>
    <node value="amp;amp;<bamp;amp;>bodyamp;amp;</bamp;amp;>" />
</root>
  

Мой XSLT выводит HTML. Вот отображаемый вывод (исходный код HTML) с различными параметрами

  • <xsl:value-of select="@value" /> выводит amp;amp;<bamp;amp;>hiamp;amp;</bamp;amp;>
  • <xsl:value-of select="@value" disable-output-escaping="yes" /> выводит amp;<bamp;>hiamp;</bamp;>

Я бы хотел, чтобы он выводился <b>hi</b> в исходный код HTML, чтобы он фактически отображался как выделенный жирным шрифтом привет. Имеет ли это смысл? Возможно ли это?

Комментарии:

1. Если возможно, ознакомьтесь с функцией xslt 3 parse-xml или saxon parse. Мы не знаем вашей среды.

2. Похоже, что ваш второй подход должен работать до тех пор, пока ваш процессор XSLT и ваш вариант использования поддерживают disable-output-escaping . xsltransform.net/3NSSEuU использует этот подход и выводит <b>hi</b> результаты . Поэтому, если вы не используете браузер Mozilla или какой-либо другой процессор XSLT, который не поддерживает disable-output-escaping , я бы ожидал, что вы получите желаемый результат.

3. @uL1 Это XSLT 1.0. Я пытаюсь сделать это в SharePoint.

4. @MartinHonnen: я допустил ошибку в имеющемся у меня XML. Я обновил его. Если вы увидите сейчас, вы увидите, в чем проблема. xsltransform.net/3NSSEuU/1

5. Позволяет ли Sharepoint использовать msdn.microsoft.com/en-us/library/wxaw5z5e (v = против 110).aspx для вызова. ЧИСТЫЙ код?

Ответ №1:

Экранирование — это процесс превращения < в amp;< . Если вы отключите экранирование, оно останется < как < . Чего вы хотите добиться, так это превратиться amp;< в < , что обычно называется «unescaping».

При обычном ходе событий синтаксический анализатор выполняет экранирование, в то время как сериализатор выполняет экранирование. Итак, если вы хотите отменить экранирование символов, вам нужно подвергнуть их процессу синтаксического анализа, что означает, что вам нужно взять содержимое @value атрибута и выполнить операцию, подобную fn:parse-xml-fragment() в XPath 3.0, или эквивалентную функцию расширения в выбранном вами процессоре.

Ответ №2:

Предполагая, что Sharepoint как продукт Microsoft .NET использует XslCompiledTransform, вы можете попытаться реализовать отмену и синтаксический анализ с расширением «script» (C # или VB или JScript.ЧИСТЫЙ код, встроенный в XSLT) следующим образом:

 <?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet
  version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:msxsl="urn:schemas-microsoft-com:xslt"
  xmlns:mf="http://example.com/mf"
  exclude-result-prefixes="msxsl mf">


  <msxsl:script language="C#" implements-prefix="mf">
    <msxsl:using namespace="System.IO"/>
    public string Unescape(string input)
    {
    XmlDocument doc = new XmlDocument();
    XmlDocumentFragment frag = doc.CreateDocumentFragment();
    frag.InnerXml = input;
    return frag.InnerText;
    }

    public XPathNavigator ParseXml(string xmlInput)
    {
    using (StringReader sr = new StringReader(xmlInput))
    {
    return new XPathDocument(sr).CreateNavigator();
    }
    }
  </msxsl:script>

  <xsl:output method="html" doctype-public="XSLT-compat" omit-xml-declaration="yes" encoding="UTF-8" indent="yes" />

  <xsl:template match="/">
    <html>
      <head>
        <title>Test</title>
      </head>
      <xsl:apply-templates/>
    </html>
  </xsl:template>

  <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="node">
    <div>
      <xsl:copy-of select="mf:ParseXml(mf:Unescape(@value))" />
    </div>
  </xsl:template>

</xsl:stylesheet>
  

Если у вас есть доступ к процессору XSLT (например, к любой версии Saxon 9.7 или Exselt или последней версии Altova или XmlPrime), поддерживающему функции XPath 3 parse-xml , и parse-xml-fragment вы можете записать этот шаблон без функций расширения (в version="3.0" таблице стилей) как

 <xsl:template match="node">
    <div>
        <xsl:copy-of select="parse-xml(string(parse-xml-fragment(@value)))"/>
    </div>
</xsl:template>
  

Ответ №3:

Выведите свой результат с disable-output-escaping помощью, затем обработайте его снова в другом XSL с disable-output-escaping помощью .

Комментарии:

1. Как бы я отнесся к этому в другом XSL?