Parse http response into tuple vector of (chrono::DateTime, f32)

Viewed 50

I send an http get request to a server and receive a response:

let resp = reqwest::blocking::get(req)?.text()?;

resp holds a String like this:

<?xml version=\"1.0\" encoding=\"UTF-8\">\n<Document xmlns=...
<datetime>202207102300</datetime>\n\t\t\t\t\t\t<value>320.08</value>\n\t\t\t\t\t<datetime>202207110000</datetime>\n\t\t\t\t\t\t<value>278.00</value>
...</Document>

What is the best way to get this text parsed into a vector containing tuple elements, as follows:

let mut tuple_items: (chrono::DateTime, f32)
1 Answers

This is my code that I created with the quickxml crate:

use chrono::NaiveDateTime;
use quick_xml::events::Event;
use quick_xml::Reader;

pub struct DatetimeValue {
    pub dt: NaiveDateTime,
    pub val: f32,
}    

pub fn parse_xml_string(&self, xml_string: String) -> Vec<DatetimeValue> {
    let mut response_vector: Vec<DatetimeValue> = vec![];
    let mut reader = Reader::from_str(&xml_string[..]);
    reader.trim_text(true);
    let mut val_flag = false;
    let mut dt_flag = false;
    let mut buf = Vec::new();
    let mut count = 0;
    let mut actual_dt: NaiveDateTime;
    loop {
        match reader.read_event(&mut buf) {
            Ok(Event::Start(ref e)) => {
                if let b"value" = e.name() { val_flag = true }
                else if let b"datetime" = e.name() { dt_flag = true }
            }
            Ok(Event::Text(e)) => {
                if dt_flag {
                    actual_dt = NaiveDateTime::parse_from_str(e
                            .unescape_and_decode(&reader)
                            .unwrap(), "%Y%m%d%H%M").unwrap();
                    dt_flag = false;
                }
                else if val_flag {
                    response_vector.push(DatetimeValue {
                        dt: actual_dt,
                        val: e
                            .unescape_and_decode(&reader)
                            .unwrap()
                            .parse::<f32>()
                            .unwrap(),
                    });
                    val_flag = false;
                }
            }
            Ok(Event::Eof) => break,
            Err(e) => panic!("Error at position {}: {:?}", reader.buffer_position(), e),
            _ => (),
        }
        buf.clear();
    }
    response_vector
}
Related