使用XSLT将一种xml格式转换为另一种格式

时间:2014-05-08 16:16:07

标签: xml xslt xslt-2.0

我有以下xml输入文件,并希望将其转换为不同的xml架构格式。 到目前为止,我所拥有的是工作并生成格式良好的xml输出。

两个挑战:

  1. 我想在我使用多个<xsl:apply-templates/>命令的地方更好地构建我的XSLT。
  2. 我还要处理多个<tradeType>个节点(例如<tradeType>IRS</tradeType>,以及<tradeType>CDS</tradeType>),并且需要我的输出稍有不同<tradeType>值。
  3. 这是<tradeType>IRS</tradeType>的输入样本:

    <collection>
        <Trades_Output>
            <tradeId>IRS-002</tradeId>
            <tradeDate>2007-09-05</tradeDate>
            <tradeType>IRS</tradeType>
            <buySell>BUY</buySell>
            <counterparty>COUNTERPARTY IRS</counterparty>
            <internalUnit>My Company Inc</internalUnit>
            <legOnePayerPartyReference>COUNTERPARTY IRS</legOnePayerPartyReference>
            <legOneReceiverPartyReference>My Company Inc</legOneReceiverPartyReference>
            <legOneStartDate>2007-09-05</legOneStartDate>
            <legOneEndDate>2014-09-05</legOneEndDate>
            <legOneNotional>151521500</legOneNotional>
            <legOneCurrency>GBP</legOneCurrency>
            <legOneRateIndex>LIBOR</legOneRateIndex>
            <legOneSpread>0.0022</legOneSpread>
            <legOneFixedRate></legOneFixedRate>
            <legTwoPayerPartyReference>My Company Inc</legTwoPayerPartyReference>
            <legTwoReceiverPartyReference>COUNTERPARTY IRS</legTwoReceiverPartyReference>
            <legTwoStartDate>2007-09-05</legTwoStartDate>
            <legTwoEndDate>2014-09-05</legTwoEndDate>
            <legTwoNotional>151521500</legTwoNotional>  
            <legTwoCurrency>GBP</legTwoCurrency>
            <legTwoRateIndex></legTwoRateIndex>
            <legTwoSpread></legTwoSpread>
            <legTwoFixedRate>0.04575</legTwoFixedRate>
            <legTwoRateType>FIXED</legTwoRateType>
        </Trades_Output>
        <Trades_Output>
           <tradeId>CDS-002</tradeId>
           <tradeDate>2010-09-27</tradeDate>
           <tradeType>CDS</tradeType>
           <counterparty>COUNTERPARTY CDS</counterparty>
            <internalUnit>My Company Limited</internalUnit>
           <buySell>BUY</buySell>
           <status>OPEN</status>
           <startDate>2007-09-05</startDate>
           <endDate>2014-09-05</endDate>
           <sellerPartyReference>COUNTERPARTY IRS</sellerPartyReference>
           <buyerPartyReference>My Company Inc</buyerPartyReference>
           <instrumentId>RBS (REG) 01/08/2013</instrumentId>
           <currency>GBP</currency>
           <amount>75000000</amount>
           <fixedRate>0.0098</fixedRate>
           <dayCountFraction>ACT/360</dayCountFraction>
         </Trades_Output>
    </collection>
    

    我想要的输出:

     <deal>
     <dealHeader>
          <dealId>IRS-RRT-002</dealId>
          <dealType>IRS</dealType>
          <dealDate>2007-09-05</dealDate>
          <status>OPEN</status>
     </dealHeader>
     <trade>
        <sysId>2</sysId>
        <tradeHeader>
            <tradeId>IRS-RRT-002</tradeId>
            <tradeDate>2007-09-05</tradeDate>
            <tradeType>IRS</tradeType>
            <counterparty>COUNTERPARTY IRS</counterparty>
            <internalUnit>My Company Inc</internalUnit>
            <buySell>BUY</buySell>
            <status>OPEN</status>
        </tradeHeader>
        <extensions>
            <extension>
                <name>OrigID</name>
                <value>IRS-RRT-002</value>
            </extension>
        </extensions>
        <product>
            <swap>
                <swapStream>
                    <payerPartyReference href='COUNTERPARTY IRS'/>
                    <receiverPartyReference href='My Company Inc'/>
                    <calculationPeriodDates id='CalcPeriodDates0'>
                        <effectiveDate>
                            <unadjustedDate>2007-09-05</unadjustedDate>
                            <dateAdjustments>
                                <businessDayConvention>MODFOLLOWING</businessDayConvention>
                            </dateAdjustments>
                        </effectiveDate>
                        <terminationDate>
                            <unadjustedDate>2014-09-05</unadjustedDate>
                            <dateAdjustments>
                                <businessDayConvention>MODFOLLOWING</businessDayConvention>
                            </dateAdjustments>
                        </terminationDate>
                        <calculationPeriodDatesAdjustments>
                            <businessDayConvention>MODFOLLOWING</businessDayConvention>
                        </calculationPeriodDatesAdjustments>
                        <calculationPeriodFrequency>
                            <periodMultiplier>6</periodMultiplier>
                            <period>M</period>
                            <rollConvention>NONE</rollConvention>
                        </calculationPeriodFrequency>
                    </calculationPeriodDates>
                    <paymentDates>
                        <calculationPeriodDatesReference href='#CalcPeriodDates0'/>
                        <paymentFrequency>
                            <periodMultiplier>6</periodMultiplier>
                            <period>M</period>
                        </paymentFrequency>
                        <payRelativeTo>CalculationPeriodEndDate</payRelativeTo>
                        <paymentDatesAdjustments>
                            <businessDayConvention>MODFOLLOWING</businessDayConvention>
                        </paymentDatesAdjustments>
                    </paymentDates>
                    <calculationPeriodAmount>
                        <calculation>
                            <notionalSchedule>
                                <notionalStepSchedule>
                                    <initialValue>151521500</initialValue>
                                    <currency>GBP</currency>
                                </notionalStepSchedule>
                            </notionalSchedule>
                            <floatingRateCalculation>
                                <floatingRateIndex>LIBOR</floatingRateIndex>
                                <indexTenor>
                                    <periodMultiplier>6</periodMultiplier>
                                    <period>M</period>
                                </indexTenor>
                                <spreadSchedule>
                                    <initialValue>0</initialValue>
                                </spreadSchedule>
                            </floatingRateCalculation>
                            <dayCountFraction>Act/360</dayCountFraction>
                        </calculation>
                    </calculationPeriodAmount>
                    <stubCalculationPeriodAmount>
                        <finalStub/>
                    </stubCalculationPeriodAmount>
                    <principalExchanges>
                        <initialExchange>false</initialExchange>
                        <finalExchange>false</finalExchange>
                        <intermediateExchange>false</intermediateExchange>
                    </principalExchanges>
                </swapStream>
                <swapStream>
                    <payerPartyReference href='My Company Inc'/>
                    <receiverPartyReference href='COUNTERPARTY IRS'/>
                    <calculationPeriodDates id='CalcPeriodDates0'>
                        <effectiveDate>
                            <unadjustedDate>2007-09-05</unadjustedDate>
                            <dateAdjustments>
                                <businessDayConvention>MODFOLLOWING</businessDayConvention>
                            </dateAdjustments>
                        </effectiveDate>
                        <terminationDate>
                            <unadjustedDate>2014-09-05</unadjustedDate>
                            <dateAdjustments>
                                <businessDayConvention>MODFOLLOWING</businessDayConvention>
                            </dateAdjustments>
                        </terminationDate>
                        <calculationPeriodDatesAdjustments>
                            <businessDayConvention>MODFOLLOWING</businessDayConvention>
                        </calculationPeriodDatesAdjustments>
                        <calculationPeriodFrequency>
                            <periodMultiplier>6</periodMultiplier>
                            <period>M</period>
                            <rollConvention>NONE</rollConvention>
                        </calculationPeriodFrequency>
                    </calculationPeriodDates>
                    <paymentDates>
                        <calculationPeriodDatesReference href='#CalcPeriodDates0'/>
                        <paymentFrequency>
                            <periodMultiplier>6</periodMultiplier>
                            <period>M</period>
                        </paymentFrequency>
                        <payRelativeTo>CalculationPeriodEndDate</payRelativeTo>
                        <paymentDatesAdjustments>
                            <businessDayConvention>MODFOLLOWING</businessDayConvention>
                        </paymentDatesAdjustments>
                    </paymentDates>
                    <calculationPeriodAmount>
                        <calculation>
                            <notionalSchedule>
                                <notionalStepSchedule>
                                    <initialValue>151521500</initialValue>
                                    <currency>GBP</currency>
                                </notionalStepSchedule>
                            </notionalSchedule>
                            <fixedRateSchedule>
                                <initialValue>0.04575</initialValue>
                            </fixedRateSchedule>
                            <dayCountFraction>Act/360</dayCountFraction>
                        </calculation>
                    </calculationPeriodAmount>
                    <principalExchanges>
                        <initialExchange>false</initialExchange>
                        <finalExchange>false</finalExchange>
                        <intermediateExchange>false</intermediateExchange>
                    </principalExchanges>
                </swapStream>
            </swap>
        </product>
      </trade>
     </deal>
    

    以及我的XSLT代码片段:

    <xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    
        <xsl:template match="/*">
            <body>
                <insertions>          
                    <xsl:apply-templates/>          
                </insertions>
            </body>
        </xsl:template>     
        <xsl:template match="Trades_Output">
            <trade>
                <tradeHeader>
                    <tradeId>
                        <xsl:value-of select="tradeId"/>
                    </tradeId>
                    <tradeDate>
                        <xsl:value-of select="tradeDate"/>
                    </tradeDate>
                </tradeHeader>
                <product>
                    <swap>
                        <swapStream>
                            <payerPartyReference>
                                <xsl:value-of select="legOnePayerPartyReference"/>
                            </payerPartyReference>
                            <receiverPartyReference>
                                <xsl:value-of select="legOneReceiverPartyReference"/>
                            </receiverPartyReference>
                        </swapStream>
                        <swapStream>
                            <payerPartyReference>
                                <xsl:value-of select="legTwoPayerPartyReference"/>
                            </payerPartyReference>
                            <receiverPartyReference>
                                <xsl:value-of select="legTwoReceiverPartyReference"/>
                            </receiverPartyReference>                
                        </swapStream>
                    </swap>
                </product>
            </trade>
        </xsl:template>
    ....
    

    是否有任何其他建议可以提供更好的结构我的XSLT?换句话说,与<xsl:template match="Trades_Output">

    中的所有xml输出相反 谢谢你。 鲍勃

