Skip to content

Instantly share code, notes, and snippets.

@Cultrarius
Created February 8, 2016 13:38
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Cultrarius/a6ebe6d52c244466ba95 to your computer and use it in GitHub Desktop.
Save Cultrarius/a6ebe6d52c244466ba95 to your computer and use it in GitHub Desktop.
use std::error::Error;
use std::fs::File;
use std::io::prelude::*;
use std::path::Path;
struct XmlReader<'a> {
file_path: &'a Path
}
struct XmlNode {
name: String,
children: Vec<XmlNode>
}
impl<'a> XmlReader<'a> {
fn read_xml(&self) -> XmlNode {
let mut file = match File::open(self.file_path) {
Err(why) => panic!("couldn't open file: {}", Error::description(&why)),
Ok(file) => file,
};
let mut s = String::new();
match file.read_to_string(&mut s) {
Err(why) => panic!("couldn't read file: {}", Error::description(&why)),
Ok(_) => println!("Successfully read file contents."),
};
let mut in_tag = false;
let mut is_end_tag = false;
let mut in_attributes = false;
let mut current_tag = String::new();
let mut nodes: Vec<XmlNode> = Vec::new();
for c in s.chars() {
if !in_tag && c == '<' {
in_tag = true;
continue;
}
if in_tag {
if c == '/' {
is_end_tag = true;
continue;
}
if c == '>' {
in_tag = false;
if is_end_tag {
let finished_node = nodes.pop().unwrap();
let last_node = nodes.pop();
if last_node.is_some() {
let mut parent_node = last_node.unwrap();
parent_node.children.push(finished_node);
nodes.push(parent_node);
} else {
println!("All xml nodes processed!");
return finished_node;
}
} else {
let node = XmlNode { name: current_tag.clone(), children: Vec::new() };
nodes.push(node);
}
is_end_tag = false;
in_attributes = false;
current_tag.clear();
continue;
}
if c == ' ' {
in_attributes = true;
continue;
}
if in_attributes {
continue;
}
current_tag.push(c);
}
}
panic!("Error reading XML document!");
}
}
fn print_node(node: &XmlNode, depth: usize) {
let indent = std::iter::repeat(" ").take(depth).collect::<String>();
println!("{}{}", indent, node.name);
for child_node in node.children.iter() {
print_node(child_node, depth + 1);
}
}
fn main() {
let path = Path::new("test.xml");
let reader = XmlReader { file_path: path };
let xml_node = reader.read_xml();
print_node(&xml_node, 0);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment