xslt - XSLT 将属性从节点转换为另一个节点的元素并将它们从源节点中删除
问题描述
给定这个 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
,在新的 changeSet 中使用 UUID生成 - 如果可能,在当前修改的 changeSet 之后添加新创建的 changeSet
所以最后它应该是这样的:
<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,因为 saxon-he 不支持对 java 的调用。因此,我使用了generate-id()
函数而不是 uuid。
<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)
解决方案
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>
推荐阅读
- python - 获取与 GMT 时差的时区列表
- ios - 在离子上删除和添加平台后的问题
- html - 标签是什么
我目前正在尝试学习 HTML,但我对链接元素有疑问:
<link rel="author" href="URL">
. 这个元素有什么作用?我的书说:
在文档和作者(文档)之间建立关系。
但这究竟意味着什么?
我网站的访问者看
- python - 如何在给定约束后删除文本?
- laravel - 如果未加载关系,则阻止数据库查询
- javascript - 如何使 Nicescroll 仅适用于某些屏幕尺寸(770 像素及以上)
- python - python2.7中处理UnicodeEncodeError
- time-series - 为什么简单的指数平滑会为不同的观察结果返回相同的预测
- java - 从自定义列表视图中获取每个选中的项目
- arrays - 创建具有多个元素的 Bash 数组