【问题标题】:XSLT remove empty xmlns when using call-templateXSLT 在使用调用模板时删除空 xmlns
【发布时间】:2018-06-26 07:46:47
【问题描述】:

这是我的示例 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 模板创建输出文件时,文件中的输出元素&lt;changeSet&gt; 具有空的xmlns="" 属性。请问我怎样才能删除它?或者,如果有办法如何使用它的命名空间定义 xml 标头 &lt;databaseChangeLog,然后告诉 call-template 使用它可能会有所帮助(但我不知道它是否像这样工作)。

我正在使用 xslt 2.0 和 saxon 9.8he

【问题讨论】:

  • 在您的 XSLT 中,您正在引用未在任何地方声明的变量(例如 $coreTablesVariable)。你能纠正这个吗?谢谢。
  • 抱歉,我从另一个示例中复制了部分模板。固定。

标签: xslt saxon


【解决方案1】:

您有一个从元素中删除命名空间的模板

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

【讨论】:

  • 那个技巧with-param 和其他变量的连接是超级正确的。我正在使用concat 函数,但这对我不起作用。再次感谢您。
  • 我可以在这个帖子中提问吗?请问我可以在不破坏命名空间等的情况下为每个changeSet 添加属性吗?我试图添加另一个与databaseChangelog/changeSet 匹配的模板,但这并不是在所有地方都有效。我主要对输出文件感兴趣。
  • 是的,您可以添加属性。您可能需要在模板上使用mode。如果你不能让它工作,你应该问一个全新的问题。谢谢!
猜你喜欢
  • 2015-11-16
  • 1970-01-01
  • 1970-01-01
  • 2015-12-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多