0

I have an XML file where I want to keep only the following tags :

assetId, index, basis1, rate, spread, pors, matDate, notional, currNotional, fixingDate and intDays

Here is an example of the original XML file :

<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
  <messageDetail>
    <transaction>
      <trades>
        <trade>
          <tradeInfoString>SPOT_FX</tradeInfoString>
          <tradeStatusCode>AMENDED</tradeStatusCode>
          <enteredDateTime>2019-05-09T10:49:05+01:00</enteredDateTime>
          <reference>3956502P</reference>
          <version>4</version>
          <tradeDate>2016-06-24</tradeDate>
          <tradeTypeCode>MARKET</tradeTypeCode>
          <tradeLegs>
            <tradeLeg>
              <bookId>721</bookId>
              <assetId>001FM1C9</assetId>
              <index>FIXED</index>
              <basis1>30/360</basis1>
              <rate>-0.381</rate>
              <spread>0</spread>
              <pors>Sale</pors>
              <matDate>2019-05-09</matDate>
              <notional>0.00</notional>
              <currNotional>25000000.00</currNotional>
              <transfers>
                <transfer>
                  <transferType>INTEREST</transferType>
                  <longShort>LONG</longShort>
                  <amount>82285.42</amount>
                  <settlementDate>2017-05-09</settlementDate>
                  <fixingDate>9999-12-31</fixingDate>
                  <intDays>311</intDays>
                  <instrument>
                    <type>CURRENCY</type>
                    <currency>EUR</currency>
                  </instrument>
                </transfer>
                <transfer>
                  <transferType>INTEREST</transferType>
                  <longShort>LONG</longShort>
                  <amount>95250.00</amount>
                  <settlementDate>2018-05-09</settlementDate>
                  <fixingDate>9999-12-31</fixingDate>
                  <intDays>360</intDays>
                  <instrument>
                    <type>CURRENCY</type>
                    <currency>EUR</currency>
                  </instrument>
                </transfer>
              </transfers>
            </tradeLeg>
            <tradeLeg>
              <bookId>721</bookId>
              <assetId>001FM1CB</assetId>
              <index>FORM</index>
              <basis1>A360</basis1>
              <rate>0</rate>
              <spread>0</spread>
              <pors>Purchase</pors>
              <matDate>2019-05-09</matDate>
              <notional>0.00</notional>
              <currNotional>25000000.00</currNotional>
              <transfers>
                <transfer>
                  <transferType>INTEREST</transferType>
                  <longShort>SHORT</longShort>
                  <amount>10150.00</amount>
                  <settlementDate>2016-08-09</settlementDate>
                  <fixingDate>2016-06-24</fixingDate>
                  <intDays>42</intDays>
                  <instrument>
                    <type>CURRENCY</type>
                    <currency>EUR</currency>
                  </instrument>
                </transfer>
              </transfers>
            </tradeLeg>
          </tradeLegs>
          <endDate>2019-05-09</endDate>
          <startDate>2016-06-28</startDate>
          <systemProductCode>SWAP</systemProductCode>
        </trade>
      </trades>
    </transaction>
  </messageDetail>

To do that, I used the following XSLT file :

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:hsbcfixml="http://www.fixprotocol.org/FIXML-4-4"
    exclude-result-prefixes="hsbcfixml">
    <xsl:output method="xml" encoding="UTF-8" 
        indent="yes" />

    <xsl:template match="node()|@*">
        <xsl:copy>
            <xsl:apply-templates select="node()|@*" />
        </xsl:copy>
    </xsl:template>

    <xsl:template
        match="node()[not(self::tradeLeg or ancestor-or-self::assetId or ancestor-or-self::index or ancestor-or-self::basis1 or ancestor-or-self::rate or ancestor-or-self::spread or ancestor-or-self::pors or ancestor-or-self::matDate or ancestor-or-self::notional or ancestor-or-self::currNotional or ancestor-or-self::fixingDate or ancestor-or-self::intDays)]">
        <xsl:apply-templates />
    </xsl:template>
</xsl:stylesheet>

Which produced the following output :

<tradeLeg>
   <assetId>001FM1C9</assetId>
   <index>FIXED</index>
   <basis1>30/360</basis1>
   <rate>-0.381</rate>
   <spread>0</spread>
   <pors>Sale</pors>
   <matDate>2019-05-09</matDate>
   <notional>0.00</notional>
   <currNotional>25000000.00</currNotional>
   <fixingDate>9999-12-31</fixingDate>
   <intDays>311</intDays>
   <fixingDate>9999-12-31</fixingDate>
   <intDays>360</intDays>
</tradeLeg>
<tradeLeg>
   <assetId>001FM1CB</assetId>
   <index>FORM</index>
   <basis1>A360</basis1>
   <rate>0</rate>
   <spread>0</spread>
   <pors>Purchase</pors>
   <matDate>2019-05-09</matDate>
   <notional>0.00</notional>
   <currNotional>25000000.00</currNotional>
   <fixingDate>2016-06-24</fixingDate>
   <intDays>42</intDays>
</tradeLeg>

The problem is that the output is not a valid XML file, it lacks a XML declaration, and a root element (XML validation is complaining that The markup in the document following the root element must be well-formed.)

How can I change the XSLT to fix this problem ?

1 Answer 1

2

To match the root node in xslt, you can use '/'.

It selects the root node which is the document node containing all other nodes.

This code can help to achieve the same:

<xsl:template match="/">
    <root>
        <xsl:apply-templates />
    </root>
</xsl:template>

You can modify your xslt as below to add root element.

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:hsbcfixml="http://www.fixprotocol.org/FIXML-4-4"
exclude-result-prefixes="hsbcfixml">

<xsl:output method="xml" encoding="UTF-8" indent="yes" />

<xsl:template match="node()|@*">
    <xsl:copy>
        <xsl:apply-templates select="node()|@*" />
    </xsl:copy>
</xsl:template>

<xsl:template match="/">
    <root>
        <xsl:apply-templates />
    </root>
</xsl:template>

<xsl:template
    match="node()[not(self::tradeLeg or ancestor-or-self::assetId or ancestor-or-self::index or ancestor-or-self::basis1 or ancestor-or-self::rate or ancestor-or-self::spread or ancestor-or-self::pors or ancestor-or-self::matDate or ancestor-or-self::notional or ancestor-or-self::currNotional or ancestor-or-self::fixingDate or ancestor-or-self::intDays)]">
    <xsl:apply-templates />
</xsl:template>
</xsl:stylesheet>

See demo here: https://xsltfiddle.liberty-development.net/bnnZWv

Let me know if I am missing something.

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

Comments

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.