2013-08-16 192 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,我编辑了代码以实现您更改的要求。如果您对输入或输出有进一步更改,我建议您发布一个新问题。 –