2012-03-09 49 views
0

是否可以在特定字段上进行过滤,然后当两个字段相同时,只允许通过这两个层次。我的意思是:XSLT只允许重复记录

输入数据:

<?xml version="1.0" encoding="UTF-8"?> 
<payload> 
    <set> 
     <field1>compare</field1> 
     <field2>info</field2> 
     <field3>more infor</field3> 
    </set> 
    <set> 
     <field4>compare</field4> 
     <field5>put through</field5> 
     <field6>this too</field6> 
    </set> 
    <set> 
     <field1>compare1</field1> 
     <field2>info</field2> 
     <field3>more infor</field3> 
    </set> 
    <set> 
     <field4>compare2</field4> 
     <field5>put through</field5> 
     <field6>this too</field6> 
    </set> 
    <set> 
     <field1>compare2</field1> 
     <field2>info</field2> 
     <field3>more infor</field3> 
    </set> 
</payload> 

然后比较字段1到信德的内容是相同的,所以“比较”和“比较2”,只有让那些四个通,因此输出看起来是这样的:

<?xml version="1.0" encoding="UTF-8"?> 
<payload> 
    <set> 
     <field1>compare</field1> 
     <field2>info</field2> 
     <field3>more infor</field3> 
    </set> 
    <set> 
     <field4>compare</field4> 
     <field5>put through</field5> 
     <field6>this too</field6> 
    </set> 
    <set> 
     <field4>compare2</field4> 
     <field5>put through</field5> 
     <field6>this too</field6> 
    </set> 
    <set> 
     <field1>compare2</field1> 
     <field2>info</field2> 
     <field3>more infor</field3> 
    </set> 
</payload> 

您将如何编写XSLT进行比较,只通过匹配?

回答

2

是否要将每个set元素的第一个子元素与其他set元素的第一个子元素进行比较? 如果我的理解是正确的,然后用XSLT 1.0,你可以使用一键作为

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

<xsl:key name="k1" match="set" use="*[1]"/> 

<xsl:strip-space elements="*"/> 
<xsl:output indent="yes"/> 

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

<xsl:template match="payload"> 
    <xsl:copy> 
    <xsl:apply-templates select="set[key('k1', *[1])[2]]"/> 
    </xsl:copy> 
</xsl:template> 

</xsl:stylesheet> 

使用XSLT 2.0,你可以做到这一点甚至更短:

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

<xsl:key name="k1" match="set" use="*[1]"/> 

<xsl:strip-space elements="*"/> 
<xsl:output indent="yes"/> 

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

<xsl:template match="set[not(key('k1', *[1])[2])]"/> 

</xsl:stylesheet> 
+0

非常感谢你这工作就像一种享受,我可以问一个简单的问题吗?我明白你的匹配节点“设置”,但是什么是* [1]。这是元素位置? AKA在每一集中的第一场? – MMKD 2012-03-09 11:46:41

+0

'*'是'child :: *'的缩写,所以它选择所有子元素,'[1]'是一个位置谓词来选择节点集或序列中的第一项,所以'* [1]'选择第一个上下文节点的子元素。我这样做是因为在你的例子中有'set'元素,其中第一个子元素被命名为'field1',而其他的元素被命名为'field4',用于比较独立于代码根据位置进行比较的元素名称(即第一个子元素)。 – 2012-03-09 12:09:41

+0

这很有道理。对不起还有一个问题,我得到'match =“set”use =“* [1]”'查找第一个元素。但是,如果我改变它说一个2所以'匹配=“设置”使用=“* [2]”'因此寻找第二个字段匹配。为什么这必须改为3? ''','[3]'是什么意思? – MMKD 2012-03-09 12:16:56