2012-06-03 18 views
0

我有這個輸入文件:如何使用XSLT修復連續節點外觀上的這種消除?

<myroot> 
    <list id="xxx"> 
     <node id="a"> 
      <section id="i"> 
       <item1 id="a0" method="start"> 
        <somechild>a</somechild> 
       </item1> 
       <item1 id="a0" method="start"> <!-- this one is successive from the previous so we eliminate --> 
        <somechild>a</somechild> 
       </item1> 
       <item1 id="a0" method="stop"/>     
       <item1 id="a0" method="start"> 
        <somechild>a</somechild> 
       </item1> 
      </section> 

      <section id="i"> 
       <item1 id="a0" method="start"> <!-- this one is successive from the previous so we eliminate --> 
        <somechild>a</somechild> 
       </item1> 
       <item1 id="a0" method="stop"/> 
       <item1 id="a0" method="start"> 
        <somechild>a</somechild> 
       </item1> 
       <item1 id="a0" method="start"> <!-- this one is successive from the previous so we eliminate --> 
        <somechild>a</somechild> 
       </item1> 
      </section>     
     </node> 
    </list> 
</myroot> 

而且我的輸出:

<myroot> 
     <list id="xxx"> 
      <node id="a"> 
       <section id="i"> 
        <item1 id="a0" method="start"> 
         <somechild>a</somechild> 
        </item1> 
        <item1 id="a0" method="stop"/>     
       </section> 

       <section id="i" /> 
      </node> 
     </list> 
    </myroot> 

**While the expected output should be:** 

<myroot> 
    <list id="xxx"> 
     <node id="a"> 
      <section id="i"> 
       <item1 id="a0" method="start"> 
        <somechild>a</somechild> 
       </item1> 
       <item1 id="a0" method="stop"/>     
       <item1 id="a0" method="start"> 
        <somechild>a</somechild> 
       </item1> 
      </section> 

      <section id="i"> 
       <item1 id="a0" method="stop"/> 
       <item1 id="a0" method="start"> 
        <somechild>a</somechild> 
       </item1> 
      </section>     
     </node> 
    </list> 
</myroot> 

XSLT文件:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0"> 
    <xsl:strip-space elements="*"/> 
    <xsl:output indent="yes"/> 

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

    <xsl:template match="/*/*/*"> 
     <xsl:copy> 
      <xsl:variable name="first-in-group" as="element()*"> 
       <xsl:for-each-group select="*" group-by="concat(node-name(.), '|', @id,'|', @method)"> 
        <xsl:for-each-group select="current-group()/*" group-by="concat(@id, '|', @method)"> 
         <xsl:sequence 
       select="for $pos in 1 to count(current-group()) 
         return current-group()[$pos] 
           [every $item 
           in subsequence(current-group(), 1, $pos - 1) 
           satisfies not(deep-equal($item, current-group()[$pos]))] "/> 
        </xsl:for-each-group> 
       </xsl:for-each-group> 
      </xsl:variable> 
      <xsl:apply-templates select="@*"/> 
      <xsl:apply-templates> 
       <xsl:with-param name="first-in-group" select="$first-in-group" tunnel="yes"/> 
      </xsl:apply-templates> 
     </xsl:copy> 
    </xsl:template> 

    <xsl:template match="/*/*/*/*/*"> 
     <xsl:param name="first-in-group" tunnel="yes"/> 
     <xsl:if test="$first-in-group intersect ."> 
      <xsl:call-template name="identity"/> 
     </xsl:if> 
    </xsl:template> 
</xsl:stylesheet> 

另一種情形:

<myroot> 
    <list id="xxx"> 
     <node id="a"> 
      <section id="i"> 
       <item1 id="a0" method="start"> 
        <somechild>a</somechild> 
       </item1> 
      </section> 

      <section id="i">    
       <item1 id="a1" method="start"> 
        <somechild>a</somechild> 
       </item1> 
       <item1 id="a0" method="start"> <!-- this one is successive from the previous, because the previous node has id of 'a1', so we eliminate --> 
        <somechild>a</somechild> 
       </item1> 
       <item1 id="a0" method="start"> <!-- this one is successive from the previous so we eliminate --> 
        <somechild>a</somechild> 
       </item1> 
      </section>     
     </node> 
    </list> 
</myroot> 

預期輸出:

<myroot> 
    <list id="xxx"> 
     <node id="a"> 
      <section id="i"> 
       <item1 id="a0" method="start"> 
        <somechild>a</somechild> 
       </item1> 
      </section> 

      <section id="i">    
       <item1 id="a1" method="start"> 
        <somechild>a</somechild> 
       </item1> 
      </section>     
     </node> 
    </list> 
</myroot> 

這個想法是用相同的方法刪除連續節點。在該實例中:

  • 開始/啓動/停止/開始/啓動 - >啓動/停止/啓動

的XSLT可以去除連續的節點但不是上面的情況下工作。

任何人都可以指出我應該在哪裏更改xslt以適應上述情況?非常感謝您的幫助。

乾杯, 約翰

回答

1

也許我失去了一些東西,但它看起來你是在複雜的。您應該能夠匹配/去除任何等於相同名稱的第一個前面元素的元素。

XSLT 2.0

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output indent="yes"/> 
    <xsl:strip-space elements="*"/> 

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

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

</xsl:stylesheet> 

XML輸出(使用上述更新後的XML)

<myroot> 
    <list id="xxx"> 
     <node id="a"> 
     <section id="i"> 
      <item1 id="a0" method="start"> 
       <somechild>a</somechild> 
      </item1> 
      <item1 id="a0" method="stop"/> 
      <item1 id="a0" method="start"> 
       <somechild>a</somechild> 
      </item1> 
     </section> 
     <section id="i"> 
      <item1 id="a0" method="stop"/> 
      <item1 id="a0" method="start"> 
       <somechild>a</somechild> 
      </item1> 
     </section> 
     </node> 
    </list> 
</myroot> 
+0

下降'' –

+0

嗨的固定問題,事實證明,去除唯一作品僅在第一個'

'部分。你有什麼建議讓你的解決方案在第二個'
'上運作。請參閱我的擴展輸入更新。非常感謝。 – John

+0

@John - 我不確定你的意思。使用你的擴展輸入,我得到了你在'預期輸出應該是:'下列出的內容。如果預期輸出與您的問題不同,請更新它。 –