2013-08-16 197 views
1

號碼,我想創建XSLT一個循環,下面的XML轉換:遍歷的元素名稱

<PAYMENTS> 
    <PAYMENT_BATCH_ID>987654321</PAYMENT_BATCH_ID> 
    <PAYMENT_NUMBER1_AMOUNT>123456789</PAYMENT_NUMBER1_AMOUNT> 
    <PAYMENT_NUMBER1_CURRENCY>EUR</PAYMENT_NUMBER1_CURRENCY> 
    <PAYMENT_NUMBER1_DATE>19700101</PAYMENT_NUMBER1_DATE> 
    <PAYMENT_STRING1_DESCRIPTION>Description</PAYMENT_STRING1_DESCRIPTION> 
    <PAYMENT_NUMBER2_AMOUNT>123456789</PAYMENT_NUMBER2_AMOUNT> 
    <PAYMENT_NUMBER2_CURRENCY>GBP</PAYMENT_NUMBER2_CURRENCY> 
    <PAYMENT_NUMBER2_DATE>19700101</PAYMENT_NUMBER2_DATE> 
    <PAYMENT_STRING2_DESCRIPTION>Description</PAYMENT_STRING2_DESCRIPTION> 
    <PAYMENT_NUMBERn_AMOUNT>123456789</PAYMENT_NUMBERn_AMOUNT> 
    <PAYMENT_NUMBERn_CURRENCY>CHF</PAYMENT_NUMBERn_CURRENCY> 
    <PAYMENT_NUMBERn_DATE>19700101</PAYMENT_NUMBERn_DATE> 
    <PAYMENT_STRINGn_DESCRIPTION>Description</PAYMENT_STRINGn_DESCRIPTION> 
</PAYMENTS> 

進入這個XML:

<PAYMENTS> 
    <PAYMENT> 
     <CURRENCY>EUR</CURRENCY> 
     <AMOUNT>123456789</AMOUNT> 
     <DATE>19700101</DATE> 
    </PAYMENT> 
    <PAYMENT> 
     <CURRENCY>GBP</CURRENCY> 
     <AMOUNT>123456789</AMOUNT> 
     <DATE>19700101</DATE> 
    </PAYMENT> 
    <PAYMENT> 
     <CURRENCY>CHF</CURRENCY> 
     <AMOUNT>123456789</AMOUNT> 
     <DATE>19700101</DATE> 
    </PAYMENT> 
</PAYMENTS> 

注意到,N可以是任何數字,所以你可以有任何數量的付款。我正在使用XSLT 2.0。

我無法找出如何迭代元素名稱中的數字。 請幫忙?

乾杯,

聰島

回答

4

樣式表

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

<xsl:output indent="yes"/> 

<xsl:template match="PAYMENTS"> 
    <xsl:copy> 
    <xsl:for-each-group select="*" group-by="replace(local-name(), '\D+', '')"> 
     <PAYMENT> 
     <xsl:apply-templates select="current-group()"/> 
     </PAYMENT> 
    </xsl:for-each-group> 
    </xsl:copy> 
</xsl:template> 

<xsl:template match="PAYMENTS/*"> 
    <xsl:element name="{substring-after(substring-after(local-name(), '_'), '_')}"> 
    <xsl:value-of select="."/> 
    </xsl:element> 
</xsl:template> 

</xsl:stylesheet> 

變換

<PAYMENTS> 
    <PAYMENT_NUMBER1_CURRENCY>EUR</PAYMENT_NUMBER1_CURRENCY> 
    <PAYMENT_NUMBER1_AMOUNT>123456789</PAYMENT_NUMBER1_AMOUNT> 
    <PAYMENT_NUMBER1_DATE>19700101</PAYMENT_NUMBER1_DATE> 
    <PAYMENT_NUMBER2_CURRENCY>GBP</PAYMENT_NUMBER2_CURRENCY> 
    <PAYMENT_NUMBER2_AMOUNT>123456789</PAYMENT_NUMBER2_AMOUNT> 
    <PAYMENT_NUMBER2_DATE>19700101</PAYMENT_NUMBER2_DATE> 
    <PAYMENT_NUMBERn_CURRENCY>CHF</PAYMENT_NUMBERn_CURRENCY> 
    <PAYMENT_NUMBERn_AMOUNT>123456789</PAYMENT_NUMBERn_AMOUNT> 
    <PAYMENT_NUMBERn_DATE>19700101</PAYMENT_NUMBERn_DATE> 
</PAYMENTS> 

