0

I'm having a bit of trouble selecting exactly what I want in the following input XML. I need to essentially select by keys/key , where there are multiple <key> child nodes.

For example, here's a sample input XML file :

  <Outbound environment="" request="selectPortfolios">
<body matchedRecordCount="4">       
    <portfolioSummary portfolioId="36">
        <portfolio id="36">
            <currency>USD</currency>
            <keys>
                <key displayValue="DummyCounterpartyIRS" sequenceNumber="100" sequenceValue="DummyCounterpartyIRS" type="Counterparty" value="DummyCounterpartyIRS"/>
                <key displayValue="Internal VaR IRS LCH" sequenceNumber="2000" sequenceValue="80" type="ExpType" value="InternalVaR_IRS_LCH"/>
            </keys>
            <status>Unapproved</status>
        </portfolio>
        <exposureProfile>
            <node date="2014-05-06">
                <tag>HSVaR 5D 100 ES</tag>
                <exposure>492692</exposure>
            </node>
        </exposureProfile>
    </portfolioSummary>
    <portfolioSummary portfolioId="37">     
        <portfolio id="37">
            <currency>USD</currency>
            <keys>
                <key displayValue="DummyCounterpartyIRS" sequenceNumber="100" sequenceValue="DummyCounterpartyIRS" type="Counterparty" value="DummyCounterpartyIRS"/>
                <key displayValue="Internal VaR CDS LCH" sequenceNumber="2000" sequenceValue="81" type="ExpType" value="InternalVaR_CDS_LCH"/>
            </keys>
            <status>Unapproved</status>
        </portfolio>
        <exposureProfile>
            <node date="2014-05-09">
                <tag>Node Scenario 4</tag>
                <exposure>248057</exposure>
            </node>
            <node date="2014-05-10">
                <tag>Node Scenario 5</tag>
                <exposure>373130</exposure>
            </node>
            <node date="2014-05-11">
                <tag>EXPECTED_SHORTFALL 99.7</tag>
                <exposure>373130</exposure>
            </node>
        </exposureProfile>
    </portfolioSummary>
    <portfolioSummary portfolioId="71">
        <readOnly>false</readOnly>
        <portfolio id="71">
            <currency>USD</currency>
            <keys>
                <key displayValue="DummyCounterpartyCDS" sequenceNumber="100" sequenceValue="DummyCounterpartyCDS" type="Counterparty" value="DummyCounterpartyCDS"/>
                <key displayValue="Internal VaR IRS LCH" sequenceNumber="2000" sequenceValue="80" type="ExpType" value="InternalVaR_IRS_LCH"/>
            </keys>         
            <status>Unapproved</status>
        </portfolio>
        <exposureProfile>
            <node date="2014-05-06">
                <tag>HSVaR 5D 100 ES</tag>
                <exposure>58</exposure>
            </node>
        </exposureProfile>
    </portfolioSummary>
    <portfolioSummary portfolioId="72">
        <readOnly>false</readOnly>
        <portfolio id="72">
            <currency>USD</currency>
            <keys>
                <key displayValue="DummyCounterpartyCDS" sequenceNumber="100" sequenceValue="DummyCounterpartyCDS" type="Counterparty" value="DummyCounterpartyCDS"/>
                <key displayValue="Internal VaR CDS LCH" sequenceNumber="2000" sequenceValue="81" type="ExpType" value="InternalVaR_CDS_LCH"/>
            </keys>
            <status>Unapproved</status>
        </portfolio>
        <exposureProfile>
            <node date="2014-05-09">
                <tag>Node Scenario 4</tag>
                <exposure>9</exposure>
            </node>
            <node date="2014-05-10">
                <tag>Node Scenario 5</tag>
                <exposure>12</exposure>
            </node>
            <node date="2014-05-11">
                <tag>EXPECTED_SHORTFALL 99.7</tag>
                <exposure>12</exposure>
            </node>
        </exposureProfile>
    </portfolioSummary>
</body>
</Outbound>

The specific <portfolioSummary> nodes I want are based on the <key> attributes:

1) First XSLT template: 1a) where attribute type="Counterparty" and value="DummyCounterpartyIRS" AND 1b) where attribute type="ExpType" AND value="InternalVaR_IRS_LCH"

2) Second XSLT template: 2a) where attribute type="Counterparty" value="DummyCounterpartyCDS" AND 2b) where attributes type="ExpType" AND value="InternalVaR_CDS_LCH"