1 个答案:

答案 0 :(得分:1)

1。我想在我使用多个命令的地方更好地构建我的XSLT。

源XML的设计非常糟糕,如果元素如下所示会更好:

<PayerPartyReference leg="one"/>

由于所有LegOne / LegTwo元素看起来基本相同,但是你使用XSLT 2.0以便使用正则表达式来解决这个问题,我会做这样的事情:

<?xml version="1.0" encoding="UTF-8"?>
<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="/*">
    <body>
        <insertions>
            <xsl:apply-templates select="Trades_Output"/>
        </insertions>
    </body>
</xsl:template>

<xsl:template match="Trades_Output">
    <trade>
        <tradeHeader>
            <xsl:copy-of select="tradeId | tradeDate"/>
        </tradeHeader>
        <product>
            <swap>
                <!-- this will generate two groups for the elements starting with legOne/legTwo -->
                <xsl:for-each-group select="*[matches(name(),'(legOne|legTwo)')]"
                    group-by="substring(name(),1,6)">
                    <swapStream>
                        <!-- 
                          this will apply to legOnePayerPartyReference and legOneReceiverPartyReference
                          when in group legOne and respectively when in group legTwo 
                        -->
                        <xsl:apply-templates select="current-group()[ends-with(name(),'PartyReference')]"/>
                        <calculationPeriodDates>
                            <xsl:apply-templates select="current-group()[ends-with(name(),'Date')]"/>
                        </calculationPeriodDates>
                    </swapStream>
                </xsl:for-each-group>
            </swap>
        </product>
    </trade>
