没有节点的XSLT复制输出和密钥上的过滤器

时间:2016-03-27 14:52:45

标签: xml xslt

XML输入:

<root>
    <results>
        <output>
            <tag1>
                <tag2>
                    <tag3>
                        <tag4>2016-03-27T14:27:10.542+03:00</tag4>
                    </tag3>
                    <tag5/>
                    <tag6>
                        <record>
                            <column name="Result">smth</column>
                        </record>
                    </tag6>
                </tag2>
            </tag1>
        </output>
    </results>
    <DesiredParentTag UserName="admin" UserId="1" timestamp="2016-03-27T17:06:10.764+03:00">
        <DesiredChildTag operation="delete">
            <action startInstant="2016-03-30T08:35:00+03:00" id="244078"/>
            <action startInstant="2016-03-29T08:35:00+03:00" id="244078"/>
        </DesiredChildTag>
        <DesiredChildTag operation="insert">
            <action id="2" startInstant="2016-03-21T08:35:00+03:00"/>
        </DesiredChildTag>
        <DesiredChildTag operation="update">
            <action id="222" startInstant="2016-03-21T08:35:00+03:00"/>
            <action id="45" startInstant="2016-03-21T08:35:00+03:00"/>
        </actions>
    </DesiredParentTag>
</root>

所需的XML输出:

    <DesiredParentTag UserName="admin" UserId="1" timestamp="2016-03-27T17:06:10.764+03:00">
        <DesiredChildTag operation="delete">
            <action startInstant="2016-03-30T08:35:00+03:00" id="244078"/>
            <!--excluded duplicate id if operation='delete'-->
        </DesiredChildTag>
        <DesiredChildTag operation="insert">
            <action id="2" startInstant="2016-03-21T08:35:00+03:00"/>
        </DesiredChildTag>
        <DesiredChildTag operation="update">
            <action id="222" startInstant="2016-03-21T08:35:00+03:00"/>
            <action id="45" startInstant="2016-03-21T08:35:00+03:00"/>
        </actions>
    </DesiredParentTag>

我想复制&#34; DesiredParentTag&#34;下的所有内容。如果操作=&#34;删除&#34;排除具有相同ID的操作标记。其他只是定期复制。

我当前的xsl :(它会复制我需要的标签和属性,但如果attirbute操作=&#39;删除&#39;则不会重复删除重复项)

<xsl:key name="ok" match="DesiredParentTag/DesiredChildTag/action" use="@id"/>
<xsl:template match="*">

    <xsl:copy-of select="DesiredParentTag[count(key('ok',@id)[1]|.)=1]"/>

</xsl:template>

</xsl:stylesheet>

1 个答案:

答案 0 :(得分:1)

使用不复制重复项的样式表:

<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">

    <xsl:key name="id" match="DesiredChildTag[@operation = 'delete']/action" use="concat(generate-id(..), '|', @id)"/>

    <xsl:template match="/">
        <xsl:apply-templates select="//DesiredParentTag"/>
    </xsl:template>

    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="DesiredChildTag[@operation = 'delete']/action[not(generate-id() = generate-id(key('id', concat(generate-id(..), '|', @id))[1]))]"/>

</xsl:transform>

http://xsltransform.net/6r5Gh47在线。

或者在XSLT 2.0版本中:

<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">

    <xsl:key name="id" match="DesiredChildTag[@operation = 'delete']/action" use="@id"/>

    <xsl:template match="/">
        <xsl:apply-templates select="//DesiredParentTag"/>
    </xsl:template>

    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="DesiredChildTag[@operation = 'delete']/action[not(. is key('id', @id, ..)[1])]"/>

</xsl:transform>

http://xsltransform.net/6r5Gh47/1