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