</xsl:template>

<xsl:template match="*[matches(name(),'(legOne|legTwo)PayerPartyReference')]">
    <payerPartyReference href="{.}"/>
</xsl:template>

<xsl:template match="*[matches(name(),'(legOne|legTwo)ReceiverPartyReference')]">
    <receiverPartyReference href="{.}"/>
</xsl:template>

<xsl:template match="*[matches(name(),'(legOne|legTwo)StartDate')]">
    <effectiveDate>
        <unadjustedDate>
            <xsl:value-of select="."/>
        </unadjustedDate>
        <dateAdjustments>
            <businessDayConvention>MODFOLLOWING</businessDayConvention>
        </dateAdjustments>
    </effectiveDate>
</xsl:template>

<xsl:template match="*[matches(name(),'(legOne|legTwo)EndDate')]">
    <terminationDate>
        <unadjustedDate>
            <xsl:value-of select="."/>
        </unadjustedDate>
        <dateAdjustments>
            <businessDayConvention>MODFOLLOWING</businessDayConvention>
        </dateAdjustments>
    </terminationDate>
</xsl:template>
</xsl:stylesheet>

我不清楚你所希望的输出中的大部分内容来自,我猜测很多东西是固定的...但是这应该让你开始。


我还要处理多个<tradeType>个节点(即<tradeType>IRS</tradeType>,以及<tradeType>CDS</tradeType>),并且需要我的输出略有不同基于<tradeType>值。

这完全取决于你的意思所以也许在这里提供一些关于每个tradeType会有什么不同的信息...最简单的解决方案是每个tradeType只有一个模板< / p>

<xsl:template match="Trades_Output[tradeType='IRS']"> 

分别

<xsl:template match="Trades_Output[tradeType='CDS']">

然后在那里有不同的结构......