element.rs

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