Элемент вывода в комментариях

Мне нужно отобразить HTML-элемент в комментариях (например)

<!-- <img src="path" width="100px" height="100px"/> -->

Я использую этот подход

<?xml version="1.0" encoding="windows-1251"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" indent="no" encoding="windows-1251"/>

    <xsl:template match="myNode">
        ...
        <xsl:comment><xsl:apply-templates select="image" /></xsl:comment>
        ...
    </xsl:template>

    <xsl:template match="image">
        <img src="{@src}" width="{@width}px" height="{@height}px" />
    </xsl:template>

</xsl:stylesheet>

В результате:

<!---->

то есть код в элементе xsl:comment игнорируется.

Как отобразить элемент в комментариях?

Ответ 1

Возможно, можно заменить

<xsl:comment><xsl:apply-templates select="image" /></xsl:comment>

с

<xsl:text disable-output-escaping="yes">&lt;!--</xsl:text>
<xsl:apply-templates select="image" />
<xsl:text disable-output-escaping="yes">--&gt;</xsl:text>

Не пробовал, хотя.

Ответ 2

<xsl:comment><xsl:apply-templates select="image" /></xsl:comment>

В результате:

<!---->

то есть код в элементе xsl: комментарий игнорируется

Описание XSLT 1.0 говорит:

Это ошибка при создании экземпляра содержимое xsl: комментарий создает узлы кроме текстовых узлов. XSLT процессор может сигнализировать об ошибке; если оно не сигнализирует об ошибке, она должна восстановить, проигнорировав оскорбление узлы вместе с их содержимым.

Как отобразить элемент в комментарии?

Это зависит от того, что предназначено для "отображения": в браузере:

&lt;-- <xsl:apply-templates select="image" /> -->

может оказаться полезным, если результат <xsl:apply-templates/> выше - просто простой текст (не разметка).

Если для "отображения" означает предоставление результата в виде текста, то DOE, если это разрешено процессором XSLT, может дать нам желаемый результат:

< -  Некоторый текст →

Наконец, если требуется, чтобы то, что должно быть внутри "комментария", должно быть разметкой, и оно должно отображаться как разметка, то это довольно сложно. В этом случае нужно использовать:

<xsl:output method="text"/>

и должен представить каждый XML-лексический элемент с нужной сериализацией (т.е. экранированной).

Таким образом, Visualizer XPath создает свой вывод.

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

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>

 <xsl:template match="/">
      &lt;-- Hello, World -->

  <xsl:text disable-output-escaping="yes">&lt;--</xsl:text>
   Hello,world! --<xsl:text disable-output-escaping="yes">&gt;</xsl:text>
 </xsl:template>
</xsl:stylesheet>

это преобразование, применяемое к любому XML-документу (не используется), создает:

      &lt;-- Hello, World --&gt;

  <--
   Hello,world! -->

Оба "комментария" могут рассматриваться как комментарии в браузере, а только второй - как комментарий в свободном тексте.

Третий подход (скорее всего, то, что вы хотите) проиллюстрирован ниже:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>

 <xsl:template match="/">
  &lt;-- <xsl:apply-templates select="image"/> -->

 </xsl:template>

 <xsl:template match="image">
  &lt;img src="<xsl:value-of select="@src"/>"
      width="<xsl:value-of select="@width"/>px"
      height="<xsl:value-of select="@height"/>px"/>
 </xsl:template>
</xsl:stylesheet>

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

<image src="http://example.com/yyy.jpg" width="200" height="300"/>

получен желаемый результат:

  &lt;-- 
  &lt;img src="http://example.com/yyy.jpg"
      width="200px"
      height="300px"/&gt;
  --&gt;

просматривается в браузере как:

< - < img src= "http://example.com/yyy.jpg"     ширина = "200px"     высота = "300px" / > →

Ответ 3

Из http://www.w3.org/TR/xslt#section-Creating-Comments:

