Условие ‹xsl:output› в XSLT 1.0?

У меня есть таблица стилей XSLT 1.0 (2.0 не вариант), которая создает XHTML. Он может, в зависимости от параметра, создать полный XHTML-валидный документ или просто <div>...</div> фрагмент, предназначенный для включения в веб-страницу.

Моя проблема заключается в создании разных XML-объявлений в этих двух случаях. Для отдельной страницы мне нужно:

<xsl:output doctype-public="-//W3C//DTD XHTML 1.0 Strict//EN"
       doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"/>

И для <div>:

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

Но <xsl:output> не может быть включено в <xsl:if>. Это может быть только прямой дочерний элемент <xsl:stylesheet>.

Единственное решение, которое я вижу, это создать таблицу стилей с большинством шаблонов, а затем две небольшие «обертки» с правильным <xsl:output> и которые будут <xsl:import> основной таблицей стилей.

Я искал лучшую идею, но, видимо, ее нет. Следуя советам Эндрю Хэйра и jelovirt, я написал два «драйвера», две простые таблицы стилей, вызывающие правильный <xsl:output>, а затем основную таблицу стилей. Вот один из этих драйверов, для автономного HTML:

<?xml version="1.0" encoding="us-ascii"?>
<!-- This file is intended to be used as the main stylesheet, it creates a 
 standalone Web page. 
-->
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">

  <xsl:import href="traceroute2html.xsl"/>

  <xsl:param name="standalone" select="'true'"/>

  <xsl:output doctype-public="-//W3C//DTD XHTML 1.0 Strict//EN"
      doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"/>

</xsl:stylesheet>

person bortzmeyer    schedule 11.03.2009    source источник


Ответы (3)


Похоже, вам нужны две разные таблицы стилей. Если это вообще возможно, вы должны создать две отдельные таблицы стилей и динамически вызывать ту, которая вам нужна, из кода.

person Andrew Hare    schedule 11.03.2009

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

  1. Опустите объявление XML во всех случаях.
  2. Условно выведите объявление как неэкранированный текст.

Это работает только в XSLT 1.0 и 2.0 при выводе в файл — это не сработает, если вам нужно обработать вывод в виде XML в том же проходе, например, при сохранении в переменной.

(Обратите внимание, что функции расширения XSLT 2.0 могут позволить взять этот вывод и обработать его как XML за один раз, а XSLT 3.0 имеет встроенную функцию для анализа входной строки как XML.)

Пример фрагмента:

<!-- Omit the XML declaration as the base case:
    we can conditionally output a declaration 
    as text, but we *cannot* apply conditions on
    this `omit-xml-declaration` attribute here.  -->
<xsl:output method="xml" indent="no" 
    omit-xml-declaration="yes"
/>

<!-- Root element match: evaluate different cases, output XML declaration,
    XHTML DOCTYPE, or something else, then process the rest of the input. -->
<xsl:template match="/">
    <xsl:choose>
        <xsl:when test="'... some condition ...'">
            <xsl:text disable-output-escaping="yes">&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;</xsl:text>
        </xsl:when>
        <xsl:when test="'... some other condition ...'">
            <xsl:text disable-output-escaping="yes">&lt;!DOCTYPE html PUBLIC &quot;-//W3C//DTD XHTML 1.0 Strict//EN&quot; &quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd&quot;&gt;</xsl:text>
        </xsl:when>
        <xsl:otherwise>
            <!-- ... some third kind of output ... -->
        </xsl:otherwise>
    </xsl:choose>
    <!-- Just process the rest -->
    <xsl:apply-templates/>
</xsl:template>


... [ other code ] ...
person Eiríkr Útlendi    schedule 29.03.2017

В XSLT значение omit-xml-declaration должно быть либо yes, либо no, здесь нельзя использовать шаблоны значений атрибутов. Это касается как 1.0, так и 2.0.

Атрибуты типа документа могут использовать AVT, но проблема в том, что вы не можете опустить атрибут, вы можете вывести только пустой атрибут, и это приводит к выводу с пустыми строками типа документа.

Извините, это невозможно сделать с помощью XSLT. Вы можете либо использовать две разные таблицы стилей, либо задать параметры вывода в коде, вызывающем XSLT-процессор.

person jelovirt    schedule 12.03.2009