Paste: XSLT -> any XML (including attributes, but without namespaces) to literal Factor hashtable

Author: x6j8x
Mode: xml
Date: Sat, 7 Mar 2009 23:12:38
Plain Text |
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

    <!-- 
        Copyright (c) 2009 - Sascha Matzke 
        See http://factorcode.org/license.txt for BSD license
    -->


    <xsl:output encoding="UTF-8" method="text" omit-xml-declaration="yes"/>

    <!-- global variables -->
    <xsl:variable name="quot" select="string('&quot;')"/>
    <xsl:variable name="quot-quoted" select="string('\&quot;')"/>

    <xsl:template match="/">
        <xsl:apply-templates mode="factorize" select="/*[1]"/>
    </xsl:template>

    <xsl:template match="*" mode="factorize">
        <xsl:variable name="subnode-result">
            <xsl:variable name="children" select="*|@*"/>
            <xsl:for-each select="$children">
                <xsl:variable name="current-group"
                    select="$children[local-name() = local-name(current())]"/>
                <xsl:if test="count($current-group[1] | .) = 1">
                    <xsl:variable name="key" select="local-name(.)"/>
                    <xsl:text> { "</xsl:text>
                    <xsl:choose>
                        <xsl:when test="count(. | ../@*) = count(../@*)">
                            <xsl:value-of select="concat('@', $key)"/>
                        </xsl:when>
                        <xsl:otherwise>
                            <xsl:value-of select="$key"/>
                        </xsl:otherwise>
                    </xsl:choose>
                    <xsl:text>" </xsl:text>
                    <xsl:choose>
                        <xsl:when test="count($current-group) > 1">
                            <xsl:text> { </xsl:text>
                            <xsl:for-each select="$current-group">
                                <xsl:apply-templates mode="factorize-node" select="."/>
                            </xsl:for-each>
                            <xsl:text> } </xsl:text>
                        </xsl:when>
                        <xsl:otherwise>
                            <xsl:apply-templates mode="factorize-node" select="."/>
                        </xsl:otherwise>
                    </xsl:choose>
                    <xsl:text> } </xsl:text>
                </xsl:if>
            </xsl:for-each>
        </xsl:variable>
        <xsl:value-of select="concat('H{ ', $subnode-result, ' } ')"/>
    </xsl:template>

    <xsl:template match="*|@*" mode="factorize-node">
        <xsl:choose>
            <xsl:when test="count(*|@*) > 0">
                <xsl:apply-templates mode="factorize" select="."/>
            </xsl:when>
            <xsl:when test="text() or string(.)">
                <xsl:choose>
                    <xsl:when test="text()">
                        <xsl:text> "</xsl:text>
                        <xsl:variable name="quot-replaced">
                            <xsl:call-template name="replace">
                                <xsl:with-param name="str" select="text()"/>
                                <xsl:with-param name="repl" select="$quot"/>
                                <xsl:with-param name="target" select="$quot-quoted"/>
                            </xsl:call-template>
                        </xsl:variable>
                        <xsl:variable name="newline-replaced">
                            <xsl:call-template name="replace">
                                <xsl:with-param name="str" select="$quot-replaced"/>
                                <xsl:with-param name="repl" select="'&#xa;'"/>
                                <xsl:with-param name="target" select="' '"/>
                            </xsl:call-template>
                        </xsl:variable>
                        <xsl:variable name="quoted-newline-replaced">
                            <xsl:call-template name="replace">
                                <xsl:with-param name="str" select="$newline-replaced"/>
                                <xsl:with-param name="repl" select="'\\n'"/>
                                <xsl:with-param name="target" select="' '"/>
                            </xsl:call-template>
                        </xsl:variable>
                        <xsl:value-of select="$quoted-newline-replaced"/>
                        <xsl:text>" </xsl:text>
                    </xsl:when>
                    <xsl:when test="string(.)">
                        <xsl:text> "</xsl:text>
                        <xsl:variable name="quot-replaced">
                            <xsl:call-template name="replace">
                                <xsl:with-param name="str" select="string()"/>
                                <xsl:with-param name="repl" select="$quot"/>
                                <xsl:with-param name="target" select="$quot-quoted"/>
                            </xsl:call-template>
                        </xsl:variable>
                        <xsl:variable name="newline-replaced">
                            <xsl:call-template name="replace">
                                <xsl:with-param name="str" select="$quot-replaced"/>
                                <xsl:with-param name="repl" select="'&#xa;'"/>
                                <xsl:with-param name="target" select="' '"/>
                            </xsl:call-template>
                        </xsl:variable>
                        <xsl:variable name="quoted-newline-replaced">
                            <xsl:call-template name="replace">
                                <xsl:with-param name="str" select="$newline-replaced"/>
                                <xsl:with-param name="repl" select="'\\n'"/>
                                <xsl:with-param name="target" select="' '"/>
                            </xsl:call-template>
                        </xsl:variable>
                        <xsl:value-of select="$quoted-newline-replaced"/>
                        <xsl:text>" </xsl:text>
                    </xsl:when>
                    <xsl:otherwise>
                        <xsl:text> f </xsl:text>
                    </xsl:otherwise>
                </xsl:choose>
            </xsl:when>
            <xsl:otherwise>
                <xsl:text> f </xsl:text>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>

    <xsl:template name="replace">
        <xsl:param name="str"/>
        <xsl:param name="repl"/>
        <xsl:param name="target"/>
        <xsl:choose>
            <xsl:when test="contains($str,$repl)">
                <xsl:variable name="before" select="substring-before($str, $repl)"/>
                <xsl:variable name="after">
                    <xsl:call-template name="replace">
                        <xsl:with-param name="str"
                            select="normalize-space(substring-after($str,$repl))"/>
                        <xsl:with-param name="repl" select="$repl"/>
                        <xsl:with-param name="target" select="$target"/>
                    </xsl:call-template>
                </xsl:variable>
                <xsl:value-of select="concat($before, $target, $after)"/>
            </xsl:when>
            <xsl:otherwise>
                <xsl:value-of select="$str"/>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>