<PAYMENTS> 
    <PAYMENT> 
     <CURRENCY>EUR</CURRENCY> 
     <AMOUNT>123456789</AMOUNT> 
     <DATE>19700101</DATE> 
    </PAYMENT> 
    <PAYMENT> 
     <CURRENCY>GBP</CURRENCY> 
     <AMOUNT>123456789</AMOUNT> 
     <DATE>19700101</DATE> 
    </PAYMENT> 
    <PAYMENT> 
     <CURRENCY>CHF</CURRENCY> 
     <AMOUNT>123456789</AMOUNT> 
     <DATE>19700101</DATE> 
    </PAYMENT> 
</PAYMENTS> 

如果您不希望將所有的元素,你想改變輸出元素的順序,那麼你需要明確的列出它們:

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

<xsl:output indent="yes"/> 

<xsl:template match="PAYMENTS"> 
    <xsl:copy> 
    <xsl:for-each-group select="* except PAYMENT_BATCH_ID" group-by="replace(local-name(), '\D+', '')"> 
     <PAYMENT> 
     <xsl:apply-templates select="current-group()[self::*[contains(local-name(), 'CURRENCY')]], 
            current-group()[self::*[contains(local-name(), 'AMOUNT')]], 
            current-group()[self::*[contains(local-name(), 'DATE')]]"/> 
     </PAYMENT> 
    </xsl:for-each-group> 
    </xsl:copy> 
</xsl:template> 

<xsl:template match="PAYMENTS/*"> 
    <xsl:element name="{substring-after(substring-after(local-name(), '_'), '_')}"> 
    <xsl:value-of select="."/> 
    </xsl:element> 
</xsl:template> 

</xsl:stylesheet> 

隨着該樣式表和輸入

<PAYMENTS> 
    <PAYMENT_BATCH_ID>987654321</PAYMENT_BATCH_ID> 
    <PAYMENT_NUMBER1_AMOUNT>123456789</PAYMENT_NUMBER1_AMOUNT> 
    <PAYMENT_NUMBER1_CURRENCY>EUR</PAYMENT_NUMBER1_CURRENCY> 
    <PAYMENT_NUMBER1_DATE>19700101</PAYMENT_NUMBER1_DATE> 
    <PAYMENT_STRING1_DESCRIPTION>Description</PAYMENT_STRING1_DESCRIPTION> 
    <PAYMENT_NUMBER2_AMOUNT>123456789</PAYMENT_NUMBER2_AMOUNT> 
    <PAYMENT_NUMBER2_CURRENCY>GBP</PAYMENT_NUMBER2_CURRENCY> 
    <PAYMENT_NUMBER2_DATE>19700101</PAYMENT_NUMBER2_DATE> 
    <PAYMENT_STRING2_DESCRIPTION>Description</PAYMENT_STRING2_DESCRIPTION> 
    <PAYMENT_NUMBERn_AMOUNT>123456789</PAYMENT_NUMBERn_AMOUNT> 
    <PAYMENT_NUMBERn_CURRENCY>CHF</PAYMENT_NUMBERn_CURRENCY> 
    <PAYMENT_NUMBERn_DATE>19700101</PAYMENT_NUMBERn_DATE> 
    <PAYMENT_STRINGn_DESCRIPTION>Description</PAYMENT_STRINGn_DESCRIPTION> 
</PAYMENTS> 

撒克遜9.5輸出

<PAYMENTS> 
    <PAYMENT> 
     <CURRENCY>EUR</CURRENCY> 
     <AMOUNT>123456789</AMOUNT> 
     <DATE>19700101</DATE> 
    </PAYMENT> 
    <PAYMENT> 
     <CURRENCY>GBP</CURRENCY> 
     <AMOUNT>123456789</AMOUNT> 
     <DATE>19700101</DATE> 
    </PAYMENT> 
    <PAYMENT> 
     <CURRENCY>CHF</CURRENCY> 
     <AMOUNT>123456789</AMOUNT> 
     <DATE>19700101</DATE> 
    </PAYMENT> 
</PAYMENTS> 
+0

您好馬丁,感謝您的回覆。這是我正在尋找的很大一部分。不過,我編輯了這個問題。元素的順序已更改,並添加了一個元素。我需要更多的控制忽略第一個元素。並且應該在NUMBERn上進行分組,其中n是循環中的序列。我也應該能夠通過元素名稱選擇貨幣,金額和日期。 – Tuno

+0

@Tuno,我編輯了代碼以實現您更改的要求。如果您對輸入或輸出有進一步更改,我建議您發佈一個新問題。 –