我的xml文件的结构如下:
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
<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" id="65D7AFA9-17F1-4406-997E-D2B42A0E9008" dbms="oracle">
<sql>GRANT SELECT,INSERT,UPDATE,DELETE ON ${dbSchema}.CATALOG TO ${appUser}</sql>
<rollback>REVOKE SELECT,INSERT,UPDATE,DELETE ON ${dbSchema}.CATALOG FROM ${appUser}</rollback>
</changeSet>
<changeSet author="system" id="E2731435-DCEE-4B7E-BA60-20A87E75227A" dbms="oracle">
<sql>GRANT SELECT,INSERT,UPDATE,DELETE ON ${dbSchema}.CATALOGATTRIBUTE TO ${appUser}</sql>
<rollback>REVOKE SELECT,INSERT,UPDATE,DELETE ON ${dbSchema}.CATALOGATTRIBUTE FROM ${appUser}</rollback>
</changeSet>
<changeSet author="system" id="65D7AFA9-17F1-4406-997E-D2B42A0E9008" dbms="oracle">
<createTable ...>
</changeSet>
</databaseChangeLog>
我想将其中sql包含changeSet
之一的所有tables
输出到一个文档,并将所有其他(不包含表名)输出到另一文档。我正在考虑将内容附加到变量,最后打印两个变量,但这不起作用(或者我不知道如何进一步处理)。
<xsl:transform version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xpath-default-namespace="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:uuid="http://uuid.util.java"
exclude-result-prefixes="uuid">
<xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/>
<xsl:variable name="tables"
select="('CATALOG','CATALOGATTRIBUTE','EVENTTYPES')"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="changeSet[sql]">
<xsl:variable name="changeSet" select="."/>
<xsl:variable name="sql" select="sql"/>
<xsl:for-each select="$tables">
<!--<xsl:variable name="selected" select="sql[contains(text(),concat('${dbSchema}.', ., ' '))]"/>-->
<xsl:variable name="tableName">
<xsl:value-of select="."/>
<xsl:value-of select="' '"/>
</xsl:variable>
<xsl:choose>
<xsl:when test="contains($sql, $tableName)">
<xsl:copy-of select="$changeSet"/>
</xsl:when>
<xsl:otherwise>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
</xsl:template>
</xsl:transform>
我能以某种方式收集所有与changeSet
匹配的tables
,然后收集所有changeSets
不匹配的东西吗?
ps:我正在使用Saxon-HE-9.8.0-14进行处理。
谢谢
答案 0 :(得分:0)
请考虑以下简化示例:
XML
<databaseChangeLog>
<changeSet>
<sql>ALPHA,BRAVO,CHARLIE</sql>
</changeSet>
<changeSet>
<sql>BRAVO,CHARLIE,DELTA</sql>
</changeSet>
<changeSet>
<sql>DELTA,ECHO,FOXTROT</sql>
</changeSet>
<changeSet>
<sql>FOXTROT,GOLF,HOTEL</sql>
</changeSet>
</databaseChangeLog>
XSLT 2.0
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:param name="tables" select="('BRAVO', 'GOLF')"/>
<xsl:template match="/databaseChangeLog">
<xsl:variable name="group1" select="changeSet[some $t in $tables satisfies contains(sql, $t)]" />
<xsl:copy>
<group1>
<xsl:copy-of select="$group1"/>
</group1>
<group2>
<xsl:copy-of select="changeSet except $group1"/>
</group2>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
结果
<?xml version="1.0" encoding="UTF-8"?>
<databaseChangeLog>
<group1>
<changeSet>
<sql>ALPHA,BRAVO,CHARLIE</sql>
</changeSet>
<changeSet>
<sql>BRAVO,CHARLIE,DELTA</sql>
</changeSet>
<changeSet>
<sql>FOXTROT,GOLF,HOTEL</sql>
</changeSet>
</group1>
<group2>
<changeSet>
<sql>DELTA,ECHO,FOXTROT</sql>
</changeSet>
</group2>
</databaseChangeLog>
演示:https://xsltfiddle.liberty-development.net/jyRYYiP
更好的解决方案是使用tokenize()
:
XSLT 2.0
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:param name="tables" select="('BRAVO', 'GOLF')"/>
<xsl:template match="/databaseChangeLog">
<xsl:variable name="group1" select="changeSet[tokenize(sql, ',') = $tables]" />
<xsl:copy>
<group1>
<xsl:copy-of select="$group1"/>
</group1>
<group2>
<xsl:copy-of select="changeSet except $group1"/>
</group2>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>