【问题标题】:xslt 2 copy parent element based on input array with loopxslt 2基于带循环的输入数组复制父元素
【发布时间】:2018-06-22 14:00:43
【问题描述】:

我有以下 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>

我想选择整个changeSet 元素,其中tableName 属性将匹配$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 进行转换。

【问题讨论】:

    标签: xslt saxon


    【解决方案1】:

    您应该使用xsl:copy-of,而不是只输出节点的字符串值的xsl:value-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>
    

    【讨论】:

    • 不错的一个...我会在可能的情况下立即接受(5 分钟内:D)。你能再告诉我一件事吗?我目前在源 xml 中使用 http://www.example.com 作为命名空间。因此,为此我将xpath-default-namespace="http://www.example.com" 添加到xsl:transform 和copy-namespaces="no" 到xsl:copy,但是仍然复制默认的xmlns=...。是否也可以禁用此功能?
    • 见stackoverflow.com/questions/11188403/…。而不是使用xsl:copy-of 使用xsl:apply-templates 并添加该问题中显示的模板
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-08
    • 1970-01-01
    • 1970-01-01
    • 2019-09-03
    • 2017-05-19
    • 2011-02-16
    相关资源
    最近更新 更多