xslt 2基于带有循环的输入数组复制父元素

时间:2018-06-22 14:00:44

标签: xslt saxon

我有以下xml:

<?xml version="1.1" encoding="UTF-8" standalone="no"?>
<databaseChangeLog>
    <changeSet id="1" author="a">
        <createTable tableName="TABLE1">
            <column></column>
        </createTable>
    </changeSet>
    <changeSet id="2" author="A">
        <createTable tableName="TABLE2">
            <column></column>
        </createTable>
    </changeSet>
    <changeSet id="3" author="A">
        <createTable tableName="TABLE3">
            <column></column>
        </createTable>
    </changeSet>
    <changeSet id="4" author="A">
        <createTable tableName="TABLE4">
            <column></column>
        </createTable>
    </changeSet>
</databaseChangeLog>

这是我的xslt:

<xsl:transform version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/>

    <xsl:variable name="tables" select="('TABLE1','TABLE4')"/>

    <xsl:template match="databaseChangeLog">
        <xsl:for-each select="changeSet/createTable">
            <xsl:if test="@tableName=$tables">
                <xsl:value-of select="../changeSet"/>
            </xsl:if>
        </xsl:for-each>
    </xsl:template>

</xsl:transform>

我想选择tableName属性将与changeSet数组值之一匹配的整个$tables元素。因此,在这种情况下,应该输出如下内容:

<changeSet id="1" author="a">
    <createTable tableName="TABLE1">
        <column></column>
    </createTable>
</changeSet>

<changeSet id="4" author="A">
    <createTable tableName="TABLE4">
        <column></column>
    </createTable>
</changeSet>

我正在使用saxon 9.8he进行转换。

1 个答案:

答案 0 :(得分:1)

您应该使用xsl:value-of,而不是仅输出节点的字符串值的xsl:copy-of。而且,您还需要选择..来获取父项(执行../changeSet会尝试获取名为changeSet的同级元素)

<xsl:template match="databaseChangeLog">
    <xsl:for-each select="changeSet/createTable">
        <xsl:if test="@tableName=$tables">
            <xsl:copy-of select=".."/>
        </xsl:if>
    </xsl:for-each>
</xsl:template>

请注意,您可以将其简化为此...

<xsl:template match="databaseChangeLog">
    <xsl:for-each select="changeSet/createTable[@tableName=$tables]">
        <xsl:copy-of select=".."/>
    </xsl:for-each>
</xsl:template>

甚至就是这个...

<xsl:template match="databaseChangeLog">
    <xsl:copy-of select="changeSet[createTable/@tableName=$tables]" />
</xsl:template>