Записки по компютъра

Петък, 2009, Март 6

Динамичен html таг в xsl template

Проблемът е следния:
Искам чрез xsl да форматирам xml документ в html такъв. Това е стандартна процедура.

Например имам my_movie.xml:

<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/xsl" href="movie.xsl"?>
<movie>
<name>YouTube</name>
<src>Whant to put movie here</src>
</movie>


Имам също темплейт movie.xsl:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template match="movie">
        <html>
            <head>
                <title><xsl:value-of select="name"/></title>
            </head>
            <body>
                <h1><xsl:value-of select="name"/></h1>
                <p id="src"><xsl:value-of select="src"/></p>
            </body>
        </html>
    </xsl:template>
</xsl:stylesheet>


Слагам тези два файла в една директория, след това казвам на някой браузер да отвори movie.xml. Показва се html страница, тъй като към xml-а съм добавил реда <?xml-stylesheet type="text/xsl" href="movie.xsl"?>, който указва как да бъде форматиран.

Дотук добре, но това, което аз искам да направя е, е да сложа не текст като съдържание на тага src, а всъщност html таг, например:

<object width="425" height="344">
    <param name="movie" value="http://www.youtube.com/v/2-xIulyVsG8&hl=en&fs=1"></param>
    <param name="allowFullScreen" value="true"></param>
    <param name="allowscriptaccess" value="always"></param>
    <embed src="http://www.youtube.com/v/2-xIulyVsG8&hl=en&fs=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"></embed>
</object>


така щото във форматираната страница да ми се показва не друго, а филмчето.

Ако сложа горното директно като съдържание на src тага няма да се получи, защото <object> ще бъде интерпретиран като нов xml таг, а не както аз искам - като текст.

Възможно е да има стандартно и просто разрешение на този проблем. Пуснах няколко търсения в гугъл, но не можах да го намеря - може би защото нямах достатъчно хъс за търсене. Наложи ми се да се замисля и ето какво измислих:

Възможно е да се използва <![CDATA[...]]>, за да се ескейпне съдържанието на src тага. Тогава movie.xml ще изглежда така:

<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/xsl" href="movie.xsl"?>
<movie>
<name>YouTube</name>
<src><![CDATA[
<object width="425" height="344">
<param name="movie" value="http://www.youtube.com/v/2-xIulyVsG8&hl=en&fs=1"></param>
<param name="allowFullScreen" value="true"></param>
<param name="allowscriptaccess" value="always"></param>
<embed src="http://www.youtube.com/v/2-xIulyVsG8&hl=en&fs=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"></embed>
]]></object>
</src>
</movie>


По такъв начин интерпретаторът ще разбере, че тук става дума за съдържание на тага, не нов таг. За съжаление обаче, той ще подмени специалните символи като '<' и '>' с '&lt;' и '&gt;' при което браузера ще покаже кода и пак не това, което аз искам.

Остава да вземем контра мерки и с javascript да върнем < и > обратно.

function replaceSpecial(){
    var text = document.getElementById("src").innerHTML;
    while(text.indexOf('&lt;') != -1){
        text = text.replace('&lt;', '<');
    }
    while(text.indexOf('&gt;') != -1){
        text = text.replace('&gt;', '>');
    }
    document.getElementById("src").innerHTML = text;
}


Добавяме в movie.xls извикване на тази javascript функция преди затварящия таг </body>:

<script type="text/javascript">replaceSpecial();</script>


Работи.

4 коментара:

  • използвай disable-output-escaping="yes" или с други думи:

    [p id="src"][xsl:value-of select="src" disable-output-escaping="yes" /][/p]

    Това няма да прави > и < в тия другите... успех

    От Anonymous Анонимен, В Понеделник, 2009, Март 23 2:20  

  • Незнам - може би не успях да схвана точно приложението: пробвах да добавя disable-output-escaping="yes" отностно изходния вариант на xml-a, после и отностно варианта с [CDATA[ и в двата случая не стана това, което очаквах. Може би не се ориентирам правилно?

    От Blogger igurbev, В Понеделник, 2009, Март 23 12:27  

  • [?xml version="1.0" encoding="utf-8"?]
    [xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"]
    [xsl:template match="movie"]
    [html]
    [head]
    [title][xsl:value-of select="name"/][/title]
    [/head]
    [body]
    [h1][xsl:value-of select="name"/][/h1]
    [p id="src"][xsl:value-of select="src" disable-output-escaping="yes"/][/p]
    [/body]
    [/html]
    [/xsl:template]
    [/xsl:stylesheet]

    Това не бачка ли с:

    [?xml version="1.0" encoding="utf-8"?]
    [?xml-stylesheet type="text/xsl" href="movie.xsl"?]
    [movie]
    [name]YouTube[/name]
    [src][![CDATA[
    [object width="425" height="344"]
    [param name="movie" value="http://www.youtube.com/v/2-xIulyVsG8&hl=en&fs=1"][/param]
    [param name="allowFullScreen" value="true"][/param]
    [param name="allowscriptaccess" value="always"][/param]
    [embed src="http://www.youtube.com/v/2-xIulyVsG8&hl=en&fs=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"][/embed]
    ]]][/object]
    [/src]
    [/movie]

    Сменям нарочно скобите, че тагове не са позволени.

    От Anonymous Анонимен, В Понеделник, 2009, Март 23 14:49  

  • Аз всвъщност пробвах точно това. Сега проверявам отново: оказва се, че с всеки друг браузер освен Firefox работи. Хм.

    От Blogger igurbev, В Понеделник, 2009, Март 23 21:45  

Публикуване на коментар



<< Начална страница