XSLT преобразовывает атрибуты из узла в элементы другого узла и удаляет их из исходного узла - PullRequest
0 голосов
/ 21 сентября 2018

с учетом этого xml

<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
                   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                   xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog                    
                   http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.6.xsd">
  <changeSet author="system (generated)"
           context="legacy"
           id="1537289247911-1"
           objectQuotingStrategy="LEGACY">
    <createTable remarks="Language-dependent texts."
                 tableName="AS_LANGUAGETEXT">
      <column name="TEXTID" remarks="Description identifier" type="NUMBER(9, 0)">
        <constraints primaryKey="true" primaryKeyName="PK_AS_LANGUAGETEXT"/>
      </column>
      <column name="LANGID"
                remarks="Language identifier"
                type="java.sql.Types.VARCHAR(2 ${byteVarcharType})">
        <constraints primaryKey="true" primaryKeyName="PK_AS_LANGUAGETEXT"/>
      </column>
      <column name="TEXT"
                remarks="Description"
                type="java.sql.Types.VARCHAR(4000 ${charVarcharType})"/>
    </createTable>
    <customChange>
      ...
    </customChange>
  </changeSet>
  <changeSet>
    <createTable>
      ...
    </createTable>
    <customChange>
      ...
    </customChange>
  </changeSet>
</databaseChangeLog>

Я хотел бы:

  • из источника changeset/createTable удалить @remarks и переместить его в цель changeSet/setTableRemarks, а также скопировать @tableName из источника в цель
  • из источника changeset/createTable/column удалить @remarks и переместить его в цель changeSet/setColumnRemarks, а также скопировать @tableName @columnName из источника в цель
  • , если это возможносгенерируйте @id с UUID в новом наборе изменений
  • , если возможно, добавьте только что созданный набор изменений после текущего измененного набора изменений

, поэтому в конце оно должно выглядеть следующим образом:

<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
                   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                   xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog  http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.6.xsd">
  <changeSet author="system (generated)"
           context="legacy"
           id="1537289247911-1"
           objectQuotingStrategy="LEGACY">
    <createTable tableName="AS_LANGUAGETEXT">
      <column name="TEXTID" type="NUMBER(9, 0)">
        <constraints primaryKey="true" primaryKeyName="PK_AS_LANGUAGETEXT"/>
      </column>
      <column name="LANGID"
                type="java.sql.Types.VARCHAR(2 ${byteVarcharType})">
        <constraints primaryKey="true" primaryKeyName="PK_AS_LANGUAGETEXT"/>
      </column>
      <column name="TEXT"
                type="java.sql.Types.VARCHAR(4000 ${charVarcharType})"/>
    </createTable>
    <customChange>
      ...
    </customChange>
  </changeSet>
  <changeSet id="621c99b7-eb65-462b-890c-014079e5b44c" author="system">
    <setTableRemarks tableName="AS_LANGUAGETEXT" remarks="Language-dependent texts." />
    <setColumnRemarks tableName="AS_LANGUAGETEXT" columnName="TEXTID" remarks="Description identifier" />
    <setColumnRemarks tableName="AS_LANGUAGETEXT" columnName="LANGID" remarks="Language identifier" />
    <setColumnRemarks tableName="AS_LANGUAGETEXT" columnName="LANGID" remarks="Description" />
  </changeSet>
  <changeSet>
    <createTable>
      ...
    </createTable>
    <customChange>
      ...
    </customChange>
  </changeSet>
  <changeSet>
    <setTableRemarks ... />
    <setColumnRemarks ... />
  </changeSet>
</databaseChangeLog>

РЕДАКТИРОВАТЬ: Я сделал это с этим шаблоном.Только то, что я не знаю, как это сделать, это uuid, потому что саксонец - он не поддерживает вызовы Java.Поэтому вместо uuid я использовал функцию generate-id().

<xsl:transform version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
               xpath-default-namespace="http://www.liquibase.org/xml/ns/dbchangelog">
    <xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/>

    <xsl:template match="node()|@*">
        <xsl:copy>
            <xsl:apply-templates select="node()|@*"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="changeSet[createTable]">
        <xsl:copy>
            <xsl:copy-of select="@*"/>
            <xsl:apply-templates select="createTable"/>
            <xsl:copy-of select="*[not(self::createTable)]"/>
        </xsl:copy>
        <xsl:element name="changeSet" namespace="http://www.liquibase.org/xml/ns/dbchangelog">
            <xsl:attribute name="id" select="generate-id()" />
            <xsl:attribute name="author">system</xsl:attribute>
            <xsl:element name="setTableRemarks" namespace="http://www.liquibase.org/xml/ns/dbchangelog">
                <xsl:attribute name="tableName" select="createTable//@tableName"/>
                <xsl:attribute name="remarks" select="createTable//@remarks"/>
            </xsl:element>
            <xsl:for-each select="createTable/column">
                <xsl:element name="setColumnRemarks" namespace="http://www.liquibase.org/xml/ns/dbchangelog">
                    <xsl:attribute name="tableName" select="../@tableName"/>
                    <xsl:attribute name="columnName" select="@name"/>
                    <xsl:attribute name="remarks" select="@remarks"/>
                </xsl:element>
            </xsl:for-each>
        </xsl:element>
    </xsl:template>

    <xsl:template match="createTable/@remarks"/>
    <xsl:template match="createTable/column/@remarks"/>

</xsl:transform>

Для преобразований я использую Saxon-HE:9.8.0-12 (java)

1 Ответ

0 голосов
/ 22 сентября 2018

UUID может быть реализован в XSLT.

Например, это было реализовано в этой таблице стилей: https://gist.github.com/azinneera/778f69ae6b0049b5edcd69da70072405,, которую можно включить или импортировать, а затем использовать метод uuid:get-uuid().

Предполагая, что он был сохранен локальнокак uuid-gen.xsl, примененный к вашей таблице стилей:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0"
    xmlns:xs="http://www.w3.org/2001/XMLSchema" 
    xmlns:uuid="http://www.uuid.org" 
    xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
    xpath-default-namespace="http://www.liquibase.org/xml/ns/dbchangelog">
    <xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/>

    <xsl:include href="uuid-gen.xsl"/>

    <xsl:template match="node()|@*">
        <xsl:copy>
            <xsl:apply-templates select="node()|@*"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="changeSet[createTable]">
        <xsl:copy>
            <xsl:copy-of select="@*"/>
            <xsl:apply-templates select="createTable"/>
            <xsl:copy-of select="*[not(self::createTable)]"/>
        </xsl:copy>
        <changeSet id="{uuid:get-uuid(.)}" author="system">
            <setTableRemarks>
                <xsl:copy-of select="createTable//(@tableName,@remarks)"/>
            </setTableRemarks>
            <xsl:for-each select="createTable/column">
                <setColumnRemarks>
                    <xsl:copy-of select="../@tableName"/>
                    <xsl:attribute name="columnName" select="@name"/>
                    <xsl:copy-of select="@remarks"/>
                </setColumnRemarks>
            </xsl:for-each>
        </changeSet>
    </xsl:template>

    <xsl:template match="createTable/@remarks"/>
    <xsl:template match="createTable/column/@remarks"/>  
</xsl:stylesheet>
...