寻求使用XSLT转换XML内容的建议

时间:2014-05-30 16:21:23

标签: xslt xslt-1.0

我正在使用XSLT 1.0将更复杂的xml架构转换为更简化的输出。 我此时并没有关注输出数据的准确性,而主要是关于xslt处理和xpath技术。

查看下面的源代码xml,我需要访问所有'rzOutbound/body/portfolios/portfolio'个节点。我可以执行XSLT处理,然后提取@id属性,<exposure>值等。这没问题。

但是,我需要在底部有另一个xml部分 - 即

<combinations> 

因此,对于我访问的每个<portfolio>节点,我需要在@id中查找combinations/portfolio属性值并验证portfolio/key1portfolio/key2的组合

例如,如果我遇到这个组合,我知道我正在处理“VM”(或财务方面的变化保证金):

  <key1 id='DummyCounterpartyIRS'></key1>
  <key2 id='MTM'></key2>

而在这种情况下,我正在处理“IM”(初始保证金):

 <portfolio id='35'>
   <key1 id='DummyCounterpartyIRS'></key1>
   <key2 id='InternalVaR_IRS_CCH'></key2>
 </portfolio>

那么我是否在'rzOutbound/body/portfolios/portfolio'节点级别开始模板迭代,还是在combinations/portfolio节点级别开始迭代?这是我最挣扎的地方,以及如何做到这一点?

这是我正在尝试的一些XSLT代码,我从xml源的底部开始,带有<combinations>节点部分:

 <?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" xmlns:xd="http://www.oxygenxml.com/ns/doc/xsl"
   exclude-result-prefixes="xs xd" version="1.0">
 <xsl:output encoding="UTF-8" indent="yes" omit-xml-declaration="yes"/>

    <xsl:template match="/*">
      <collection>
         <xsl:apply-templates select="combinations/portfolio"/>
      </collection>
    </xsl:template>

    <xsl:template match="combinations/portfolio">
         <-- if <key1> and <key2> @id attrib values are acceptable, then apply the 
              next template and select rzOutbound/body/portfolios/portfolio node 
              where the @id is a match -->
         <xsl:apply-templates select="/razorOutbound/body/portfolios/portfolio[@id=thisID]" />
    </xsl:template>

    <xsl:template match="contributions/tradeContribution">
       <extIA>
          <Legal_ID>
            <xsl:value-of select="ancestor::portfolio/@id"/>                
          </Legal_ID>
          <Amount>
            <xsl:value-of select="ancestor::portfolio/exposure"/>                
          </Amount>
    </xsl:template> 

 </xsl:stylesheet>

我的源xml是:

 <rzOutbound>
