2017-08-23 17 views
0

考慮我的XML文件:復位計

<Data> 
    <VetaP dfg="2" ppp="oe"/> 
    <VetaD ods="3" ds="oda"/> 
    <VetaR date="080817"/> 
    <VetaR date=""/> 
    <VetaR date=""/> 
    <VetaR date=""/> 
    <VetaR date="080817"/> 
    <VetaR date=""/> 
    <VetaR date=""/> 
    <VetaR date="080817"/> 
</Data> 

我需要在<VetaR>添加屬性序列,這個屬性是每個VetaR創造了一個櫃檯。但是,我需要重置計數器,每5次出現<VetaR>。我還需要添加一個屬性cnt,其中,它也是一個計數器,但是這次它只會每增加5次出現<VetaR>。我需要刪除空的屬性。

這裏是我的XSLT代碼:

電流輸出:

<Data> 
    <VetaP dfg="2" ppp="oe"/> 
    <VetaD ods="3" ds="oda"/> 
    <VetaR seq="3" cnt="1" date="080817"/> 
    <VetaR seq="4" cnt="1"/> 
    <VetaR seq="5" cnt="1"/> 
    <VetaR seq="1" cnt="2"/> 
    <VetaR seq="2" cnt="2" date="080817"/> 
    <VetaR seq="3" cnt="2"/> 
    <VetaR seq="4" cnt="2"/> 
    <VetaR seq="5" cnt="2" date="080817"/></Data> 

所需的輸出:

<Data> 
    <VetaP dfg="2" ppp="oe"/> 
    <VetaD ods="3" ds="oda"/> 
    <VetaR seq="1" cnt="1" date="080817"/> 
    <VetaR seq="2" cnt="1"/> 
    <VetaR seq="3" cnt="1"/> 
    <VetaR seq="4" cnt="1"/> 
    <VetaR seq="5" cnt="1" date="080817"/> 
    <VetaR seq="1" cnt="2"/> 
    <VetaR seq="2" cnt="2"/> 
    <VetaR seq="3" cnt="2" date="080817"/></Data> 
+0

通過復位計數器方面的這種思想,你想,如果你使用的是過程編程語言,而不是你將如何解決這個問題一個功能性的。儘量遠離「告訴計算機做什麼」,而應該從描述輸出如何與輸入相關的角度思考。 –

回答

2

我會解決它的位置分組:

<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="Data"> 
     <xsl:copy> 
      <xsl:for-each-group select="*" group-adjacent="(position() - 1) idiv 5"> 
       <xsl:apply-templates select="current-group()"> 
        <xsl:with-param name="group-pos" select="position()"/> 
       </xsl:apply-templates> 
      </xsl:for-each-group> 
     </xsl:copy> 
    </xsl:template> 

    <xsl:template match="VetaR"> 
     <xsl:param name="group-pos"/> 
     <VetaR seq="{position()}" cnt="{$group-pos}"> 
      <xsl:apply-templates select="@*"/> 
     </VetaR> 
    </xsl:template> 

    <xsl:template match="VetaR/@*[not(normalize-space())]"/> 
</xsl:stylesheet> 
+0

謝謝!如果在VetaR之前還有其他元素呢?我無法得到正確的輸出,位置從2開始更新輸入文件。 –

+0

好吧,如果已知所有其他元素都在'VetaR'元素之前,那麼您可以通過首先單獨處理它們並用它們單獨處理來輕鬆修復代碼。 ' ... <的xsl:for-各個羣組>'。如果輸入變量更大,那麼我想你需要向我們展示輸入和期望輸出的更多細節。 –

2

爲什麼不乾脆:

<xsl:template match="VetaR"> 
    <VetaR seq="{(position() - 1) mod 5 + 1}" cnt="{(position() - 1) idiv 5 + 1}"> 
     <xsl:if test="string(@date)"> 
      <xsl:copy-of select="@date"/> 
     </xsl:if> 
    </VetaR> 
</xsl:template>