Skip to content

Instantly share code, notes, and snippets.

@andrewminton
Forked from anonymous/master.xml
Created September 6, 2013 16:09
Show Gist options
  • Save andrewminton/6466039 to your computer and use it in GitHub Desktop.
Save andrewminton/6466039 to your computer and use it in GitHub Desktop.
<data>
<entry>
<caption mode="formatted">
<p>A fairly long looking <a href="http://www.stackoverflow.com">caption with a link</a> that goes to an external site.</p>
</caption>
</entry>
<entry>
<caption mode="unformatted">
<![CDATA[A fairly long looking <a href="http://www.stackoverflow.com">caption with a link</a> that goes to an external site.]]>
</caption>
</entry>
</data>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:exsl="http://exslt.org/common" extension-element-prefixes="exsl">
<xsl:output method="xml" indent="yes" />
<xsl:template match="/">
<xsl:apply-templates select="data/entry"/>
</xsl:template>
<xsl:template match="data/entry">
<xsl:copy-of select="caption/*"/>
<xsl:variable name="html-ready">
<xsl:copy-of select="caption/*"/>
</xsl:variable>
<!-- process contents of caption node-->
<!-- stringify it -->
<li>
<img>
<xsl:attribute name="src">/image/2/150/112/5<xsl:value-of select="@path"/>/<xsl:value-of select="filename"/></xsl:attribute>
<xsl:attribute name="data-caption">
<xsl:copy-of select="caption/*" disable-output-escaping="yes"/>
<!--<xsl:call-template name="nodetostring">
<xsl:with-param name="node" select="$html-ready"/>
<xsl:with-param name="format" select="true()"/>
</xsl:call-template>-->
</xsl:attribute>
</img>
</li>
</xsl:template>
<xsl:template name="nodetostring">
<!-- Incoming XML -->
<xsl:param name="node"/>
<!-- Turn format on and off -->
<xsl:param name="format" select="false()"/>
<!-- Format indent -->
<xsl:param name="format-tab" select="'&#09;'"/>
<!-- Escape double quotes in strings -->
<xsl:param name="esc-dblq" select="false()"/>
<xsl:apply-templates select="exsl:node-set($node)/* | exsl:node-set($node)/text()" mode="nodetostring">
<xsl:with-param name="format" select="$format"/>
<xsl:with-param name="format-tab" select="$format-tab"/>
<xsl:with-param name="esc-dblq" select="$esc-dblq"/>
</xsl:apply-templates>
</xsl:template>
<!-- Render nodes -->
<xsl:template match="*" mode="nodetostring">
<xsl:param name="format" select="false()"/>
<xsl:param name="format-tab" select="'&#09;'"/>
<xsl:param name="esc-dblq" select="false()"/>
<xsl:variable name="empty"/>
<xsl:choose>
<!--
if element has text only
-->
<xsl:when test="normalize-space(.) != $empty and not(*)">
<xsl:if test="$format">
<xsl:apply-templates select="ancestor::*[1]" mode="nodetostring-format">
<xsl:with-param name="format-tab" select="$format-tab"/>
</xsl:apply-templates>
</xsl:if>
<xsl:apply-templates select="." mode="nodetostring-opentag">
<xsl:with-param name="esc-dblq" select="$esc-dblq"/>
</xsl:apply-templates>
<xsl:apply-templates select="text()" mode="nodetostring">
<xsl:with-param name="format" select="false()"/>
<xsl:with-param name="esc-dblq" select="$esc-dblq"/>
</xsl:apply-templates>
<xsl:apply-templates select="." mode="nodetostring-closetag">
<xsl:with-param name="esc-dblq" select="$esc-dblq"/>
</xsl:apply-templates>
</xsl:when>
<!--
if element has text and children
-->
<xsl:when test="normalize-space(.) != $empty and *">
<xsl:if test="$format">
<xsl:apply-templates select="ancestor::*[1]" mode="nodetostring-format">
<xsl:with-param name="format-tab" select="$format-tab"/>
</xsl:apply-templates>
</xsl:if>
<xsl:apply-templates select="." mode="nodetostring-opentag">
<xsl:with-param name="esc-dblq" select="$esc-dblq"/>
</xsl:apply-templates>
<xsl:if test="$format">
<xsl:text>&#10;</xsl:text>
</xsl:if>
<xsl:apply-templates select="* | text()" mode="nodetostring">
<xsl:with-param name="format" select="$format"/>
<xsl:with-param name="esc-dblq" select="$esc-dblq"/>
</xsl:apply-templates>
<xsl:if test="$format">
<xsl:apply-templates select="ancestor::*[1]" mode="nodetostring-format">
<xsl:with-param name="format-tab" select="$format-tab"/>
</xsl:apply-templates>
</xsl:if>
<xsl:apply-templates select="." mode="nodetostring-closetag">
<xsl:with-param name="esc-dblq" select="$esc-dblq"/>
</xsl:apply-templates>
</xsl:when>
<!--
if element has children only
-->
<xsl:when test="*">
<xsl:if test="$format">
<xsl:apply-templates select="ancestor::*[1]" mode="nodetostring-format">
<xsl:with-param name="format-tab" select="$format-tab"/>
</xsl:apply-templates>
</xsl:if>
<xsl:apply-templates select="." mode="nodetostring-opentag">
<xsl:with-param name="esc-dblq" select="$esc-dblq"/>
</xsl:apply-templates>
<xsl:if test="$format">
<xsl:text>&#10;</xsl:text>
</xsl:if>
<xsl:apply-templates select="*" mode="nodetostring">
<xsl:with-param name="format" select="$format"/>
<xsl:with-param name="esc-dblq" select="$esc-dblq"/>
</xsl:apply-templates>
<xsl:if test="$format">
<xsl:apply-templates select="ancestor::*[1]" mode="nodetostring-format">
<xsl:with-param name="format-tab" select="$format-tab"/>
</xsl:apply-templates>
</xsl:if>
<xsl:apply-templates select="." mode="nodetostring-closetag">
<xsl:with-param name="esc-dblq" select="$esc-dblq"/>
</xsl:apply-templates>
</xsl:when>
<!--
assuming empty tags are self closing, e.g. <img/>, <source/>, <input/>
-->
<xsl:otherwise>
<xsl:if test="$format">
<xsl:apply-templates select="ancestor::*[1]" mode="nodetostring-format">
<xsl:with-param name="format-tab" select="$format-tab"/>
</xsl:apply-templates>
</xsl:if>
<xsl:apply-templates select="." mode="nodetostring-selfclosetag">
<xsl:with-param name="esc-dblq" select="$esc-dblq"/>
</xsl:apply-templates>
</xsl:otherwise>
</xsl:choose>
<xsl:if test="$format">
<xsl:text>&#10;</xsl:text>
</xsl:if>
</xsl:template>
<!-- Render text -->
<xsl:template match="text()" mode="nodetostring">
<xsl:param name="format" select="false()"/>
<xsl:param name="format-tab" select="'&#09;'"/>
<xsl:param name="esc-dblq" select="false()"/>
<xsl:if test="$format">
<xsl:apply-templates select="ancestor::*[1]" mode="nodetostring-format">
<xsl:with-param name="format-tab" select="$format-tab"/>
</xsl:apply-templates>
</xsl:if>
<xsl:choose>
<xsl:when test="$esc-dblq">
<xsl:call-template name="nodetostring.replace">
<xsl:with-param name="in" select="."/>
<xsl:with-param name="needle" select="'&#34;'"/>
<xsl:with-param name="replace" select="'&#92;&#34;'"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="."/>
</xsl:otherwise>
</xsl:choose>
<xsl:if test="$format">
<xsl:text>&#10;</xsl:text>
</xsl:if>
</xsl:template>
<!-- Render self closing tags -->
<xsl:template match="*" mode="nodetostring-selfclosetag">
<xsl:param name="esc-dblq" select="false()"/>
<xsl:text>&lt;</xsl:text>
<xsl:value-of select="name()"/>
<xsl:apply-templates select="@*" mode="nodetostring-attribs">
<xsl:with-param name="esc-dblq" select="$esc-dblq"/>
</xsl:apply-templates>
<xsl:text>/&gt;</xsl:text>
</xsl:template>
<!-- Render open tag -->
<xsl:template match="*" mode="nodetostring-opentag">
<xsl:param name="esc-dblq" select="false()"/>
<xsl:text>&lt;</xsl:text>
<xsl:value-of select="name()"/>
<xsl:apply-templates select="@*" mode="nodetostring-attribs">
<xsl:with-param name="esc-dblq" select="$esc-dblq"/>
</xsl:apply-templates>
<xsl:text>&gt;</xsl:text>
</xsl:template>
<!-- Render close tag -->
<xsl:template match="*" mode="nodetostring-closetag">
<xsl:text>&lt;/</xsl:text>
<xsl:value-of select="name()"/>
<xsl:text>&gt;</xsl:text>
</xsl:template>
<!-- Render attributes -->
<xsl:template match="@*" mode="nodetostring-attribs">
<xsl:param name="esc-dblq" select="false()"/>
<xsl:variable name="dbl-quotes">
<xsl:if test="$esc-dblq">\</xsl:if>
<xsl:text>"</xsl:text>
</xsl:variable>
<xsl:value-of select="concat(' ', name(), '=', $dbl-quotes, ., $dbl-quotes)"/>
</xsl:template>
<!-- Formatter utility. Inserts $format-tab as long as parents exist -->
<xsl:template match="*" mode="nodetostring-format">
<xsl:param name="format-tab"/>
<xsl:value-of select="$format-tab"/>
<xsl:apply-templates select="ancestor::*[1]" mode="nodetostring-format">
<xsl:with-param name="format-tab" select="$format-tab"/>
</xsl:apply-templates>
</xsl:template>
<!-- Utility to replace a string in another string -->
<xsl:template name="nodetostring.replace">
<xsl:param name="in" select="''"/>
<xsl:param name="needle" select="''"/>
<xsl:param name="replace" select="''"/>
<xsl:choose>
<xsl:when test="contains($in, $needle)">
<xsl:value-of select="substring-before($in, $needle)"/>
<xsl:value-of select="$replace"/>
<xsl:call-template name="nodetostring.replace">
<xsl:with-param name="in" select="substring-after($in, $needle)"/>
<xsl:with-param name="needle" select="$needle"/>
<xsl:with-param name="replace" select="$replace"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$in"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment