2015-04-23 81 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如果您的問題得到解答,請通過接受答案關閉它。 –

相關問題