forked from Florob/RustyXML
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathElementBuilder.rs
More file actions
84 lines (79 loc) · 2.55 KB
/
ElementBuilder.rs
File metadata and controls
84 lines (79 loc) · 2.55 KB
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
// RustyXML
// Copyright (c) 2013 Florian Zeitz
//
// This project is MIT licensed.
// Please see the COPYING file for more information.
use base::*;
// DOM Builder
/// An ELement Builder, building `Element`s from `Event`s as produced by `Parser`
pub struct ElementBuilder {
priv stack: ~[~Element]
}
impl ElementBuilder {
/// Returns a new `ElementBuilder`
pub fn new() -> ElementBuilder {
let e = ElementBuilder {
stack: ~[]
};
e
}
/// Hands an `Event` to the builder.
/// While no root element has been finished `Ok(None)` is returned.
/// Once sufficent data has been received an `Element` is returned as `Ok(elem)`.
/// Upon Error `Err("message")` is returned.
pub fn push_event(&mut self, e: Event) -> Result<Option<Element>, ~str> {
match e {
PI(cont) => {
let l = self.stack.len();
if l > 0 {
(*self.stack[l-1]).children.push(PINode(cont));
}
Ok(None)
}
StartTag { name, attributes } => {
self.stack.push(~Element {
name: name.clone(),
attributes: attributes.clone(),
children: ~[]
});
Ok(None)
}
EndTag { name } => {
if self.stack.len() == 0 {
return Err(~"Elements not properly nested");
}
let elem = self.stack.pop();
let l = self.stack.len();
if elem.name != name {
Err(~"Elements not properly nested")
} else if l == 0 {
Ok(Some(*elem))
} else {
(*self.stack[l-1]).children.push(Element(elem));
Ok(None)
}
}
Characters(chars) => {
let l = self.stack.len();
if l > 0 {
(*self.stack[l-1]).children.push(CharacterNode(chars));
}
Ok(None)
}
CDATA(chars) => {
let l = self.stack.len();
if l > 0 {
(*self.stack[l-1]).children.push(CDATANode(chars));
}
Ok(None)
}
Comment(cont) => {
let l = self.stack.len();
if l > 0 {
(*self.stack[l-1]).children.push(CommentNode(cont));
}
Ok(None)
}
}
}
}