0

I'm making a call to an API endpoint, and the data is returned in xml format. I'm using 'xml2js' to convert it to json format, but there is a huge amount of data being converted, and it's crashing quite a lot.

The thing is, I only need a small amount of the xml data that is returned. The xml data that is returned looks something like this...

<odds>
  <event>
    <market id="16336888" state="open" slug="winner" winners="1" traded_volume="0">
      <contract id="54475601" name="Raya2" slug="home" state_or_outcome="open" volume="0.0">
        <bids/>
        <offers/>
      </contract>
      <contract id="54475603" name="Draw" slug="draw" state_or_outcome="open" volume="0.0">
        <bids/>
        <offers/>
      </contract>
      <contract id="54475602" name="Club Celaya" slug="away" state_or_outcome="open" volume="0.0">
        <bids/>
        <offers/>
      </contract>
    </market>

    </market></market>
    <market>...</market>
    <market>...</market>
    <market>...</market>
    ... // more markets
  </event>
  <event>...</event>
  <event>...</event>
  <event>...</event>
  .. // more events
</odds>

From this xml, I need every event, but I only need the first market in each event (market with 'slug' = 'winner'). Is there a way I can cut all the 'markets' I don't need from each 'event' tag, so less xml has to be converted to json?

willmahon
  • 319
  • 4
  • 13

2 Answers2

0

If you want to bring all the data inside the first market with the slug winner in every event, you could use this function:

import { parseStringPromise } from 'xml2js';

async function getMarkets(xml) {
  const results = [];

  const informationParsed = await parseStringPromise(xml, {
    explicitArray: false
  });

  for (const xmlEvent of informationParsed.odds.event) {
    for (const market of xmlEvent.market) {
      if (market.$.slug === 'winner') {
        results.push(market);
        break;
      }
    }
  }
  return results;
}
David Arias
  • 182
  • 14
0

Here is XSLT based method.

The XSLT is following a so called Identity Transform pattern.

One single line does all the magic:

<xsl:template match="market[@slug!='winner']"/>

Everything else is just a plumbing.

Useful links:

XSLT

<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/>
    <xsl:strip-space elements="*"/>

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

    <xsl:template match="market[@slug!='winner']"/>
</xsl:stylesheet>
Yitzhak Khabinsky
  • 18,471
  • 2
  • 15
  • 21