1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102
use crate::{error::Error, *}; use quick_xml::{ events::{attributes::Attributes, *}, Reader, }; use serde_json::{Map, Value}; use std::io::BufRead; fn parse_tag<B: BufRead>( reader: &mut Reader<B>, buf: &mut Vec<u8>, root: bool, ) -> Result<Map<String, Value>, Error> { let mut children = Map::new(); loop { let event = reader.read_event(buf); let mut start_tag = |name: &[u8], attributes: Attributes, map: Map<String, Value>| -> Result<(), Error> { let mut map = map; for attribute in attributes { let attribute = attribute.map_err(|e| Error::XmlQuickXmlError(e))?; map.insert( format!( "{}{}", ATTRIBUTE_START_CHARACTER, bytes_to_string(attribute.key)? ), Value::String(bytes_to_string(&attribute.value)?), ); } let key = bytes_to_string(name)?; match &mut children.get_mut(&key) { None => { children.insert(key, Value::Array(vec![Value::Object(map)])); } Some(value) => { value .as_array_mut() .ok_or(Error::JsonParseUnexpectedArray)? .push(Value::Object(map)); } } Ok(()) }; match event { Ok(Event::Start(ref e)) => { let mut buf = vec![]; start_tag( e.name(), e.attributes(), parse_tag(reader, &mut buf, false)?, )?; } Ok(Event::End(ref _e)) => { break; } Ok(Event::Empty(ref e)) => { start_tag(e.name(), e.attributes(), Map::new())?; } Ok(Event::Text(ref e)) => { children.insert( TEXT_CHARACTER.to_string(), Value::String( e.unescape_and_decode(&reader) .map_err(|e| Error::XmlQuickXmlError(e))?, ), ); } Ok(Event::Comment(ref _e)) => {} Ok(Event::CData(ref _e)) => {} Ok(Event::Decl(ref _e)) => {} Ok(Event::PI(ref _e)) => {} Ok(Event::DocType(ref _e)) => {} Ok(Event::Eof) => { if root { break; } return Err(Error::XmlParseUnexpectedEof); } Err(e) => return Err(Error::XmlQuickXmlError(e)), } buf.clear(); } Ok(children) } pub fn xml_to_json(xml: &str) -> Result<Value, Error> { let mut buf = vec![]; let mut reader = Reader::from_str(xml); reader.trim_text(true); Ok(Value::Object(parse_tag(&mut reader, &mut buf, true)?)) }