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