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;
  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, "&amp;")?,
 29            '<' => write!(writer, "&lt;")?,
 30            '>' => write!(writer, "&gt;")?,
 31            '\'' => write!(writer, "&apos;")?,
 32            '"' => write!(writer, "&quot;")?,
 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}