<body>
    <portfolios>
        <portfolio id='39'>
            <exposure>4233391.352528125</exposure>
            <contributions>
                <tradeContribution tradeId='CDS-RRT-002' dealId='CDS-RRT-002' desc='CRSW' contribution='2732540.4858249128'>
                    <hideTrade>false</hideTrade>                        
                </tradeContribution>
                <tradeContribution tradeId='CDS-RRT-001' dealId='CDS-RRT-001' desc='CRSW' contribution='1528725.384451054'>
                    <hideTrade>false</hideTrade>                        
                </tradeContribution>
            </contributions>
            <nodeAnalysis id='ES 99.7'>
                <method>EXPECTED_SHORTFALL</method>
            </nodeAnalysis>
        </portfolio>
        <portfolio id='36'>
            <exposure>1243694.4436083585</exposure>
            <contributions>
                <tradeContribution tradeId='IRS-RRT-001' dealId='IRS-RRT-001' desc='IRSW-FIX-FLOAT' contribution='743437.76086249948'>
                    <hideTrade>false</hideTrade>
                </tradeContribution>
                <tradeContribution tradeId='IRS-RRT-002' dealId='IRS-RRT-002' desc='IRSW-FIX-FLOAT' contribution='500256.682745859'>
                    <hideTrade>false</hideTrade>
                </tradeContribution>
            </contributions>
            <nodeAnalysis id='ES 99.7'>
                <method>EXPECTED_SHORTFALL</method>
            </nodeAnalysis>
        </portfolio>
        <portfolio id='35'>
            <exposure>20150788.00987801</exposure>
            <contributions>
                <tradeContribution tradeId='IRS-RRT-001' dealId='IRS-RRT-001' desc='IRSW-FIX-FLOAT' contribution='12045637.843246162'>
                    <hideTrade>false</hideTrade>                        
                </tradeContribution>
                <tradeContribution tradeId='IRS-RRT-002' dealId='IRS-RRT-002' desc='IRSW-FIX-FLOAT' contribution='8105150.1666318476'>
                    <hideTrade>false</hideTrade>                    
                </tradeContribution>
            </contributions>
            <nodeAnalysis id='HSVaR 5D 100 ES'>
                <method>INTERPOLATED_EXPECTED_SHORTFALL</method>                    
                <percentile>100</percentile>
            </nodeAnalysis>
        </portfolio>
        <portfolio id='38'>             
            <exposure>5869883.4547659159</exposure>
            <contributions>
                <tradeContribution tradeId='CDS-RRT-002' dealId='CDS-RRT-002' desc='CRSW' contribution='3871823.3074953556'>
                    <hideTrade>false</hideTrade>                        
                </tradeContribution>
                <tradeContribution tradeId='CDS-RRT-001' dealId='CDS-RRT-001' desc='CRSW' contribution='1998060.1472705603'>
                    <hideTrade>false</hideTrade>                        
                </tradeContribution>
            </contributions>
            <nodeAnalysis id='HSVaR 5D 100 ES'>
                <method>INTERPOLATED_EXPECTED_SHORTFALL</method>                    
                <percentile>100</percentile>
            </nodeAnalysis>
        </portfolio>
        <portfolio id='34'>         
            <exposure>93678157.587009192</exposure>
            <contributions>
                <tradeContribution tradeId='IRS-RRT-001' dealId='IRS-RRT-001' desc='IRSW-FIX-FLOAT' contribution='50713348.483467519'>
                    <hideTrade>false</hideTrade>                        
                </tradeContribution>
                <tradeContribution tradeId='IRS-RRT-002' dealId='IRS-RRT-002' desc='IRSW-FIX-FLOAT' contribution='42964809.103541672'>
                    <hideTrade>false</hideTrade>                        
                </tradeContribution>
            </contributions>
            <nodeAnalysis id='MTM'>
                <method>SCENARIO</method>
                <exposure>true</exposure>                   
            </nodeAnalysis>
        </portfolio>
        <portfolio id='37'>
            <exposure>-507553339.63408583</exposure>
            <contributions>
                <tradeContribution tradeId='CDS-RRT-001' dealId='CDS-RRT-001' desc='CRSW' contribution='-207732702.4400686'>
                    <hideTrade>false</hideTrade>                        
                </tradeContribution>
                <tradeContribution tradeId='CDS-RRT-002' dealId='CDS-RRT-002' desc='CRSW' contribution='-299820637.19401723'>
                    <hideTrade>false</hideTrade>                        
                </tradeContribution>
            </contributions>
            <nodeAnalysis id='MTM'>
                <method>SCENARIO</method>
                <exposure>true</exposure>                   
            </nodeAnalysis>
        </portfolio>
    </portfolios>
</body>
<combinations>
    <portfolio id='34'>
        <key1 id='DummyCounterpartyIRS'></key1>
        <key2 id='MTM'></key2>
    </portfolio>
    <portfolio id='35'>
        <key1 id='DummyCounterpartyIRS'></key1>
        <key2 id='InternalVaR_IRS_CCH'></key2>
    </portfolio>
    <portfolio id='38'>
        <key1 id='DummyCounterpartyCDS'></key1>
        <key2 id='InternalVaR_IRS_CCH'></key2>
    </portfolio>
    <portfolio id='39'>
        <key1 id='DummyCounterpartyCDS'></key1>
        <key2 id='InternalVaR_CDS_CCH'></key2>
    </portfolio>
    <portfolio id='36'>
        <key1 id='DummyCounterpartyIRS'></key1>
        <key2 id='InternalVaR_CDS_CCH'></key2>
    </portfolio>
    <portfolio id='37'>
        <key1 id='DummyCounterpartyCDS'></key1>
        <key2 id='MTM'></key2>
    </portfolio>
</combinations>
 </rzOutbound>

这里是一个示例xml输出(我现在不关注输出数据的准确性,但主要是关于xslt处理和xpath技术。):

<collection>
<extIA>
  <AgreementID>39</AgreementID>
  <Legal_ID>39</Legal_ID>
  <Product/>
  <Amount>4233391.352528125</Amount>
  <Currency>USD</Currency>
  <ValuationDate>2012-05-15</ValuationDate>
  <externalSystem>IM</externalSystem>
</extIA>
<extIA>
  <AgreementID>39</AgreementID>
  <Legal_ID>39</Legal_ID>
  <Product/>
  <Amount>4233391.352528125</Amount>
  <Currency>USD</Currency>
  <ValuationDate>2012-05-15</ValuationDate>
</extIA>
<extIA>
  <AgreementID>36</AgreementID>
  <Legal_ID>36</Legal_ID>
  <Product/>
  <Amount>1243694.4436083585</Amount>
  <Currency>USD</Currency>
  <ValuationDate>2012-05-15</ValuationDate>
