Abhijeet Patil
Abhijeet Patil

Reputation: 65

Join two node data in XML using XSLT

I have XML file as below

<message>
  <swap>
    <clause>
      <genclause name="TRADE_DESC">
        <startdate>2019-07-01</startdate>
        <min>-1000.000000000000</min>
        <max>20.050000000000</max>
        <comment>AAA.USD</comment>
      </genclause>
      <genclause name="TRADE_DESC">
        <startdate>2019-09-09</startdate>
        <min>-1000.000000000000</min>
        <max>24.880000000000</max>
        **<comment>AAA.USD</comment>**
      </genclause>
      <genclause name="TRADE_DESC">
        <startdate>2019-09-09</startdate>
        <min>-2500.000000000000</min>
        <max>45.010000000000</max>
        <comment>BBB.USD</comment>
      </genclause>
      <genclause name="TRADE_DESC">
        <startdate>2019-09-09</startdate>
        <min>1500.000000000000</min>
        <max>87.450000000000</max>
        <comment>CCC.USD</comment>
      </genclause>
    </clause>
  </swap>


  <share>
    <identifier>
      **<reference name="SecID">AAA.USD</reference>**
      <reference name="Exchg">Q</reference>
      <reference name="ISNO">UBSGFD321313</reference>
      <reference name="SYMB">AAA</reference>
      </reference>
    </identifier>
    <name>AAAAA AAAAAA AAAAAAA</name>
  </share>
  <share>
    <identifier>
      <reference name="SecID">BBB.USD</reference>
      <reference name="Exchg">N</reference>
      <reference name="ISNO">QEIRUYW313</reference>
      <reference name="SYMB">BBB</reference>
      </reference>
    </identifier>
    <name>BBBB BBBBBBB BBBBBB</name>
  </share>
</message>

(1) For every node value AAA.USD in "swap/clause/genclause/comment" I want to search matching node value in "share/identifier/reference[@name='SecID']" (here it will be AAA.USD

(2) Then pick all the child node value from both the nodes at "swap/clause/genclause" and "share/identifier".

(3) The output XML should be like :

<AnexTwoInfo>
  <TradeData>
    <SecID>AAA.USD<SecID>
    <min>1000</min>
    <max>24.88</max>
    <Trade_Date>2019-09-09</Trade_Date>
    <name>>AAAAA AAAAAA AAAAAAA</name>
    <Exchange>Q</xchange>
    <ISNO>UBSGFD321313</ISNO>
  </TradeData>
...
...
...

<AnexTwoInfo>

Can anyone please help me? Just started working on XML/XSLT and this is really scratching my head very badly.

For this XML/XSLT I have to use version 1.0 ONLY. This is a restriction.

Please let me know if I have to provide any further information on this.

Thank you.

Upvotes: 0

Views: 80

Answers (1)

michael.hor257k
michael.hor257k

Reputation: 116957

XSLT has a built-in key mechanism for resolving cross-references. In your example, it could work like this:

XSLT 1.0

<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:strip-space elements="*"/>

<xsl:key name="share" match="share" use="identifier/reference[@name='SecID']"/>

<xsl:template match="/message">
    <AnexTwoInfo>
        <xsl:for-each select="swap/clause/genclause">
            <TradeData>
                <SecID>
                    <xsl:value-of select="comment"/>
                </SecID>
                <!-- more nodes here -->
                <xsl:copy-of select="key('share', comment)/name"/>
            </TradeData>
        </xsl:for-each>
    </AnexTwoInfo>
</xsl:template>

</xsl:stylesheet>

When this is applied to a well-formed (!) input:

XML

<message>
  <swap>
    <clause>
      <genclause name="TRADE_DESC">
        <startdate>2019-07-01</startdate>
        <min>-1000.000000000000</min>
        <max>20.050000000000</max>
        <comment>AAA.USD</comment>
      </genclause>
      <genclause name="TRADE_DESC">
        <startdate>2019-09-09</startdate>
        <min>-1000.000000000000</min>
        <max>24.880000000000</max>
        <comment>AAA.USD</comment>
      </genclause>
      <genclause name="TRADE_DESC">
        <startdate>2019-09-09</startdate>
        <min>-2500.000000000000</min>
        <max>45.010000000000</max>
        <comment>BBB.USD</comment>
      </genclause>
      <genclause name="TRADE_DESC">
        <startdate>2019-09-09</startdate>
        <min>1500.000000000000</min>
        <max>87.450000000000</max>
        <comment>CCC.USD</comment>
      </genclause>
    </clause>
  </swap>

  <share>
    <identifier>
      <reference name="SecID">AAA.USD</reference>
      <reference name="Exchg">Q</reference>
      <reference name="ISNO">UBSGFD321313</reference>
      <reference name="SYMB">AAA</reference>
    </identifier>
    <name>AAAAA AAAAAA AAAAAAA</name>
  </share>
  <share>
    <identifier>
      <reference name="SecID">BBB.USD</reference>
      <reference name="Exchg">N</reference>
      <reference name="ISNO">QEIRUYW313</reference>
      <reference name="SYMB">BBB</reference>
    </identifier>
    <name>BBBB BBBBBBB BBBBBB</name>
  </share>
</message>

it will produce:

Result

<?xml version="1.0" encoding="UTF-8"?>
<AnexTwoInfo>
  <TradeData>
    <SecID>AAA.USD</SecID>
    <name>AAAAA AAAAAA AAAAAAA</name>
  </TradeData>
  <TradeData>
    <SecID>AAA.USD</SecID>
    <name>AAAAA AAAAAA AAAAAAA</name>
  </TradeData>
  <TradeData>
    <SecID>BBB.USD</SecID>
    <name>BBBB BBBBBBB BBBBBB</name>
  </TradeData>
  <TradeData>
    <SecID>CCC.USD</SecID>
  </TradeData>
</AnexTwoInfo>

Upvotes: 1

Related Questions