我正在使用XSLT 1.0将更复杂的xml架构转换为更简化的输出。 我此时并没有关注输出数据的准确性,而主要是关于xslt处理和xpath技术。
查看下面的源代码xml,我需要访问所有'rzOutbound/body/portfolios/portfolio'
个节点。我可以执行XSLT处理,然后提取@id
属性,<exposure>
值等。这没问题。
但是,我需要在底部有另一个xml部分 - 即
<combinations>
因此,对于我访问的每个<portfolio>
节点,我需要在@id
中查找combinations/portfolio
属性值并验证portfolio/key1
和portfolio/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>
答案 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>