</xsl:stylesheet>

Annotation: better version...

Author: x6j8x
Mode: xml
Date: Sat, 7 Mar 2009 23:19:10
Plain Text |
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

    <!-- 
        Copyright (c) 2009 - Sascha Matzke 
        See http://factorcode.org/license.txt for BSD license
    -->


    <xsl:output encoding="UTF-8" method="text" omit-xml-declaration="yes"/>

    <!-- global variables -->
    <xsl:variable name="quot" select="string('&quot;')"/>
    <xsl:variable name="quot-quoted" select="string('\&quot;')"/>

    <xsl:template match="/">
        <xsl:apply-templates mode="factorize" select="/*[1]"/>
    </xsl:template>

    <xsl:template match="*" mode="factorize">
        <xsl:variable name="subnode-result">
            <xsl:variable name="children" select="*|@*"/>
            <xsl:for-each select="$children">
                <xsl:variable name="current-group"
                    select="$children[local-name() = local-name(current())]"/>
                <xsl:if test="count($current-group[1] | .) = 1">
                    <xsl:variable name="key" select="local-name(.)"/>
                    <xsl:text> { "</xsl:text>
                    <xsl:choose>
                        <xsl:when test="count(. | ../@*) = count(../@*)">
                            <xsl:value-of select="concat('@', $key)"/>
                        </xsl:when>
                        <xsl:otherwise>
                            <xsl:value-of select="$key"/>
                        </xsl:otherwise>
                    </xsl:choose>
                    <xsl:text>" </xsl:text>
                    <xsl:choose>
                        <xsl:when test="count($current-group) > 1">
                            <xsl:text> { </xsl:text>
                            <xsl:for-each select="$current-group">
                                <xsl:apply-templates mode="factorize-node" select="."/>
                            </xsl:for-each>
                            <xsl:text> } </xsl:text>
                        </xsl:when>
                        <xsl:otherwise>
                            <xsl:apply-templates mode="factorize-node" select="."/>
                        </xsl:otherwise>
                    </xsl:choose>
                    <xsl:text> } </xsl:text>
                </xsl:if>
            </xsl:for-each>
        </xsl:variable>
        <xsl:value-of select="concat('H{ ', $subnode-result, ' } ')"/>
    </xsl:template>

    <xsl:template match="*|@*" mode="factorize-node">
        <xsl:choose>
            <xsl:when test="count(*|@*) > 0">
                <xsl:apply-templates mode="factorize" select="."/>
            </xsl:when>
            <xsl:when test="text() or string(.)">
                <xsl:choose>
                    <xsl:when test="text()">
                        <xsl:call-template name="mkstring">
                            <xsl:with-param name="str" select="text()"/>
                        </xsl:call-template>
                    </xsl:when>
                    <xsl:when test="string(.)">
                        <xsl:call-template name="mkstring">
                            <xsl:with-param name="str" select="string(.)"/>
                        </xsl:call-template>
                    </xsl:when>
                    <xsl:otherwise>
                        <xsl:text> f </xsl:text>
                    </xsl:otherwise>
                </xsl:choose>
            </xsl:when>
            <xsl:otherwise>
                <xsl:text> f </xsl:text>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>

    <xsl:template name="mkstring">
        <xsl:param name="str"/>
        <xsl:text> "</xsl:text>
        <xsl:variable name="quot-replaced">
            <xsl:call-template name="replace">
                <xsl:with-param name="str" select="$str"/>
                <xsl:with-param name="repl" select="$quot"/>
                <xsl:with-param name="target" select="$quot-quoted"/>
            </xsl:call-template>
        </xsl:variable>
        <xsl:variable name="newline-replaced">
            <xsl:call-template name="replace">
                <xsl:with-param name="str" select="$quot-replaced"/>
                <xsl:with-param name="repl" select="'&#xa;'"/>
                <xsl:with-param name="target" select="' '"/>
            </xsl:call-template>
        </xsl:variable>
        <xsl:variable name="quoted-newline-replaced">
            <xsl:call-template name="replace">
                <xsl:with-param name="str" select="$newline-replaced"/>
                <xsl:with-param name="repl" select="'\\n'"/>
                <xsl:with-param name="target" select="' '"/>
            </xsl:call-template>
        </xsl:variable>
        <xsl:value-of select="$quoted-newline-replaced"/>
        <xsl:text>" </xsl:text>
    </xsl:template>

    <xsl:template name="replace">
        <xsl:param name="str"/>
        <xsl:param name="repl"/>
        <xsl:param name="target"/>
        <xsl:choose>
            <xsl:when test="contains($str,$repl)">
                <xsl:variable name="before" select="substring-before($str, $repl)"/>
                <xsl:variable name="after">
                    <xsl:call-template name="replace">
                        <xsl:with-param name="str"
                            select="normalize-space(substring-after($str,$repl))"/>
                        <xsl:with-param name="repl" select="$repl"/>
                        <xsl:with-param name="target" select="$target"/>
                    </xsl:call-template>
                </xsl:variable>
                <xsl:value-of select="concat($before, $target, $after)"/>
            </xsl:when>
            <xsl:otherwise>
                <xsl:value-of select="$str"/>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>

</xsl:stylesheet>

Annotation: @Github

Author: x6j8x
Mode: text
Date: Sun, 8 Mar 2009 01:37:59
Plain Text |
http://github.com/x6j8x/factorize

New Annotation

Summary:
Author:
Mode:
Body: