代码之家  ›  专栏  ›  技术社区  ›  bilak

使用调用模板时xslt删除空xmlns

  •  1
  • bilak  · 技术社区  · 6 年前

    这是我的示例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头 <databaseChangeLog 使用它的名称空间,然后告诉调用模板使用它可能会有帮助(但我不知道它是否像这样工作)。

    我使用的是xslt 2.0和saxon 9.8he

    1 回复  |  直到 6 年前
        1
  •  0
  •   Tim C    6 年前

    您有一个从元素中移除名称空间的模板

    <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 为此,要选择原始节点,而不是创建副本…

      <xsl:with-param name="changeLogContent" select="$coreTablesVariable,$coreSequencesVariable,$coreIndexesVariable,$coreForeignConstraintsVariable,$coreViewsVariable"/>
    

    然后,在 createChangeLog ,如果确实要在不做更改的情况下复制节点,请使用 xsl:copy-of 而不是 xsl:apply-templates (因为 xsl:apply模板 只需再次匹配命名空间移除模板。

    <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>