XSLT добавляет атрибуты к обработанным узлам с выводом в result-document - PullRequest
0 голосов
/ 26 июня 2018

это образец 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:comment>CORE SEQUENCES</xsl:comment>
    <xsl:variable name="coreSequencesVariable" select="changeSet[createSequence[starts-with(@sequenceName, 'SEQ_') and substring-after(@sequenceName, 'SEQ_') = $coreTables]]"/>
    <xsl:comment>CORE INDEXES</xsl:comment>
    <xsl:variable name="coreIndexesVariable" select="changeSet[createIndex/@tableName=$coreTables]"/>
    <xsl:comment>CORE FOREIGN CONSTRAINTS</xsl:comment>
    <xsl:variable name="coreForeignConstraintsVariable" select="changeSet[addForeignKeyConstraint/@baseTableName=$coreTables]"/>
    <xsl:comment>CORE VIEWS</xsl:comment>
    <xsl:variable name="coreViewsVariable" select="changeSet[createView/@viewName=$coreTables]"/>
    <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>
</xsl:transform>

Я бы хотел добавить к выводу xml, обработанному внутри createChangelogTemplate, к каждому элементу <changeSet> другой атрибут (context="legacy"). Я пытался добавить другой шаблон, который соответствует databaseChangelog/changeSet с дополнительным элементом xsl:attribute, но это не сработало для меня. Если есть способ, как сделать это в одном месте, это было бы неплохо, потому что мне нужно будет подготовить больше разделов, таких как CORE.

Я использую xslt 2.0 и саксонский 9.8he.

1 Ответ

0 голосов
/ 26 июня 2018

Используйте отдельный mode, т. Е. Вместо <xsl:copy-of select="$changeLogContent"/> используйте <xsl:apply-templates select="$changeLogContent" mode="legacy"/>, затем настройте, например,

<xsl:template match="changeSet" mode="legacy">
  <xsl:copy>
    <xsl:copy-of select="@*"/>
    <xsl:attribute name="context">legacy</xsl:attribute>
    <xsl:copy-of select="node()"/>
  </xsl:copy>
</xsl:template>

Если необходима дальнейшая обработка атрибутов и / или дочерних узлов, измените <xsl:copy-of select="@*"/> и / или <xsl:copy-of select="node()"/> для использования xsl:apply-templates mode="#current" и настройки дополнительных шаблонов для режима, выполняющего любую обработку.

...