2013-08-28 74 views
2

我有以下数据XSL - 如何比较2组节点?

<parent> 
    <child>APPLES</child> 
    <child>APPLES</child> 
    <child>APPLES</child> 
</parent> 
<parent> 
    <child>APPLES</child> 
    <child>BANANA</child> 
    <child>APPLES</child> 
</parent> 

有一个简单的方法来比较的父节点?或者我将不得不在每个for-each中嵌套for-each,并使用position()手动测试每个孩子?

+0

你想要什么输出? –

+0

在我的数据中有30多个节点,我正在通过查看每个节点。我想知道当前父项的子节点何时与以前的父项不同。 E.G,它可以是X X X,然后是X X X,然后是Y X Y.我想知道这是什么时候发生的。 –

回答

2

XSLT 2.0具有的功能http://www.w3.org/TR/2013/CR-xpath-functions-30-20130521/#func-deep-equal所以可以编写一个模板

<xsl:template match="parent[deep-equal(., preceding-sibling::parent[1])]">...</xsl:template> 

处理那些parent元素等于其前面的同级parent

如果你想用XSLT 1.0做到这一点,然后你用纯文本内容的子元素序列的简单的情况下,它应该足以编写模板

<xsl:template match="parent" mode="sig"> 
    <xsl:for-each select="*"> 
    <xsl:if test="position() &gt; 1">|</xsl:if> 
    <xsl:value-of select="."/> 
    </xsl:for-each> 
</xsl:template> 

,然后使用它,如下所示:

<xsl:template match="parent"> 
    <xsl:variable name="this-sig"> 
    <xsl:apply-templates select="." mode="sig"/> 
    </xsl:variable> 
    <xsl:variable name="pre-sig"> 
    <xsl:apply-templates select="preceding-sibling::parent[1]" mode="sig"/> 
    </xsl:variable> 
    <!-- now compare e.g. --> 
    <xsl:choose> 
    <xsl:when test="$this-sig = $pre-sig">...</xsl:when> 
    <xsl:otherwise>...</xsl:otherwise> 
    </xsl:choose> 
</xsl:template> 

对于更复杂的内容,你需要细化模板计算“签名”串的实施,你可能想在网上搜索,我相信Dimitre Novatchev已经张贴在早期,类似的问题的解决方案。

+0

感谢您的回复,但不幸的是我仅限于XSLT 1.0 –

+0

在这种情况下,您必须通过递归模板实现一个等价物,该模板将两个节点作为其参数进行比较。 XPath 2.0 deep-equal()的规范可能被证明是有用的。 –

+0

@DerekHo,我已经添加了一些关于如何与XSLT 1.0进行比较的建议。 –