1//! Provides an `Element` type, which represents DOM nodes, and a builder to create them with.
2
3use std::io:: Write;
4use std::collections::{btree_map, BTreeMap};
5
6use std::str;
7
8use error::{Error, ErrorKind, Result};
9
10use quick_xml::reader::Reader as EventReader;
11use quick_xml::events::{Event, BytesStart};
12
13use std::io::BufRead;
14
15use std::str::FromStr;
16
17use std::slice;
18
19use convert::{IntoElements, IntoAttributeValue, ElementEmitter};
20
21/// Escape XML text
22pub fn write_escaped<W: Write>(writer: &mut W, input: &str) -> Result<()> {
23 for c in input.chars() {
24 match c {
25 '&' => write!(writer, "&")?,
26 '<' => write!(writer, "<")?,
27 '>' => write!(writer, ">")?,
28 '\'' => write!(writer, "'")?,
29 '"' => write!(writer, """)?,
30 _ => write!(writer, "{}", c)?,
31 }
32 }
33
34 Ok(())
35}
36
37/// A node in an element tree.
38#[derive(Clone, Debug, PartialEq, Eq)]
39pub enum Node {
40 /// An `Element`.
41 Element(Element),
42 /// A text node.
43 Text(String),
44}
45
46impl Node {
47 /// Turns this into an `Element` if possible, else returns None.
48 ///
49 /// # Examples
50 ///
51 /// ```rust
52 /// use minidom::Node;
53 ///
54 /// let elm = Node::Element("<meow />".parse().unwrap());
55 /// let txt = Node::Text("meow".to_owned());
56 ///
57 /// assert_eq!(elm.as_element().unwrap().name(), "meow");
58 /// assert_eq!(txt.as_element(), None);
59 /// ```
60 pub fn as_element(&self) -> Option<&Element> {
61 match *self {
62 Node::Element(ref e) => Some(e),
63 Node::Text(_) => None,
64 }
65 }
66
67 /// Turns this into a `String` if possible, else returns None.
68 ///
69 /// # Examples
70 ///
71 /// ```rust
72 /// use minidom::Node;
73 ///
74 /// let elm = Node::Element("<meow />".parse().unwrap());
75 /// let txt = Node::Text("meow".to_owned());
76 ///
77 /// assert_eq!(elm.as_text(), None);
78 /// assert_eq!(txt.as_text().unwrap(), "meow");
79 /// ```
80 pub fn as_text(&self) -> Option<&str> {
81 match *self {
82 Node::Element(_) => None,
83 Node::Text(ref s) => Some(s),
84 }
85 }
86
87 fn write_to_inner<W: Write>(&self, writer: &mut W, last_namespace: &mut Option<String>) -> Result<()>{
88 match *self {
89 Node::Element(ref elmt) => elmt.write_to_inner(writer, last_namespace)?,
90 Node::Text(ref s) => write_escaped(writer, s)?,
91 }
92
93 Ok(())
94 }
95}
96
97#[derive(Clone, PartialEq, Eq, Debug)]
98/// A struct representing a DOM Element.
99pub struct Element {
100 name: String,
101 namespace: Option<String>,
102 attributes: BTreeMap<String, String>,
103 children: Vec<Node>,
104}
105
106impl<'a> From<&'a Element> for String {
107 fn from(elem: &'a Element) -> String {
108 let mut writer = Vec::new();
109 elem.write_to(&mut writer).unwrap();
110 String::from_utf8(writer).unwrap()
111 }
112}
113
114
115impl FromStr for Element {
116 type Err = Error;
117
118 fn from_str(s: &str) -> Result<Element> {
119 let mut reader = EventReader::from_str(s);
120 Element::from_reader(&mut reader)
121 }
122}
123
124impl Element {
125 fn new(name: String, namespace: Option<String>, attributes: BTreeMap<String, String>, children: Vec<Node>) -> Element {
126 Element {
127 name: name,
128 namespace: namespace,
129 attributes: attributes,
130 children: children,
131 }
132 }
133
134 /// Return a builder for an `Element` with the given `name`.
135 ///
136 /// # Examples
137 ///
138 /// ```rust
139 /// use minidom::Element;
140 ///
141 /// let elem = Element::builder("name")
142 /// .ns("namespace")
143 /// .attr("name", "value")
144 /// .append("inner")
145 /// .build();
146 ///
147 /// assert_eq!(elem.name(), "name");
148 /// assert_eq!(elem.ns(), Some("namespace"));
149 /// assert_eq!(elem.attr("name"), Some("value"));
150 /// assert_eq!(elem.attr("inexistent"), None);
151 /// assert_eq!(elem.text(), "inner");
152 /// ```
153 pub fn builder<S: Into<String>>(name: S) -> ElementBuilder {
154 ElementBuilder {
155 root: Element::new(name.into(), None, BTreeMap::new(), Vec::new()),
156 }
157 }
158
159 /// Returns a bare minimum `Element` with this name.
160 ///
161 /// # Examples
162 ///
163 /// ```rust
164 /// use minidom::Element;
165 ///
166 /// let bare = Element::bare("name");
167 ///
168 /// assert_eq!(bare.name(), "name");
169 /// assert_eq!(bare.ns(), None);
170 /// assert_eq!(bare.attr("name"), None);
171 /// assert_eq!(bare.text(), "");
172 /// ```
173 pub fn bare<S: Into<String>>(name: S) -> Element {
174 Element {
175 name: name.into(),
176 namespace: None,
177 attributes: BTreeMap::new(),
178 children: Vec::new(),
179 }
180 }
181
182 /// Returns a reference to the name of this element.
183 pub fn name(&self) -> &str {
184 &self.name
185 }
186
187 /// Returns a reference to the namespace of this element, if it has one, else `None`.
188 pub fn ns(&self) -> Option<&str> {
189 self.namespace.as_ref()
190 .map(String::as_ref)
191 }
192
193 /// Returns a reference to the value of the given attribute, if it exists, else `None`.
194 pub fn attr(&self, name: &str) -> Option<&str> {
195 if let Some(value) = self.attributes.get(name) {
196 return Some(value)
197 }
198 None
199 }
200
201 /// Returns an iterator over the attributes of this element.
202 ///
203 /// # Example
204 ///
205 /// ```rust
206 /// use minidom::Element;
207 ///
208 /// let elm: Element = "<elem a=\"b\" />".parse().unwrap();
209 ///
210 /// let mut iter = elm.attrs();
211 ///
212 /// assert_eq!(iter.next().unwrap(), ("a", "b"));
213 /// assert_eq!(iter.next(), None);
214 /// ```
215 pub fn attrs(&self) -> Attrs {
216 Attrs {
217 iter: self.attributes.iter(),
218 }
219 }
220
221 /// Returns an iterator over the attributes of this element, with the value being a mutable
222 /// reference.
223 pub fn attrs_mut(&mut self) -> AttrsMut {
224 AttrsMut {
225 iter: self.attributes.iter_mut(),
226 }
227 }
228
229 /// Modifies the value of an attribute.
230 pub fn set_attr<S: Into<String>, V: IntoAttributeValue>(&mut self, name: S, val: V) {
231 let name = name.into();
232 let val = val.into_attribute_value();
233
234 if let Some(value) = self.attributes.get_mut(&name) {
235 *value = val.expect("removing existing value via set_attr, this is not yet supported (TODO)"); // TODO
236 return;
237 }
238
239 if let Some(val) = val {
240 self.attributes.insert(name, val);
241 }
242 }
243
244 /// Returns whether the element has the given name and namespace.
245 ///
246 /// # Examples
247 ///
248 /// ```rust
249 /// use minidom::Element;
250 ///
251 /// let elem = Element::builder("name").ns("namespace").build();
252 ///
253 /// assert_eq!(elem.is("name", "namespace"), true);
254 /// assert_eq!(elem.is("name", "wrong"), false);
255 /// assert_eq!(elem.is("wrong", "namespace"), false);
256 /// assert_eq!(elem.is("wrong", "wrong"), false);
257 /// ```
258 pub fn is<N: AsRef<str>, NS: AsRef<str>>(&self, name: N, namespace: NS) -> bool {
259 let ns = self.namespace.as_ref().map(String::as_ref);
260 self.name == name.as_ref() && ns == Some(namespace.as_ref())
261 }
262
263 /// Parse a document from an `EventReader`.
264 pub fn from_reader<R: BufRead>(reader: &mut EventReader<R>) -> Result<Element> {
265 let mut buf = Vec::new();
266 let root: Element;
267
268 loop {
269 let e = reader.read_event(&mut buf)?;
270 match e {
271 Event::Empty(ref e) | Event::Start(ref e) => {
272 root = build_element(e)?; // FIXME: could be break build_element(e)? when break value is stable
273 break;
274 },
275 Event::Eof => {
276 bail!(ErrorKind::EndOfDocument);
277 },
278 _ => () // TODO: may need more errors
279 }
280 };
281
282 let mut stack = vec![root];
283
284 loop {
285 match reader.read_event(&mut buf)? {
286 Event::Empty(ref e) => {
287 let elem = build_element(e)?;
288 // Since there is no Event::End after, directly append it to the current node
289 stack.last_mut().unwrap().append_child(elem);
290 },
291 Event::Start(ref e) => {
292 let elem = build_element(e)?;
293 stack.push(elem);
294 },
295 Event::End(ref e) => {
296 if stack.len() <= 1 {
297 break;
298 }
299 let elem = stack.pop().unwrap();
300 if let Some(to) = stack.last_mut() {
301 if elem.name().as_bytes() != e.name() {
302 bail!(ErrorKind::InvalidElementClosed);
303 }
304 to.append_child(elem);
305 }
306 },
307 Event::Text(s) | Event::CData(s) => {
308 let text = s.unescape_and_decode(reader)?;
309 if text != "" {
310 let mut current_elem = stack.last_mut().unwrap();
311 current_elem.append_text_node(text);
312 }
313 },
314 Event::Eof => {
315 break;
316 },
317 _ => (), // TODO: may need to implement more
318 }
319 }
320 Ok(stack.pop().unwrap())
321 }
322
323 /// Output a document to a `Writer`.
324 pub fn write_to<W: Write>(&self, writer: &mut W) -> Result<()> {
325 let mut last_namespace = None;
326 write!(writer, "<?xml version=\"1.0\" encoding=\"utf-8\"?>")?;
327 self.write_to_inner(writer, &mut last_namespace)
328 }
329
330 /// Output a document to a `Writer` assuming you're already in the provided namespace
331 pub fn write_to_in_namespace<W: Write>(&self, writer: &mut W, namespace: &str) -> Result<()> {
332 write!(writer, "<?xml version=\"1.0\" encoding=\"utf-8\"?>")?;
333 self.write_to_inner(writer, &mut Some(namespace.to_owned()))
334 }
335
336 fn write_to_inner<W: Write>(&self, writer: &mut W, last_namespace: &mut Option<String>) -> Result<()> {
337 write!(writer, "<")?;
338 write!(writer, "{}", self.name)?;
339
340 if let Some(ref ns) = self.namespace {
341 if *last_namespace != self.namespace {
342 write!(writer, " xmlns=\"")?;
343 write_escaped(writer, ns)?;
344 write!(writer, "\"")?;
345 *last_namespace = Some(ns.clone());
346 }
347 }
348
349 for (key, value) in &self.attributes {
350 write!(writer, " {}=\"", key)?;
351 write_escaped(writer, value)?;
352 write!(writer, "\"")?;
353 }
354
355 if self.children.is_empty() {
356 write!(writer, " />")?;
357 return Ok(())
358 }
359
360 write!(writer, ">")?;
361
362 for child in &self.children {
363 child.write_to_inner(writer, last_namespace)?;
364 }
365
366 write!(writer, "</{}>", self.name)?;
367 Ok(())
368 }
369
370 /// Returns an iterator over references to every child node of this element.
371 ///
372 /// # Examples
373 ///
374 /// ```rust
375 /// use minidom::Element;
376 ///
377 /// let elem: Element = "<root>a<c1 />b<c2 />c</root>".parse().unwrap();
378 ///
379 /// let mut iter = elem.nodes();
380 ///
381 /// assert_eq!(iter.next().unwrap().as_text().unwrap(), "a");
382 /// assert_eq!(iter.next().unwrap().as_element().unwrap().name(), "c1");
383 /// assert_eq!(iter.next().unwrap().as_text().unwrap(), "b");
384 /// assert_eq!(iter.next().unwrap().as_element().unwrap().name(), "c2");
385 /// assert_eq!(iter.next().unwrap().as_text().unwrap(), "c");
386 /// assert_eq!(iter.next(), None);
387 /// ```
388 #[inline] pub fn nodes(&self) -> Nodes {
389 self.children.iter()
390 }
391
392 /// Returns an iterator over mutable references to every child node of this element.
393 #[inline] pub fn nodes_mut(&mut self) -> NodesMut {
394 self.children.iter_mut()
395 }
396
397 /// Returns an iterator over references to every child element of this element.
398 ///
399 /// # Examples
400 ///
401 /// ```rust
402 /// use minidom::Element;
403 ///
404 /// let elem: Element = "<root>hello<child1 />this<child2 />is<child3 />ignored</root>".parse().unwrap();
405 ///
406 /// let mut iter = elem.children();
407 /// assert_eq!(iter.next().unwrap().name(), "child1");
408 /// assert_eq!(iter.next().unwrap().name(), "child2");
409 /// assert_eq!(iter.next().unwrap().name(), "child3");
410 /// assert_eq!(iter.next(), None);
411 /// ```
412 #[inline] pub fn children(&self) -> Children {
413 Children {
414 iter: self.children.iter(),
415 }
416 }
417
418 /// Returns an iterator over mutable references to every child element of this element.
419 #[inline] pub fn children_mut(&mut self) -> ChildrenMut {
420 ChildrenMut {
421 iter: self.children.iter_mut(),
422 }
423 }
424
425 /// Returns an iterator over references to every text node of this element.
426 ///
427 /// # Examples
428 ///
429 /// ```rust
430 /// use minidom::Element;
431 ///
432 /// let elem: Element = "<root>hello<c /> world!</root>".parse().unwrap();
433 ///
434 /// let mut iter = elem.texts();
435 /// assert_eq!(iter.next().unwrap(), "hello");
436 /// assert_eq!(iter.next().unwrap(), " world!");
437 /// assert_eq!(iter.next(), None);
438 /// ```
439 #[inline] pub fn texts(&self) -> Texts {
440 Texts {
441 iter: self.children.iter(),
442 }
443 }
444
445 /// Returns an iterator over mutable references to every text node of this element.
446 #[inline] pub fn texts_mut(&mut self) -> TextsMut {
447 TextsMut {
448 iter: self.children.iter_mut(),
449 }
450 }
451
452 /// Appends a child node to the `Element`, returning the appended node.
453 ///
454 /// # Examples
455 ///
456 /// ```rust
457 /// use minidom::Element;
458 ///
459 /// let mut elem = Element::bare("root");
460 ///
461 /// assert_eq!(elem.children().count(), 0);
462 ///
463 /// elem.append_child(Element::bare("child"));
464 ///
465 /// {
466 /// let mut iter = elem.children();
467 /// assert_eq!(iter.next().unwrap().name(), "child");
468 /// assert_eq!(iter.next(), None);
469 /// }
470 ///
471 /// let child = elem.append_child(Element::bare("new"));
472 ///
473 /// assert_eq!(child.name(), "new");
474 /// ```
475 pub fn append_child(&mut self, mut child: Element) -> &mut Element {
476 if child.namespace.is_none() && self.namespace.is_some() {
477 child.namespace = self.namespace.clone();
478 child.propagate_namespaces();
479 }
480 self.children.push(Node::Element(child));
481 if let Node::Element(ref mut cld) = *self.children.last_mut().unwrap() {
482 cld
483 }
484 else {
485 unreachable!()
486 }
487 }
488
489 fn propagate_namespaces(&mut self) {
490 let ns = self.namespace.clone();
491 for child in self.children_mut() {
492 if child.namespace.is_none() {
493 child.namespace = ns.clone();
494 child.propagate_namespaces();
495 }
496 }
497 }
498
499 /// Appends a text node to an `Element`.
500 ///
501 /// # Examples
502 ///
503 /// ```rust
504 /// use minidom::Element;
505 ///
506 /// let mut elem = Element::bare("node");
507 ///
508 /// assert_eq!(elem.text(), "");
509 ///
510 /// elem.append_text_node("text");
511 ///
512 /// assert_eq!(elem.text(), "text");
513 /// ```
514 pub fn append_text_node<S: Into<String>>(&mut self, child: S) {
515 self.children.push(Node::Text(child.into()));
516 }
517
518 /// Appends a node to an `Element`.
519 ///
520 /// # Examples
521 ///
522 /// ```rust
523 /// use minidom::{Element, Node};
524 ///
525 /// let mut elem = Element::bare("node");
526 ///
527 /// elem.append_node(Node::Text("hello".to_owned()));
528 ///
529 /// assert_eq!(elem.text(), "hello");
530 /// ```
531 pub fn append_node(&mut self, node: Node) {
532 self.children.push(node);
533 }
534
535 /// Returns the concatenation of all text nodes in the `Element`.
536 ///
537 /// # Examples
538 ///
539 /// ```rust
540 /// use minidom::Element;
541 ///
542 /// let elem: Element = "<node>hello,<split /> world!</node>".parse().unwrap();
543 ///
544 /// assert_eq!(elem.text(), "hello, world!");
545 /// ```
546 pub fn text(&self) -> String {
547 self.texts().fold(String::new(), |ret, new| ret + new)
548 }
549
550 /// Returns a reference to the first child element with the specific name and namespace, if it
551 /// exists in the direct descendants of this `Element`, else returns `None`.
552 ///
553 /// # Examples
554 ///
555 /// ```rust
556 /// use minidom::Element;
557 ///
558 /// let elem: Element = r#"<node xmlns="ns"><a /><a xmlns="other_ns" /><b /></node>"#.parse().unwrap();
559 ///
560 /// assert!(elem.get_child("a", "ns").unwrap().is("a", "ns"));
561 /// assert!(elem.get_child("a", "other_ns").unwrap().is("a", "other_ns"));
562 /// assert!(elem.get_child("b", "ns").unwrap().is("b", "ns"));
563 /// assert_eq!(elem.get_child("c", "ns"), None);
564 /// assert_eq!(elem.get_child("b", "other_ns"), None);
565 /// assert_eq!(elem.get_child("a", "inexistent_ns"), None);
566 /// ```
567 pub fn get_child<N: AsRef<str>, NS: AsRef<str>>(&self, name: N, namespace: NS) -> Option<&Element> {
568 for fork in &self.children {
569 if let Node::Element(ref e) = *fork {
570 if e.is(name.as_ref(), namespace.as_ref()) {
571 return Some(e);
572 }
573 }
574 }
575 None
576 }
577
578 /// Returns a mutable reference to the first child element with the specific name and namespace,
579 /// if it exists in the direct descendants of this `Element`, else returns `None`.
580 pub fn get_child_mut<N: AsRef<str>, NS: AsRef<str>>(&mut self, name: N, namespace: NS) -> Option<&mut Element> {
581 for fork in &mut self.children {
582 if let Node::Element(ref mut e) = *fork {
583 if e.is(name.as_ref(), namespace.as_ref()) {
584 return Some(e);
585 }
586 }
587 }
588 None
589 }
590
591 /// Returns whether a specific child with this name and namespace exists in the direct
592 /// descendants of the `Element`.
593 ///
594 /// # Examples
595 ///
596 /// ```rust
597 /// use minidom::Element;
598 ///
599 /// let elem: Element = r#"<node xmlns="ns"><a /><a xmlns="other_ns" /><b /></node>"#.parse().unwrap();
600 ///
601 /// assert_eq!(elem.has_child("a", "other_ns"), true);
602 /// assert_eq!(elem.has_child("a", "ns"), true);
603 /// assert_eq!(elem.has_child("a", "inexistent_ns"), false);
604 /// assert_eq!(elem.has_child("b", "ns"), true);
605 /// assert_eq!(elem.has_child("b", "other_ns"), false);
606 /// assert_eq!(elem.has_child("b", "inexistent_ns"), false);
607 /// ```
608 pub fn has_child<N: AsRef<str>, NS: AsRef<str>>(&self, name: N, namespace: NS) -> bool {
609 self.get_child(name, namespace).is_some()
610 }
611}
612
613fn build_element(event: &BytesStart) -> Result<Element> {
614 let mut attributes = event.attributes()
615 .map(|o| {
616 let o = o?;
617 let key = str::from_utf8(o.key)?.to_owned();
618 let value = str::from_utf8(o.value)?.to_owned();
619 Ok((key, value))
620 }
621 )
622 .collect::<Result<BTreeMap<String, String>>>()?;
623 let mut ns_key = None;
624 for (key, _) in &attributes {
625 if key == "xmlns" || key.starts_with("xmlns:") {
626 ns_key = Some(key.clone());
627 }
628 }
629
630 let ns = match ns_key {
631 None => None,
632 Some(key) => attributes.remove(&key),
633 };
634 let name = str::from_utf8(event.name())?.to_owned();
635 Ok(Element::new(name, ns, attributes, Vec::new()))
636}
637
638/// An iterator over references to child elements of an `Element`.
639pub struct Children<'a> {
640 iter: slice::Iter<'a, Node>,
641}
642
643impl<'a> Iterator for Children<'a> {
644 type Item = &'a Element;
645
646 fn next(&mut self) -> Option<&'a Element> {
647 for item in &mut self.iter {
648 if let Node::Element(ref child) = *item {
649 return Some(child);
650 }
651 }
652 None
653 }
654}
655
656/// An iterator over mutable references to child elements of an `Element`.
657pub struct ChildrenMut<'a> {
658 iter: slice::IterMut<'a, Node>,
659}
660
661impl<'a> Iterator for ChildrenMut<'a> {
662 type Item = &'a mut Element;
663
664 fn next(&mut self) -> Option<&'a mut Element> {
665 for item in &mut self.iter {
666 if let Node::Element(ref mut child) = *item {
667 return Some(child);
668 }
669 }
670 None
671 }
672}
673
674/// An iterator over references to child text nodes of an `Element`.
675pub struct Texts<'a> {
676 iter: slice::Iter<'a, Node>,
677}
678
679impl<'a> Iterator for Texts<'a> {
680 type Item = &'a str;
681
682 fn next(&mut self) -> Option<&'a str> {
683 for item in &mut self.iter {
684 if let Node::Text(ref child) = *item {
685 return Some(child);
686 }
687 }
688 None
689 }
690}
691
692/// An iterator over mutable references to child text nodes of an `Element`.
693pub struct TextsMut<'a> {
694 iter: slice::IterMut<'a, Node>,
695}
696
697impl<'a> Iterator for TextsMut<'a> {
698 type Item = &'a mut String;
699
700 fn next(&mut self) -> Option<&'a mut String> {
701 for item in &mut self.iter {
702 if let Node::Text(ref mut child) = *item {
703 return Some(child);
704 }
705 }
706 None
707 }
708}
709
710/// An iterator over references to all child nodes of an `Element`.
711pub type Nodes<'a> = slice::Iter<'a, Node>;
712
713/// An iterator over mutable references to all child nodes of an `Element`.
714pub type NodesMut<'a> = slice::IterMut<'a, Node>;
715
716/// An iterator over the attributes of an `Element`.
717pub struct Attrs<'a> {
718 iter: btree_map::Iter<'a, String, String>,
719}
720
721impl<'a> Iterator for Attrs<'a> {
722 type Item = (&'a str, &'a str);
723
724 fn next(&mut self) -> Option<Self::Item> {
725 self.iter.next().map(|(x, y)| (x.as_ref(), y.as_ref()))
726 }
727}
728
729/// An iterator over the attributes of an `Element`, with the values mutable.
730pub struct AttrsMut<'a> {
731 iter: btree_map::IterMut<'a, String, String>,
732}
733
734impl<'a> Iterator for AttrsMut<'a> {
735 type Item = (&'a str, &'a mut String);
736
737 fn next(&mut self) -> Option<Self::Item> {
738 self.iter.next().map(|(x, y)| (x.as_ref(), y))
739 }
740}
741
742/// A builder for `Element`s.
743pub struct ElementBuilder {
744 root: Element,
745}
746
747impl ElementBuilder {
748 /// Sets the namespace.
749 pub fn ns<S: Into<String>>(mut self, namespace: S) -> ElementBuilder {
750 self.root.namespace = Some(namespace.into());
751 self
752 }
753
754 /// Sets an attribute.
755 pub fn attr<S: Into<String>, V: IntoAttributeValue>(mut self, name: S, value: V) -> ElementBuilder {
756 self.root.set_attr(name, value);
757 self
758 }
759
760 /// Appends anything implementing `IntoElements` into the tree.
761 pub fn append<T: IntoElements>(mut self, into: T) -> ElementBuilder {
762 {
763 let mut emitter = ElementEmitter::new(&mut self.root);
764 into.into_elements(&mut emitter);
765 }
766 self
767 }
768
769 /// Builds the `Element`.
770 pub fn build(self) -> Element {
771 self.root
772 }
773}
774
775#[test]
776fn test_element_new() {
777 use std::iter::FromIterator;
778
779 let elem = Element::new( "name".to_owned()
780 , Some("namespace".to_owned())
781 , BTreeMap::from_iter(vec![ ("name".to_string(), "value".to_string()) ].into_iter() )
782 , Vec::new() );
783
784 assert_eq!(elem.name(), "name");
785 assert_eq!(elem.ns(), Some("namespace"));
786 assert_eq!(elem.attr("name"), Some("value"));
787 assert_eq!(elem.attr("inexistent"), None);
788}