XSLT 在使用 call-template 时删除空的 xmlns
XSLT remove empty xmlns when using call-template
这是我的样本xml:
<?xml version="1.0" encoding="UTF-8"?>
<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
http://www.liquibase.org/xml/ns/dbchangelog">
<changeSet id="1" author="a">
<createTable tableName="TABLE1">
<column>
</column>
</createTable>
</changeSet>
<changeSet id="1-1" author="a">
<createSequence sequenceName="SEQ_TABLE1" />
</changeSet>
<changeSet id="4" author="A">
<createTable tableName="TABLE4">
<column>
</column>
</createTable>
</changeSet>
</databaseChangeLog>
这是我的模板:
<?xml version="1.0" encoding="UTF-8"?>
<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:variable name="coreTables" select="('TABLE1','TABLE2')"/>
<xsl:template match="node()[not(self::*)]">
<xsl:copy>
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>
<xsl:template match="*">
<xsl:element name="{local-name()}">
<xsl:apply-templates select="node()|@*"/>
</xsl:element>
</xsl:template>
<xsl:template match="@*">
<xsl:attribute name="{local-name()}">
<xsl:value-of select="."/>
</xsl:attribute>
</xsl:template>
<xsl:template match="databaseChangeLog">
<!-- CORE-->
<xsl:comment>CORE TABLES</xsl:comment>
<xsl:variable name="coreTablesVariable" select="changeSet[createTable/@tableName=$coreTables]"/>
<xsl:apply-templates select="$coreTablesVariable"/>
<xsl:comment>CORE SEQUENCES</xsl:comment>
<xsl:variable name="coreSequencesVariable" select="changeSet[createSequence[starts-with(@sequenceName, 'SEQ_') and substring-after(@sequenceName, 'SEQ_') = $coreTables]]"/>
<xsl:apply-templates select="$coreSequencesVariable"/>
<xsl:comment>CORE INDEXES</xsl:comment>
<xsl:variable name="coreIndexesVariable" select="changeSet[createIndex/@tableName=$coreTables]"/>
<xsl:apply-templates select="$coreIndexesVariable"/>
<xsl:comment>CORE FOREIGN CONSTRAINTS</xsl:comment>
<xsl:variable name="coreForeignConstraintsVariable" select="changeSet[addForeignKeyConstraint/@baseTableName=$coreTables]"/>
<xsl:apply-templates select="$coreForeignConstraintsVariable"/>
<xsl:comment>CORE VIEWS</xsl:comment>
<xsl:variable name="coreViewsVariable" select="changeSet[createView/@viewName=$coreTables]"/>
<xsl:apply-templates select="$coreViewsVariable"/>
<xsl:call-template name="createChangeLog">
<xsl:with-param name="outputFile" select="'core-changelog.xml'"/>
<xsl:with-param name="changeLogContent">
<xsl:apply-templates select="$coreTablesVariable"/>
<xsl:apply-templates select="$coreSequencesVariable"/>
<xsl:apply-templates select="$coreIndexesVariable"/>
<xsl:apply-templates select="$coreForeignConstraintsVariable"/>
<xsl:apply-templates select="$coreViewsVariable"/>
</xsl:with-param>
</xsl:call-template>
</xsl:template>
<xsl:template name="createChangeLog">
<xsl:param name="outputFile"/>
<xsl:param name="changeLogContent"/>
<xsl:result-document encoding="UTF-8" indent="true" method="xml" href="{$outputFile}">
<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 http://www.liquibase.org/xml/ns/dbchangelog" logicalFilePath="TODO">
<xsl:apply-templates select="$changeLogContent"/>
</databaseChangeLog>
</xsl:result-document>
</xsl:template>
</xsl:transform>
问题是,当我通过调用 createChangeLog
模板创建输出文件时,文件中的输出元素 <changeSet>
具有空的 xmlns=""
属性。请问我怎样才能删除它?或者如果有什么方法可以用它的命名空间定义 xml header <databaseChangeLog
然后告诉 call-template 使用它可能会有所帮助(但我不知道是否它是这样工作的。
我正在使用 xslt 2.0 和 saxon 9.8he
您有一个从元素中删除命名空间的模板
<xsl:template match="*">
<xsl:element name="{local-name()}">
<xsl:apply-templates select="node()|@*"/>
</xsl:element>
</xsl:template>
这意味着,当您像这样设置 changeLogContent
参数时...
<xsl:with-param name="changeLogContent">
<xsl:apply-templates select="$coreTablesVariable"/>
<xsl:apply-templates select="$coreSequencesVariable"/>
<xsl:apply-templates select="$coreIndexesVariable"/>
<xsl:apply-templates select="$coreForeignConstraintsVariable"/>
<xsl:apply-templates select="$coreViewsVariable"/>
</xsl:with-param>
...它将使用此模板,因此被设置为没有命名空间的节点副本。
首先,您应该做的是将 xsl:with-param
更改为 select 原始节点,而不是创建副本...
<xsl:with-param name="changeLogContent" select="$coreTablesVariable,$coreSequencesVariable,$coreIndexesVariable,$coreForeignConstraintsVariable,$coreViewsVariable"/>
然后,在 createChangeLog
中,如果您真的想不做任何更改地复制节点,请使用 xsl:copy-of
而不是 xsl:apply-templates
(因为 xsl:apply-templates
只会匹配再次删除命名空间模板。
<xsl:copy-of select="$changeLogContent"/>
试试这两个模板
<xsl:template match="databaseChangeLog">
<!-- CORE-->
<xsl:comment>CORE TABLES</xsl:comment>
<xsl:variable name="coreTablesVariable" select="changeSet[createTable/@tableName=$coreTables]"/>
<xsl:apply-templates select="$coreTablesVariable"/>
<xsl:comment>CORE SEQUENCES</xsl:comment>
<xsl:variable name="coreSequencesVariable" select="changeSet[createSequence[starts-with(@sequenceName, 'SEQ_') and substring-after(@sequenceName, 'SEQ_') = $coreTables]]"/>
<xsl:apply-templates select="$coreSequencesVariable"/>
<xsl:comment>CORE INDEXES</xsl:comment>
<xsl:variable name="coreIndexesVariable" select="changeSet[createIndex/@tableName=$coreTables]"/>
<xsl:apply-templates select="$coreIndexesVariable"/>
<xsl:comment>CORE FOREIGN CONSTRAINTS</xsl:comment>
<xsl:variable name="coreForeignConstraintsVariable" select="changeSet[addForeignKeyConstraint/@baseTableName=$coreTables]"/>
<xsl:apply-templates select="$coreForeignConstraintsVariable"/>
<xsl:comment>CORE VIEWS</xsl:comment>
<xsl:variable name="coreViewsVariable" select="changeSet[createView/@viewName=$coreTables]"/>
<xsl:apply-templates select="$coreViewsVariable"/>
<xsl:call-template name="createChangeLog">
<xsl:with-param name="outputFile" select="'core-changelog.xml'"/>
<xsl:with-param name="changeLogContent" select="$coreTablesVariable,$coreSequencesVariable,$coreIndexesVariable,$coreForeignConstraintsVariable,$coreViewsVariable"/>
</xsl:call-template>
</xsl:template>
<xsl:template name="createChangeLog">
<xsl:param name="outputFile"/>
<xsl:param name="changeLogContent"/>
<xsl:result-document encoding="UTF-8" indent="true" method="xml" href="{$outputFile}">
<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 http://www.liquibase.org/xml/ns/dbchangelog" logicalFilePath="TODO">
<xsl:copy-of select="$changeLogContent"/>
</databaseChangeLog>
</xsl:result-document>
</xsl:template>
这是我的样本xml:
<?xml version="1.0" encoding="UTF-8"?>
<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
http://www.liquibase.org/xml/ns/dbchangelog">
<changeSet id="1" author="a">
<createTable tableName="TABLE1">
<column>
</column>
</createTable>
</changeSet>
<changeSet id="1-1" author="a">
<createSequence sequenceName="SEQ_TABLE1" />
</changeSet>
<changeSet id="4" author="A">
<createTable tableName="TABLE4">
<column>
</column>
</createTable>
</changeSet>
</databaseChangeLog>
这是我的模板:
<?xml version="1.0" encoding="UTF-8"?>
<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:variable name="coreTables" select="('TABLE1','TABLE2')"/>
<xsl:template match="node()[not(self::*)]">
<xsl:copy>
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>
<xsl:template match="*">
<xsl:element name="{local-name()}">
<xsl:apply-templates select="node()|@*"/>
</xsl:element>
</xsl:template>
<xsl:template match="@*">
<xsl:attribute name="{local-name()}">
<xsl:value-of select="."/>
</xsl:attribute>
</xsl:template>
<xsl:template match="databaseChangeLog">
<!-- CORE-->
<xsl:comment>CORE TABLES</xsl:comment>
<xsl:variable name="coreTablesVariable" select="changeSet[createTable/@tableName=$coreTables]"/>
<xsl:apply-templates select="$coreTablesVariable"/>
<xsl:comment>CORE SEQUENCES</xsl:comment>
<xsl:variable name="coreSequencesVariable" select="changeSet[createSequence[starts-with(@sequenceName, 'SEQ_') and substring-after(@sequenceName, 'SEQ_') = $coreTables]]"/>
<xsl:apply-templates select="$coreSequencesVariable"/>
<xsl:comment>CORE INDEXES</xsl:comment>
<xsl:variable name="coreIndexesVariable" select="changeSet[createIndex/@tableName=$coreTables]"/>
<xsl:apply-templates select="$coreIndexesVariable"/>
<xsl:comment>CORE FOREIGN CONSTRAINTS</xsl:comment>
<xsl:variable name="coreForeignConstraintsVariable" select="changeSet[addForeignKeyConstraint/@baseTableName=$coreTables]"/>
<xsl:apply-templates select="$coreForeignConstraintsVariable"/>
<xsl:comment>CORE VIEWS</xsl:comment>
<xsl:variable name="coreViewsVariable" select="changeSet[createView/@viewName=$coreTables]"/>
<xsl:apply-templates select="$coreViewsVariable"/>
<xsl:call-template name="createChangeLog">
<xsl:with-param name="outputFile" select="'core-changelog.xml'"/>
<xsl:with-param name="changeLogContent">
<xsl:apply-templates select="$coreTablesVariable"/>
<xsl:apply-templates select="$coreSequencesVariable"/>
<xsl:apply-templates select="$coreIndexesVariable"/>
<xsl:apply-templates select="$coreForeignConstraintsVariable"/>
<xsl:apply-templates select="$coreViewsVariable"/>
</xsl:with-param>
</xsl:call-template>
</xsl:template>
<xsl:template name="createChangeLog">
<xsl:param name="outputFile"/>
<xsl:param name="changeLogContent"/>
<xsl:result-document encoding="UTF-8" indent="true" method="xml" href="{$outputFile}">
<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 http://www.liquibase.org/xml/ns/dbchangelog" logicalFilePath="TODO">
<xsl:apply-templates select="$changeLogContent"/>
</databaseChangeLog>
</xsl:result-document>
</xsl:template>
</xsl:transform>
问题是,当我通过调用 createChangeLog
模板创建输出文件时,文件中的输出元素 <changeSet>
具有空的 xmlns=""
属性。请问我怎样才能删除它?或者如果有什么方法可以用它的命名空间定义 xml header <databaseChangeLog
然后告诉 call-template 使用它可能会有所帮助(但我不知道是否它是这样工作的。
我正在使用 xslt 2.0 和 saxon 9.8he
您有一个从元素中删除命名空间的模板
<xsl:template match="*">
<xsl:element name="{local-name()}">
<xsl:apply-templates select="node()|@*"/>
</xsl:element>
</xsl:template>
这意味着,当您像这样设置 changeLogContent
参数时...
<xsl:with-param name="changeLogContent">
<xsl:apply-templates select="$coreTablesVariable"/>
<xsl:apply-templates select="$coreSequencesVariable"/>
<xsl:apply-templates select="$coreIndexesVariable"/>
<xsl:apply-templates select="$coreForeignConstraintsVariable"/>
<xsl:apply-templates select="$coreViewsVariable"/>
</xsl:with-param>
...它将使用此模板,因此被设置为没有命名空间的节点副本。
首先,您应该做的是将 xsl:with-param
更改为 select 原始节点,而不是创建副本...
<xsl:with-param name="changeLogContent" select="$coreTablesVariable,$coreSequencesVariable,$coreIndexesVariable,$coreForeignConstraintsVariable,$coreViewsVariable"/>
然后,在 createChangeLog
中,如果您真的想不做任何更改地复制节点,请使用 xsl:copy-of
而不是 xsl:apply-templates
(因为 xsl:apply-templates
只会匹配再次删除命名空间模板。
<xsl:copy-of select="$changeLogContent"/>
试试这两个模板
<xsl:template match="databaseChangeLog">
<!-- CORE-->
<xsl:comment>CORE TABLES</xsl:comment>
<xsl:variable name="coreTablesVariable" select="changeSet[createTable/@tableName=$coreTables]"/>
<xsl:apply-templates select="$coreTablesVariable"/>
<xsl:comment>CORE SEQUENCES</xsl:comment>
<xsl:variable name="coreSequencesVariable" select="changeSet[createSequence[starts-with(@sequenceName, 'SEQ_') and substring-after(@sequenceName, 'SEQ_') = $coreTables]]"/>
<xsl:apply-templates select="$coreSequencesVariable"/>
<xsl:comment>CORE INDEXES</xsl:comment>
<xsl:variable name="coreIndexesVariable" select="changeSet[createIndex/@tableName=$coreTables]"/>
<xsl:apply-templates select="$coreIndexesVariable"/>
<xsl:comment>CORE FOREIGN CONSTRAINTS</xsl:comment>
<xsl:variable name="coreForeignConstraintsVariable" select="changeSet[addForeignKeyConstraint/@baseTableName=$coreTables]"/>
<xsl:apply-templates select="$coreForeignConstraintsVariable"/>
<xsl:comment>CORE VIEWS</xsl:comment>
<xsl:variable name="coreViewsVariable" select="changeSet[createView/@viewName=$coreTables]"/>
<xsl:apply-templates select="$coreViewsVariable"/>
<xsl:call-template name="createChangeLog">
<xsl:with-param name="outputFile" select="'core-changelog.xml'"/>
<xsl:with-param name="changeLogContent" select="$coreTablesVariable,$coreSequencesVariable,$coreIndexesVariable,$coreForeignConstraintsVariable,$coreViewsVariable"/>
</xsl:call-template>
</xsl:template>
<xsl:template name="createChangeLog">
<xsl:param name="outputFile"/>
<xsl:param name="changeLogContent"/>
<xsl:result-document encoding="UTF-8" indent="true" method="xml" href="{$outputFile}">
<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 http://www.liquibase.org/xml/ns/dbchangelog" logicalFilePath="TODO">
<xsl:copy-of select="$changeLogContent"/>
</databaseChangeLog>
</xsl:result-document>
</xsl:template>