Skip to content

Instantly share code, notes, and snippets.

@stanio
Last active December 18, 2019 05:48
Show Gist options
  • Save stanio/4b4b6f57bae0df4bf166909f37bc2a4b to your computer and use it in GitHub Desktop.
Save stanio/4b4b6f57bae0df4bf166909f37bc2a4b to your computer and use it in GitHub Desktop.
Transform Liquibase XML into Groovy DSL syntax
<?xml-stylesheet href="liquibase-groovy.xslt" type="text/xml"?>

<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" ...>
    ...
</databaseChangeLog>
databaseChangeLog {
    ...
}
<?xml version="1.0" encoding="UTF-8"?>
<!--
- This file is in the Public Domain, and comes with NO WARRANTY.
-->
<!--
- Poor man's conversion of Liquibase changelog XML file:
-
- https://www.liquibase.org/documentation/databasechangelog.html
-
- into Groovy DSL:
-
- https://github.com/liquibase/liquibase-groovy-dsl
- https://github.com/liquibase/liquibase-groovy-dsl/blob/master/src/test/changelog/changelog.groovy
-->
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" encoding="UTF-8" media-type="text/x-groovy" />
<xsl:param name="indent" select="string(' ')" />
<xsl:template match="*">
<xsl:param name="current-indent" />
<xsl:value-of select="$current-indent" />
<xsl:value-of select="local-name()" />
<xsl:apply-templates select="@*[namespace-uri()='']" />
<xsl:choose>
<xsl:when test="*[1]|comment()[1]">
<xsl:call-template name="block">
<xsl:with-param name="current-indent" select="$current-indent" />
</xsl:call-template>
</xsl:when>
<xsl:when test="@*[namespace-uri()=''] and text()[normalize-space()!='']">
<xsl:call-template name="block">
<xsl:with-param name="current-indent" select="$current-indent" />
</xsl:call-template>
</xsl:when>
<xsl:when test="text()[normalize-space()!='']">
<xsl:apply-templates select="text()[normalize-space()!='']">
<xsl:with-param name="current-indent" select="$current-indent" />
</xsl:apply-templates>
</xsl:when>
<xsl:otherwise>
<xsl:text>&#10;</xsl:text>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template name="block">
<xsl:param name="current-indent" />
<xsl:text> {&#10;</xsl:text>
<xsl:apply-templates select="*|comment()|text()[normalize-space()!='']">
<xsl:with-param name="current-indent" select="concat($current-indent, $indent)" />
</xsl:apply-templates>
<xsl:value-of select="$current-indent" />
<xsl:text>}&#10;</xsl:text>
</xsl:template>
<xsl:template match="@*">
<xsl:choose>
<xsl:when test="position() = 1">
<xsl:text>(</xsl:text>
</xsl:when>
<xsl:otherwise>
<xsl:text>, </xsl:text>
</xsl:otherwise>
</xsl:choose>
<xsl:value-of select="local-name()" />
<xsl:text>: </xsl:text>
<xsl:call-template name="value" />
<xsl:if test="position() = last()">
<xsl:text>)</xsl:text>
</xsl:if>
</xsl:template>
<xsl:template match="comment()">
<xsl:param name="current-indent" />
<xsl:value-of select="$current-indent" />
<xsl:text>/* </xsl:text>
<xsl:value-of select="." />
<xsl:text> */&#10;</xsl:text>
</xsl:template>
<xsl:template match="text()">
<xsl:param name="current-indent" />
<xsl:value-of select="$current-indent" />
<xsl:call-template name="value" />
<xsl:text>&#10;</xsl:text>
</xsl:template>
<xsl:template name="value">
<xsl:choose>
<xsl:when test=". = 'true'">
<xsl:text>true</xsl:text>
</xsl:when>
<xsl:when test=". = 'false'">
<xsl:text>false</xsl:text>
</xsl:when>
<xsl:when test="contains(., '&#10;')">
<xsl:text>"""</xsl:text>
<xsl:if test="not(starts-with(., '&#10;'))">
<xsl:text>&#10;</xsl:text>
</xsl:if>
<xsl:value-of select="." />
<xsl:text>"""</xsl:text>
</xsl:when>
<xsl:when test="contains(., '${')">
<xsl:text>"</xsl:text>
<xsl:value-of select="." />
<xsl:text>"</xsl:text>
</xsl:when>
<xsl:otherwise>
<xsl:text>'</xsl:text>
<xsl:value-of select="." />
<xsl:text>'</xsl:text>
</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