</extIA>
<extIA>
  <AgreementID>36</AgreementID>
  <Legal_ID>36</Legal_ID>
  <Product/>
  <Amount>1243694.4436083585</Amount>
  <Currency>USD</Currency>
  <ValuationDate>2012-05-15</ValuationDate>
</extIA>
<extIA>
  <AgreementID>34</AgreementID>
  <Legal_ID>34</Legal_ID>
  <Product/>
  <Amount>93678157.587009192</Amount>
  <Currency>USD</Currency>
  <ValuationDate>2012-05-15</ValuationDate>
</extIA>
<extIA>
  <AgreementID>34</AgreementID>
  <Legal_ID>34</Legal_ID>
  <Product/>
  <Amount>93678157.587009192</Amount>
  <Currency>USD</Currency>
  <ValuationDate>2012-05-15</ValuationDate>
</extIA>
 <extIA>
  <AgreementID>37</AgreementID>
  <Legal_ID>37</Legal_ID>
  <Product/>
  <Amount>-507553339.63408583</Amount>
  <Currency>USD</Currency>
  <ValuationDate>2012-05-15</ValuationDate>
 </extIA>
 <extIA>
  <AgreementID>37</AgreementID>
  <Legal_ID>37</Legal_ID>
  <Product/>
  <Amount>-507553339.63408583</Amount>
  <Currency>USD</Currency>
  <ValuationDate>2012-05-15</ValuationDate>
</extIA>
 </collection>

1 个答案:

答案 0 :(得分:2)

  

所以我开始我的模板迭代   'rzOutbound / body / portfolio / portfolio'节点级别,还是我开始我的   组合/组合节点级别的迭代?

如果 - 看起来 - XML的两个分支都包含相同的组合,那么选择哪一个并不重要。您始终可以使用投资组合ID作为密钥从其他分支中的相应投资组合中获取数据。

  

例如,如果我遇到这种组合,我知道我正在处理   使用“VM”(或财务条款中的变动保证金):

  <key1 id='DummyCounterpartyIRS'></key1>
  <key2 id='MTM'></key2>
     

而在这种情况下,我正在处理“IM”(初始保证金):

 <portfolio id='35'>
   <key1 id='DummyCounterpartyIRS'></key1>
   <key2 id='InternalVaR_IRS_CCH'></key2>
 </portfolio>

这部分不清楚。我没有看到你从给定的文件中知道任何这样的事情。如果您希望样式表“了解”这些内容,则必须在样式表本身或通过链接到外部XML文档来提供此信息。只有这样,样式表才能决定“if <key1> and <key2> @id attrib values are acceptable”。

<-- if <key1> and <key2> @id attrib values are acceptable, then apply the 
              next template and select rzOutbound/body/portfolios/portfolio node 
              where the @id is a match -->
         <xsl:apply-templates select="/razorOutbound/body/portfolios/portfolio[@id=thisID]" />

我认为这不是一个好用的模式。要么将代码放在if语句中执行,要么 - 如果它太长或需要在别处重用 - 请调用命名模板。 <xsl:apply-templates>正在更改上下文,如果您不想更改上下文,则不应使用它。


修改

  

如果我在<portfolio id='39'>的背景下,你能否给予   我举例说明了如何引用<key1> @id属性   在<combinations>分支内,其中id ='39'?

不确定。这是一个简单的示例,演示如何使用将“本地”数据与从“其他”分支查找的数据相结合:

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>

<xsl:key name="comb" match="combinations/portfolio" use="@id" />

<xsl:template match="/">
    <output>
        <xsl:for-each select="rzOutbound/body/portfolios/portfolio">
            <portfolio id="{@id}">
                <exposure><xsl:value-of select="exposure"/></exposure>
                <key1><xsl:value-of select="key('comb', @id)/key1/@id"/></key1>
            </portfolio>
        </xsl:for-each>
    </output>
</xsl:template>

</xsl:stylesheet>

应用于输入示例时,结果为:

<?xml version="1.0" encoding="UTF-8"?>
<output>
   <portfolio id="39">
      <exposure>4233391.352528125</exposure>
      <key1>DummyCounterpartyCDS</key1>
   </portfolio>
   <portfolio id="36">
      <exposure>1243694.4436083585</exposure>
      <key1>DummyCounterpartyIRS</key1>
   </portfolio>
   <portfolio id="35">
      <exposure>20150788.00987801</exposure>
      <key1>DummyCounterpartyIRS</key1>
   </portfolio>
   <portfolio id="38">
      <exposure>5869883.4547659159</exposure>
      <key1>DummyCounterpartyCDS</key1>
   </portfolio>
   <portfolio id="34">
      <exposure>93678157.587009192</exposure>
      <key1>DummyCounterpartyIRS</key1>
   </portfolio>
   <portfolio id="37">
      <exposure>-507553339.63408583</exposure>
      <key1>DummyCounterpartyCDS</key1>
   </portfolio>
</output>