Элемент вывода в комментариях - PullRequest
11 голосов
/ 14 октября 2010

Мне нужно отобразить 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 игнорируется.

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

Ответы [ 4 ]

11 голосов
/ 14 октября 2010

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

<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>

Хотя не пробовал.

7 голосов
/ 14 октября 2010
<xsl:comment><xsl:apply-templates select="image" /></xsl:comment>

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

<!---->

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

XSLT 1.0 Spec говорит :

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

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

Зависит от того, что подразумевается под «отображением»: в браузере:

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

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

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

<- Немного текста ->

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

<xsl:output method="text"/>

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

Вот как XPath Visualizer создает свой вывод.

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

<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" /> ->

1 голос
/ 14 октября 2010

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

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

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

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

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

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

Ошибка при создании экземпляра содержимого xsl: comment создает узлы, отличные от текстовых узлов.Процессор 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 инструкции.

0 голосов
/ 31 января 2013

Как уже говорил Дмитрий, вы не можете использовать инструкцию 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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...