Search code examples
javascriptreactjsapi-design

How to access attributes on xml feed


I am trying to parse data from an xml file in my React JS app, but it seems to return a full xml object comprising of 25 or so 'cube' elements. I'm interested in accessing the 'currency' and 'rate' attribute of each cube, and output each of these inside of a dropdown. Is there a way of looping over all the cubes and somehow targeting these? I'm trying to build a currency converter that automatically converts a price entered by the user.

My code:

import React, { Component } from 'react';
import "../../App.css"

class Countries extends Component {
    constructor() {
        super();
        this.state = {
            countrycodes: [],
            exchangerates: []
        };
    }


componentDidMount(){
    fetch('http://www.ecb.europa.eu/stats/eurofxref/eurofxref-daily.xml')
        .then(response => response.text())
        .then(str => (new window.DOMParser()).parseFromString(str, "text/xml"))
        .then(data => {
            const cubes = data.getElementsByTagName("Cube")
            for( const element of cubes) {
                if (!element.getAttribute('currency')) {
                    continue;
                }

                let countrycodes = element.getAttribute('currency')
                let exchangerates = element.getAttribute('rate')
                this.setState({
                    countrycodes: countrycodes,
                    exchangerates: exchangerates
                })                                
            }
        });       
    }


render() {
    return (

        <div className="container2">
            <div className="container1">
                <select>{this.state.countrycodes.map((country) => {
                    <option>{country}</option>})                                            
                }
                </select>
            </div>
        </div>
    )
    }
}

export default Countries;

Thanks,

Robert


Solution

  • Use getAttribute:

    class Countries extends React.Component {
        constructor() {
            super();
            this.state = {
                countryCodes: []
            };
        }
    
    
      componentDidMount(){
        fetch({url: 'http://www.ecb.europa.eu/stats/eurofxref/eurofxref-daily.xml'})
            .then(response => response.text())
            .then(str => (new window.DOMParser()).parseFromString(str, "text/xml"))
            .then(data => {
                const countryCodes = [];
                const cubes = data.getElementsByTagName("Cube");
                for (const element of cubes) {
                    if (!element.getAttribute('currency')) {
                        // skip cube with no currency
                        continue;
                    }
                    countryCodes.push({ 
                        currency:element.getAttribute('currency'),
                        rate: element.getAttribute('rate')
                    });
                }
                this.setState({countryCodes});
           });
        }
    
      render() {
    
        const options = this.state.countryCodes.map(
            ({currency, rate}) => (<option value={rate}>{currency} - {rate}</option>));
        return (
            <div className="container2">
                <div className="container1">
                    <select>
                      {options}
                    </select>
                </div>
            </div>
        )
      }
    }
    

    To check you can open http://www.ecb.europa.eu/stats/eurofxref/eurofxref-daily.xml and run fetch(...) directly in browser's console:

    enter image description here