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