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