Last active
December 23, 2015 03:39
-
-
Save ijy/6574468 to your computer and use it in GitHub Desktop.
Converts a node-set into a string (allows you to insert code blocks as text rather than being interpreted). Useful for things such as JSON conversions and displaying code snippets. @href: http://www.getsymphony.com/download/xslt-utilities/view/103039/
@href: http://www.getsymphony.com/discuss/thread/103015/
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<xsl:variable name="html-ready"> | |
<!-- prepare the HTML as you want it --> | |
</xsl:variable> | |
<!-- stringify it --> | |
<xsl:call-template name="nodetostring"> | |
<xsl:with-param name="node" select="$html-ready"/> | |
<xsl:with-param name="esc-dblq" select="true()"/> | |
</xsl:template> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="UTF-8"?> | |
<xsl:stylesheet version="1.0" | |
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" | |
xmlns:exsl="http://exslt.org/common" | |
extension-element-prefixes="exsl"> | |
<!-- | |
Converts a nodeset to string, especially useful for json conversions. | |
=================================================================================== | |
Adapted from @Thomas Appel's nodetostring utility at http://www.getsymphony.com/download/xslt-utilities/view/79266/ | |
This version adds formatting capabilities. Very useful for displaying code snippets. | |
=================================================================================== | |
Example usage: | |
(convert a nodeset to string: ) | |
___ | |
<xsl:call-template name="nodetostring"> | |
<xsl:with-param name="node" select="YOUR_XML"/> | |
</xsl:template> | |
___ | |
Format result | |
___ | |
<xsl:call-template name="nodetostring"> | |
<xsl:with-param name="node" select="YOUR_XML"/> | |
<xsl:with-param name="format" select="true()"/> | |
</xsl:template> | |
___ | |
Escape double quotes | |
___ | |
<xsl:call-template name="nodetostring"> | |
<xsl:with-param name="node" select="YOUR_XML"/> | |
<xsl:with-param name="esc-dblq" select="true()"/> | |
</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="'	'"/> | |
<!-- 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="'	'"/> | |
<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> </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> </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> </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="'	'"/> | |
<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="'"'"/> | |
<xsl:with-param name="replace" select="'\"'"/> | |
</xsl:call-template> | |
</xsl:when> | |
<xsl:otherwise> | |
<xsl:value-of select="."/> | |
</xsl:otherwise> | |
</xsl:choose> | |
<xsl:if test="$format"> | |
<xsl:text> </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><</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>/></xsl:text> | |
</xsl:template> | |
<!-- Render open tag --> | |
<xsl:template match="*" mode="nodetostring-opentag"> | |
<xsl:param name="esc-dblq" select="false()"/> | |
<xsl:text><</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>></xsl:text> | |
</xsl:template> | |
<!-- Render close tag --> | |
<xsl:template match="*" mode="nodetostring-closetag"> | |
<xsl:text></</xsl:text> | |
<xsl:value-of select="name()"/> | |
<xsl:text>></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