Элемент xsl: comment создается для создания комментария node в дереве результатов. Содержимое элемента xsl: comment является шаблоном для строкового значения комментария node.

Например, этот

<xsl:comment>This file is automatically generated. Do not edit!</xsl:comment>

создаст комментарий

<!--This file is automatically generated. Do not edit!-->

Это ошибка при создании экземпляра содержимое xsl: комментарий создает узлы кроме текстовых узлов. XSLT процессор может сигнализировать об ошибке; если оно не сигнализирует об ошибке, она должна восстановить, проигнорировав оскорбление узлы вместе с их содержимым.

Это ошибка, если результат создание экземпляра xsl: комментарий содержит строку -- или заканчивается на -. Процессор XSLT может сигнализировать об ошибке; если это не сигнализировать об ошибке, она должна вставка пробела после любого случая из -, за которым следует еще один - или который заканчивает комментарий.

Итак, для того, чтобы делать то, что вам нужно, вам нужно использовать механизм DOE.

Как пример, эта таблица стилей:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:msxsl="urn:schemas-microsoft-com:xslt"
 exclude-result-prefixes="msxsl">
    <xsl:output method="html" indent="no" encoding="windows-1251"/>
    <xsl:template match="img">
        <img src="{.}"/>
    </xsl:template>
    <xsl:template match="root">
        <xsl:variable name="vResult">
            <xsl:apply-templates/>
        </xsl:variable>
        <html>
            <xsl:copy-of select="$vResult"/>
            <xsl:comment>
                <xsl:apply-templates select="msxsl:node-set($vResult)"
                                     mode="encode"/>
            </xsl:comment>
        </html>
    </xsl:template>
    <xsl:template match="*" mode="encode">
        <xsl:value-of select="concat('&lt;',name())"
                      disable-output-escaping="yes"/>
        <xsl:apply-templates select="@*" mode="encode"/>
        <xsl:text>></xsl:text>
        <xsl:apply-templates mode="encode"/>
        <xsl:value-of select="concat('&lt;',name(),'>')"
                      disable-output-escaping="yes"/>
    </xsl:template>
    <xsl:template match="*[not(node())]" mode="encode">
        <xsl:value-of select="concat('&lt;',name())"
                      disable-output-escaping="yes"/>
        <xsl:apply-templates select="@*" mode="encode"/>
        <xsl:text>/></xsl:text>
    </xsl:template>
    <xsl:template match="@*" mode="encode">
        <xsl:value-of select="concat(' ',name(),'=&quot;',.,'&quot;')"/>
    </xsl:template>
</xsl:stylesheet>

С помощью этого ввода:

<root>
    <img>http://example.org/image1.jpg</img>
    <img>http://example.org/image2.jpg</img>
    <img>http://example.org/image3.jpg</img>
</root>

Вывод:

<html>
    <img src="http://example.org/image1.jpg">
    <img src="http://example.org/image2.jpg">
    <img src="http://example.org/image3.jpg">
    <!--<img src="http://example.org/image1.jpg"/>
        <img src="http://example.org/image2.jpg"/>
        <img src="http://example.org/image3.jpg"/>-->
</html>

Примечание: node-set функция расширения для двухпроходного преобразования. disable-output-escaping для инструкции xsl:value-of.

Ответ 4

Как уже говорилось Димитрием, вы не можете использовать инструкцию xsl: comment.

Если ваша цель - просто прокомментировать фрагмент дерева, самый простой способ - поместить маркеры комментариев в текст (неэкранированный) следующим образом:

<xsl:text disable-output-escaping="yes">&lt;!--</xsl:text><xsl:apply-templates select="image" /><xsl:text disable-output-escaping="yes">--&gt;</xsl:text>

вместо:

<xsl:comment><xsl:apply-templates select="image" /></xsl:comment>

и вы получите именно это

<!-- <img src="path" width="100px" height="100px"/> -->

используется с msxml и saxon