如果某些条件匹配,则XSL复制节点

时间:2017-02-02 13:50:45

标签: xml xslt

我有这个伪xml:

<?xml version="1.0" encoding="UTF-8"?>
<comtec version="2010">
<query name="rgh/TestNTV/ABC">
    <vars>
        <parameter name="ids">1,2,3,4</parameter>
    </vars>
    <err/>
    <Results>
        <record id="1">
            <column name="id_task">1</column>
            <column name="capabilityCode">FR1</column>
            <column name="ColMiss">miss</column>
            <column name="ColHave"/>
        </record>
        <record id="2">
            <column name="id_task">1</column>
            <column name="capabilityCode">FR2</column>
            <column name="ColMiss"/>
            <column name="ColHave">notmiss</column>
        </record>
        <record id="3">
            <column name="id_task">2</column>
            <column name="capabilityCode">D2</column>
            <column name="ColMiss">miss</column>
            <column name="ColHave"/>
        </record>
        <record id="4">
            <column name="id_task">2</column>
            <column name="capabilityCode">F3</column>
            <column name="ColMiss">miss</column>
            <column name="ColHave"/>
        </record>
        <record id="5">
            <column name="id_task">3</column>
            <column name="capabilityCode">SD21</column>
            <column name="ColMiss"/>
            <column name="ColHave">notmiss</column>
        </record>
        <record id="6">
            <column name="id_task">4</column>
            <column name="capabilityCode">XXX</column>
            <column name="ColMiss">miss</column>
            <column name="ColHave"/>
        </record>
    </Results>
</query>
</comtec>

期望的输出:

<Results>
<record id="1">
    <column name="id_task">1</column>
    <column name="capabilityCode">FR1</column>
    <column name="ColMiss">miss</column>
    <column name="ColHave"/>
</record>
<record id="2">
    <column name="id_task">1</column>
    <column name="capabilityCode">FR2</column>
    <column name="ColMiss"/>
    <column name="ColHave">notmiss</column>
</record>
<record id="3">
    <column name="id_task">2</column>
    <column name="capabilityCode">D2</column>
    <column name="ColMiss">miss</column>
    <column name="ColHave"/>
</record>
<record id="4">
    <column name="id_task">2</column>
    <column name="capabilityCode">F3</column>
    <column name="ColMiss">miss</column>
    <column name="ColHave"/>
</record>
<record id="6">
    <column name="id_task">4</column>
    <column name="capabilityCode">XXX</column>
    <column name="ColMiss">miss</column>
    <column name="ColHave"/>
</record>
</Results>

基本上我想复制每个&#34;记录&#34;每个ID的标记,包含&#34; ColMiss&#34; NOT NULL或(&#34; ColMiss&#34; not null和&#34; ColHave&#34; not null)的组合。更确切地说,如果我的id_task正在重新开始(如示例中所示)并且它有2个记录,其中一个记录是ColMiss&#34;不是null并且另一条记录与CollMiss null但是ColHave不为null我想要复制&#34;记录&#34;供参考。 如果我的任务只有&#34; ColMiss&#34;不是null然后我想复制它的所有记录 如果我的任务只有&#34; ColHave&#34;然后我不想要那些信息。

换句话说,如果一个ID错过了&#39;然后复制该ID的所有记录,如果ID没有错过&#39;然后不要复制。

有人告诉我这应该用变量完成吗? 非常感谢你的帮助

UPDATE; 当前的XSL

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:template match="@*|node()">
    <comtec>
        <xsl:for-each select="//record">
            <xsl:variable name="var_id2">
                <xsl:value-of select="column[@name='ColMiss']"/>
            </xsl:variable>
            <xsl:variable name="var_id3">
                <xsl:value-of select="column[@name='ColHave']"/>
            </xsl:variable>
            <xsl:if test="($var_id2 !='') ">
                <xsl:variable name="var_id">
                    <xsl:value-of select="column[@name='id_task']"/>
                </xsl:variable>
                <record>
                    <xsl:copy-of select="node()"/>
                </record>
            </xsl:if>
        </xsl:for-each>
    </comtec>
</xsl:template>
</xsl:stylesheet>

这会选择所有记录(但没有属性&#34; ID&#34;我需要它)但是它并没有复制我示例中id_task = 1的所有记录,显然为什么但我不会&#39 ;知道如何从这里开始做出预期的结果。

1 个答案:

答案 0 :(得分:0)

此处不需要变量,但您可以使用密钥按ID查找record元素,这样您就可以受益

<xsl:key name="record" match="record" use="column[@name='id_task']" />

然后只是选择record元素的情况,其中id的键中的记录指定了ColMiss

试试这个XSLT

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>

<xsl:key name="record" match="record" use="column[@name='id_task']" />

<xsl:template match="@*|node()">
    <comtec>
        <xsl:copy-of select="//record[key('record', column[@name='id_task'])/column[@name='ColMiss'][normalize-space()]]" />
    </comtec>
</xsl:template>
</xsl:stylesheet>

请注意,这不是完全有效的,因为您将检查该集合中每个记录的相同节点集。相反,您无法使用名为Muenchian grouping的技术,因此您只需对每组中的第一条记录执行ColMiss检查

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>

<xsl:key name="record" match="record" use="column[@name='id_task']" />

<xsl:template match="@*|node()">
    <comtec>
        <xsl:for-each select="//record
                                [generate-id() = generate-id(key('record', column[@name='id_task'])[1])]
                                [key('record', column[@name='id_task'])/column[@name='ColMiss'][normalize-space()]]">
            <xsl:copy-of select="key('record', column[@name='id_task'])" />
        </xsl:for-each>
    </comtec>
</xsl:template>
</xsl:stylesheet>