2016-12-02 55 views
0

之間刪除重複考慮這個XML:刪除從開頭和結尾某些節點和

<a> 
    <b>something</b> 
    <b>something</b> 
    <M>other</M> 
    <b>something</b> 
    <b>something</b> 
    <N>else</N> 
    <b>something</b> 
    <b>something</b> 
    <b>something</b> 
</a> 

現在我要刪除所有「B」開頭或結尾,如果他們在不同的間我只想要輸出一個節點。所以這將是所需的輸出:

<a> 
    <M>other</M> 
    <b>something</b> 
    <N>else</N> 
</a> 

我不知道有多少「b」,我不知道其他節點的名稱是什麼。開始的時候是很容易的:刪除所有「B」時,他們遵循「B」:

<xsl:template match="b[preceding-sibling::*[1][self::b]]"/> 

然後刪除第一個「B」:

<xsl:template match="b[position= 1]"/> 

而最後,如果只有一個「B」 :

<xsl:template match="b[position= last()]"/> 

但我無法得到最後三個「b」的第一個。測試應該說:如果只有「b」但沒有其他東西,然後刪除「b」。我找到的一些解決方案使用了分組,但由於節點的順序很重要,所以在這裏似乎沒有幫助。

回答

1

我建議使用xsl:for-each-group如下:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:xs="http://www.w3.org/2001/XMLSchema" 
    exclude-result-prefixes="xs" 
    version="2.0"> 

    <xsl:output indent="yes"/> 

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

    <xsl:template match="a"> 
     <xsl:copy> 
      <xsl:for-each-group select="*" group-adjacent="boolean(self::b)"> 
       <xsl:choose> 
        <xsl:when test="not(current-grouping-key())"> 
         <xsl:apply-templates select="current-group()"/> 
        </xsl:when> 
        <xsl:when test="not(position() = (1, last()))"> 
         <xsl:apply-templates select="."/> 
        </xsl:when> 
       </xsl:choose> 
      </xsl:for-each-group> 
     </xsl:copy> 
    </xsl:template> 

</xsl:stylesheet> 

這轉變

<a> 
    <b>1</b> 
    <b>2</b> 
    <M>foo</M> 
    <b>3</b> 
    <b>4</b> 
    <N>bar</N> 
    <b>5</b> 
    <b>6</b> 
    <b>7</b> 
</a> 

<a> 
    <M>foo</M> 
    <b>3</b> 
    <N>bar</N> 
</a> 
相關問題