2015-04-23 85 views
0

我想使用XSLT转换下面的XML:删除连续节点具有相同名称的

<level> 
    <nextlevel> 
     <note> text text text </note> 
    </nextlevel> 
    <nextlevel> 
     <abc> 
     </abc> 
     <note>bla bla bla </note> 
     <note>bla bla bla bla bla</note> 
     <xyz> 
     </xyz> 
    </nextlevel> 
    <nextlevel> 
     <note> text text text </note> 
    </nextlevel> 
</level> 

我想删除重复的节点“注意”只有当它出现连续两次。输出应该是这样的:

<level> 
<nextlevel> 
    <note> text text text </note> 
</nextlevel> 
    <nextlevel> 
    <abc> 
    </abc> 
    <xyz> 
    </xyz> 
</nextlevel> 
<nextlevel> 
    <note> text text text </note> 
</nextlevel> 
</level> 

我使用下面的XSLT:

<xsl:key name="dup" match="note" use="concat(generate-id(..), '|', name())"/> 

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

<xsl:template match="note[not(generate-id() = generate-id(key('dup', concat(generate-id(..), '|', .))[1]))]"/> 

然而,所有的名字节点“注”被删除,什么是错我的XSLT?

+0

你甲肝使用名称的关键“DUP” ..但它不是在XSLT – CPR43

回答

0

尝试使用此这将避免与相同的值

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

     <xsl:template match="*[not(*)][name() = preceding-sibling::*[1]/name()][@value = preceding-sibling::*[1]/@value]" /> 
+0

感谢定义,但上述代码给出了以下错误: msxml3.dll:NodeTest预计在这里。 – Archana

+0

嗯..不知道为什么..它似乎在这里工作 – CPR43

0

使用XSLT 1.0这里同名连续节点的重复是一个建议:

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

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

<xsl:template match="note[(preceding-sibling::*[1][not(self::note)] or not(preceding-sibling::*[1])) 
          and following-sibling::*[1][self::note] 
          and (following-sibling::*[2][not(self::note)] or not(following-sibling::*[2]))]"/> 

<xsl:template match="note[preceding-sibling::*[1][self::note] 
          and (preceding-sibling::*[2][not(self::note)] or not(preceding-sibling::*[2])) 
          and (following-sibling::*[1][not(self::note)] or not(following-sibling::*[1]))]"/> 

</xsl:stylesheet> 

当施加到输入

<level> 
    <nextlevel> 
     <note> text text text </note> 
    </nextlevel> 
    <nextlevel> 
     <abc> 
     </abc> 
     <note>bla bla bla </note> 
     <note>bla bla bla bla bla</note> 
     <xyz> 
     </xyz> 
    </nextlevel> 
    <nextlevel> 
     <note> text text text </note> 
    </nextlevel> 
    <nextlevel> 
     <foo>bar</foo> 
     <note>...</note> 
     <note>...</note> 
     <note>...</note> 
     <note>...</note> 
     <bar>baz</bar> 
    </nextlevel> 
</level> 

它输出

<level> 
    <nextlevel> 
     <note> text text text </note> 
    </nextlevel> 
    <nextlevel> 
     <abc> 
     </abc> 


     <xyz> 
     </xyz> 
    </nextlevel> 
    <nextlevel> 
     <note> text text text </note> 
    </nextlevel> 
    <nextlevel> 
     <foo>bar</foo> 
     <note>...</note> 
     <note>...</note> 
     <note>...</note> 
     <note>...</note> 
     <bar>baz</bar> 
    </nextlevel> 
</level> 
0

I want to remove the duplicate nodes "note" only when it appears twice consecutively.

也许这可能是简单的:

<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:strip-space elements="*"/> 

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

<xsl:template match="note[count(../note) > 1]"/> 

</xsl:stylesheet> 

这将删除有另一个note作为同级任何note。如果该票据是连续是很重要的,你可以改变除去模板:

<xsl:template match="note[preceding-sibling::node()[1][self::note] or following-sibling::node()[1][self::note]]"/> 
+0

谢谢迈克尔,这工作! – Archana

+0

@Archana如果您的问题得到解答,请通过接受答案关闭它。 –

相关问题