【问题标题】:Seeking advice on using XSLT to transform XML content寻求有关使用 XSLT 转换 XML 内容的建议
【发布时间】:2014-07-20 11:32:00
【问题描述】:

我正在使用 XSLT 1.0 将更复杂的 xml 模式转换为更简化的输出。 我现在不关注输出数据的准确性,而是主要关注 xslt 处理和 xpath 技术。

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

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

<combinations> 

所以对于我访问的每个&lt;portfolio&gt;节点,我都需要在combinations/portfolio内部查找@id属性值,并验证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 源代码底部的 &lt;combinations&gt; 节点部分开始:

 <?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>

【问题讨论】:

    标签: xslt xslt-1.0


    【解决方案1】:

    所以我要在 'rzOutbound/body/portfolios/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 &lt;key1&gt; and &lt;key2&gt; @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 语句中,要么 - 如果它太长或需要在其他地方重用 - 调用命名模板。 &lt;xsl:apply-templates&gt; 正在更改上下文,如果您不想更改上下文,则不应使用它。


    编辑

    例如,如果我在&lt;portfolio id='39'&gt; 的上下文中,你能给 我是如何引用位于的&lt;key1&gt; @id 属性的示例 在 id='39' 的&lt;combinations&gt; 分支内?

    当然。下面是一个简单的示例,展示了如何使用 key 将“本地”数据与从“其他”分支查找的数据结合起来:

    <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>
    

    【讨论】:

    • 如果我在 的上下文中,你能给我一个例子来说明如何引用位于&lt;combinations&gt; 中的&lt;key1&gt; @id 属性id='39' 的分支?谢谢你,鲍勃。
    • 感谢您的帮助。 key() 函数正是我所需要的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-06
    • 2011-08-29
    • 1970-01-01
    相关资源
    最近更新 更多