It should end up pulling TWO <portfolioSummary> nodes for both portfolioId="36" and portfolioId="72"

Here's what I have, but it's not selecting properly:

   <?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">
<!-- Variable declaration -->
<xsl:variable name="hsVar1D" select="'1D (99%)'"></xsl:variable>
<xsl:variable name="hsVar5D" select="'HSVaR 5D 100 ES'"></xsl:variable>

<!-- Pull portfolioSummary nodes for HSVaR -->
<xsl:template match="/*">
    <collection>
        <xsl:apply-templates select="/Outbound/body/portfolioSummary[descendant::portfolio/keys/key[@type='Counterparty' and @value='DummyCounterpartyIRS']]"/>
        <xsl:apply-templates select="/Outbound/body/portfolioSummary[descendant::portfolio/keys/key[@type='Counterparty' and @value='DummyCounterpartyCDS']]"/>

    </collection>
</xsl:template>
<xsl:template match="*">
    <xsl:choose>
        <xsl:when test="descendant::portfolio/keys/key[@type='ExpType' and @value='InternalVaR_IRS_LCH']">
        <extIA>
            <AGREEMENTID><xsl:value-of select="@portfolioId"></xsl:value-of></AGREEMENTID>
            <legal_id><xsl:value-of select="portfolio/keys/key[@type='Counterparty']/@displayValue"/></legal_id>
            <PRODUCT><xsl:value-of select="portfolio/keys/key[@type='Counterparty']/@displayValue"/></PRODUCT>               
            <AMOUNT><xsl:value-of select="exposureProfile/node[tag/text()[contains(.,$hsVar5D)]]/exposure"/></AMOUNT>
            <CURRENCY><xsl:value-of select="bandStructure/currency"/></CURRENCY>
            <ValuationDate>2012-05-15</ValuationDate>
            <externalSystem>MY EXT SYSTEM</externalSystem>
        </extIA>
        </xsl:when>
        <xsl:when test="descendant::portfolio/keys/key[@type='ExpType' and @value='InternalVaR_CDS_LCH']">
            <extIA>
                <AGREEMENTID><xsl:value-of select="@portfolioId"></xsl:value-of></AGREEMENTID>
                <legal_id><xsl:value-of select="portfolio/keys/key[@type='Counterparty']/@displayValue"/></legal_id>
                <PRODUCT><xsl:value-of select="portfolio/keys/key[@type='ExpType']/@displayValue"/></PRODUCT>
                                    <AMOUNT><xsl:value-of select="exposureProfile/node[tag/text()[contains(.,$hsVar5D)]]/exposure"/></AMOUNT>
                <CURRENCY><xsl:value-of select="bandStructure/currency"/></CURRENCY>
                <ValuationDate>2012-05-15</ValuationDate>
                <externalSystem>MY EXT SYSTEM</externalSystem>
            </extIA>
        </xsl:when>
        <xsl:otherwise></xsl:otherwise>
    </xsl:choose>

</xsl:template>
</xsl:stylesheet>

1 Answer 1

1

The <xsl:apply-templates> in your first template are not selecting anything. You are matching /* and selecting an absolute location path which starts with an element that does not exist: razorOutbound.

Change it to:

<xsl:template match="/">
    <collection>
        <xsl:apply-templates select="Outbound/body/portfolioSummary[descendant::portfolio/keys/key[@type='Counterparty' and @value='DummyCounterpartyIRS']]"/>
        <xsl:apply-templates select="Outbound/body/portfolioSummary[descendant::portfolio/keys/key[@type='Counterparty' and @value='DummyCounterpartyCDS']]"/>
    </collection>
</xsl:template>

As for the selections, four portfolios are selected, and not two. The first expression:

//body/portfolioSummary[portfolio/keys/key[@type='Counterparty' and @value='DummyCounterpartyIRS']]

will match two portfolios (36 and 37), and the other will match 71 and 72. The * template will be called twice for each pair and will always match one or the other xsl:when. If you want to select only one of each, you have to add some other restriction to it.

Sign up to request clarification or add additional context in comments.

2 Comments

I was scrubbing the source XML data, and inadvertently left the old values. But yes, it should read <OutBound> .
So if I loop through each <key> node every time my final template is executed (i.e. <xsl:for-each select="portfolio/keys/key">, couldn't I use an if statement to narrow my selection as in: <xsl:if test="(@type='ExpType') and (@value='Internal VaR IRS LCH')">

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.