element.rs

  1//! Provides an `Element` type, which represents DOM nodes, and a builder to create them with.
  2
  3use std::io::prelude::*;
  4use std::io::Cursor;
  5use std::collections::BTreeMap;
  6use std::collections::btree_map;
  7
  8use std::fmt;
  9
 10use error::Error;
 11
 12use xml::reader::{XmlEvent as ReaderEvent, EventReader};
 13use xml::writer::{XmlEvent as WriterEvent, EventWriter, EmitterConfig};
 14use xml::name::Name;
 15use xml::namespace::NS_NO_PREFIX;
 16
 17use std::str::FromStr;
 18
 19use std::slice;
 20
 21use convert::{IntoElements, IntoAttributeValue, ElementEmitter};
 22
 23/// A node in an element tree.
 24#[derive(Clone, Debug, PartialEq, Eq)]
 25pub enum Node {
 26    /// An `Element`.
 27    Element(Element),
 28    /// A text node.
 29    Text(String),
 30}
 31
 32impl Node {
 33    /// Turns this into an `Element` if possible, else returns None.
 34    ///
 35    /// # Examples
 36    ///
 37    /// ```rust
 38    /// use minidom::Node;
 39    ///
 40    /// let elm = Node::Element("<meow />".parse().unwrap());
 41    /// let txt = Node::Text("meow".to_owned());
 42    ///
 43    /// assert_eq!(elm.as_element().unwrap().name(), "meow");
 44    /// assert_eq!(txt.as_element(), None);
 45    /// ```
 46    pub fn as_element<'a>(&'a self) -> Option<&'a Element> {
 47        match *self {
 48            Node::Element(ref e) => Some(e),
 49            Node::Text(_) => None,
 50        }
 51    }
 52
 53    /// Turns this into a `String` if possible, else returns None.
 54    ///
 55    /// # Examples
 56    ///
 57    /// ```rust
 58    /// use minidom::Node;
 59    ///
 60    /// let elm = Node::Element("<meow />".parse().unwrap());
 61    /// let txt = Node::Text("meow".to_owned());
 62    ///
 63    /// assert_eq!(elm.as_text(), None);
 64    /// assert_eq!(txt.as_text().unwrap(), "meow");
 65    /// ```
 66    pub fn as_text<'a>(&'a self) -> Option<&'a str> {
 67        match *self {
 68            Node::Element(_) => None,
 69            Node::Text(ref s) => Some(s),
 70        }
 71    }
 72}
 73
 74#[derive(Clone, PartialEq, Eq)]
 75/// A struct representing a DOM Element.
 76pub struct Element {
 77    name: String,
 78    namespace: Option<String>,
 79    attributes: BTreeMap<String, String>,
 80    children: Vec<Node>,
 81}
 82
 83impl<'a> From<&'a Element> for String {
 84    fn from(elem: &'a Element) -> String {
 85        let mut out = Vec::new();
 86        let config = EmitterConfig::new()
 87                    .write_document_declaration(false);
 88        elem.write_to(&mut EventWriter::new_with_config(&mut out, config)).unwrap();
 89        String::from_utf8(out).unwrap()
 90    }
 91}
 92
 93impl fmt::Debug for Element {
 94    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
 95        write!(fmt, "{}", String::from(self))?;
 96        Ok(())
 97    }
 98}
 99
100impl FromStr for Element {
101    type Err = Error;
102
103    fn from_str(s: &str) -> Result<Element, Error> {
104        let mut reader = EventReader::new(Cursor::new(s));
105        Element::from_reader(&mut reader)
106    }
107}
108
109impl Element {
110    fn new(name: String, namespace: Option<String>, attributes: BTreeMap<String, String>, children: Vec<Node>) -> Element {
111        Element {
112            name: name,
113            namespace: namespace,
114            attributes: attributes,
115            children: children,
116        }
117    }
118
119    /// Return a builder for an `Element` with the given `name`.
120    ///
121    /// # Examples
122    ///
123    /// ```rust
124    /// use minidom::Element;
125    ///
126    /// let elem = Element::builder("name")
127    ///                    .ns("namespace")
128    ///                    .attr("name", "value")
129    ///                    .append("inner")
130    ///                    .build();
131    ///
132    /// assert_eq!(elem.name(), "name");
133    /// assert_eq!(elem.ns(), Some("namespace"));
134    /// assert_eq!(elem.attr("name"), Some("value"));
135    /// assert_eq!(elem.attr("inexistent"), None);
136    /// assert_eq!(elem.text(), "inner");
137    /// ```
138    pub fn builder<S: Into<String>>(name: S) -> ElementBuilder {
139        ElementBuilder {
140            root: Element::new(name.into(), None, BTreeMap::new(), Vec::new()),
141        }
142    }
143
144    /// Returns a bare minimum `Element` with this name.
145    ///
146    /// # Examples
147    ///
148    /// ```rust
149    /// use minidom::Element;
150    ///
151    /// let bare = Element::bare("name");
152    ///
153    /// assert_eq!(bare.name(), "name");
154    /// assert_eq!(bare.ns(), None);
155    /// assert_eq!(bare.attr("name"), None);
156    /// assert_eq!(bare.text(), "");
157    /// ```
158    pub fn bare<S: Into<String>>(name: S) -> Element {
159        Element {
160            name: name.into(),
161            namespace: None,
162            attributes: BTreeMap::new(),
163            children: Vec::new(),
164        }
165    }
166
167    /// Returns a reference to the name of this element.
168    pub fn name(&self) -> &str {
169        &self.name
170    }
171
172    /// Returns a reference to the namespace of this element, if it has one, else `None`.
173    pub fn ns(&self) -> Option<&str> {
174        self.namespace.as_ref()
175                      .map(String::as_ref)
176    }
177
178    /// Returns a reference to the value of the given attribute, if it exists, else `None`.
179    pub fn attr(&self, name: &str) -> Option<&str> {
180        if let Some(value) = self.attributes.get(name) {
181            return Some(&value)
182        }
183        None
184    }
185
186    /// Returns an iterator over the attributes of this element.
187    ///
188    /// # Example
189    ///
190    /// ```rust
191    /// use minidom::Element;
192    ///
193    /// let elm: Element = "<elem a=\"b\" />".parse().unwrap();
194    ///
195    /// let mut iter = elm.attrs();
196    ///
197    /// assert_eq!(iter.next().unwrap(), ("a", "b"));
198    /// assert_eq!(iter.next(), None);
199    /// ```
200    pub fn attrs<'a>(&'a self) -> Attrs<'a> {
201        Attrs {
202            iter: self.attributes.iter(),
203        }
204    }
205
206    /// Returns an iterator over the attributes of this element, with the value being a mutable
207    /// reference.
208    pub fn attrs_mut<'a>(&'a mut self) -> AttrsMut<'a> {
209        AttrsMut {
210            iter: self.attributes.iter_mut(),
211        }
212    }
213
214    /// Modifies the value of an attribute.
215    pub fn set_attr<S: Into<String>, V: IntoAttributeValue>(&mut self, name: S, val: V) {
216        let name = name.into();
217        let val = val.into_attribute_value();
218
219        if let Some(value) = self.attributes.get_mut(&name) {
220            *value = val.expect("removing existing value via set_attr, this is not yet supported (TODO)"); // TODO
221            return;
222        }
223
224        if let Some(val) = val {
225            self.attributes.insert(name, val);
226        }
227    }
228
229    /// Returns whether the element has the given name and namespace.
230    ///
231    /// # Examples
232    ///
233    /// ```rust
234    /// use minidom::Element;
235    ///
236    /// let elem = Element::builder("name").ns("namespace").build();
237    ///
238    /// assert_eq!(elem.is("name", "namespace"), true);
239    /// assert_eq!(elem.is("name", "wrong"), false);
240    /// assert_eq!(elem.is("wrong", "namespace"), false);
241    /// assert_eq!(elem.is("wrong", "wrong"), false);
242    /// ```
243    pub fn is<N: AsRef<str>, NS: AsRef<str>>(&self, name: N, namespace: NS) -> bool {
244        let ns = self.namespace.as_ref().map(String::as_ref);
245        self.name == name.as_ref() && ns == Some(namespace.as_ref())
246    }
247
248    /// Parse a document from an `EventReader`.
249    pub fn from_reader<R: Read>(reader: &mut EventReader<R>) -> Result<Element, Error> {
250        loop {
251            let e = reader.next()?;
252            match e {
253                ReaderEvent::StartElement { name, attributes, namespace } => {
254                    let attributes = attributes.into_iter()
255                                               .map(|o| {
256                                                    (match o.name.prefix {
257                                                        Some(prefix) => format!("{}:{}", prefix, o.name.local_name),
258                                                        None => o.name.local_name
259                                                    },
260                                                    o.value)
261                                                })
262                                               .collect();
263                    let ns = if let Some(ref prefix) = name.prefix {
264                        namespace.get(prefix)
265                    }
266                    else {
267                        namespace.get(NS_NO_PREFIX)
268                    }.map(|s| s.to_owned());
269
270                    let mut root = Element::new(name.local_name, ns, attributes, Vec::new());
271                    root.from_reader_inner(reader)?;
272                    return Ok(root);
273                },
274                ReaderEvent::EndDocument => {
275                    return Err(Error::EndOfDocument);
276                },
277                _ => () // TODO: may need more errors
278            }
279        }
280    }
281
282    fn from_reader_inner<R: Read>(&mut self, reader: &mut EventReader<R>) -> Result<(), Error> {
283        loop {
284            let e = reader.next()?;
285            match e {
286                ReaderEvent::StartElement { name, attributes, namespace } => {
287                    let attributes = attributes.into_iter()
288                                               .map(|o| {
289                                                    (match o.name.prefix {
290                                                        Some(prefix) => format!("{}:{}", prefix, o.name.local_name),
291                                                        None => o.name.local_name
292                                                    },
293                                                    o.value)
294                                                })
295                                               .collect();
296                    let ns = if let Some(ref prefix) = name.prefix {
297                        namespace.get(prefix)
298                    }
299                    else {
300                        namespace.get(NS_NO_PREFIX)
301                    }.map(|s| s.to_owned());
302                    let elem = Element::new(name.local_name, ns, attributes, Vec::with_capacity(1));
303                    let elem_ref = self.append_child(elem);
304                    elem_ref.from_reader_inner(reader)?;
305                },
306                ReaderEvent::EndElement { .. } => {
307                    // TODO: may want to check whether we're closing the correct element
308                    return Ok(());
309                },
310                ReaderEvent::Characters(s) => {
311                    self.append_text_node(s);
312                },
313                ReaderEvent::CData(s) => {
314                    self.append_text_node(s);
315                },
316                ReaderEvent::EndDocument => {
317                    return Err(Error::EndOfDocument);
318                },
319                _ => (), // TODO: may need to implement more
320            }
321        }
322    }
323
324    /// Output a document to an `EventWriter`.
325    pub fn write_to<W: Write>(&self, writer: &mut EventWriter<W>) -> Result<(), Error> {
326        let name = if let Some(ref ns) = self.namespace {
327            Name::qualified(&self.name, &ns, None)
328        }
329        else {
330            Name::local(&self.name)
331        };
332        let mut start = WriterEvent::start_element(name);
333        if let Some(ref ns) = self.namespace {
334            start = start.default_ns(ns.clone());
335        }
336        for attr in &self.attributes { // TODO: I think this could be done a lot more efficiently
337            start = start.attr(Name::local(&attr.0), &attr.1);
338        }
339        writer.write(start)?;
340        for child in &self.children {
341            match *child {
342                Node::Element(ref e) => {
343                    e.write_to(writer)?;
344                },
345                Node::Text(ref s) => {
346                    writer.write(WriterEvent::characters(s))?;
347                },
348            }
349        }
350        writer.write(WriterEvent::end_element())?;
351        Ok(())
352    }
353
354    /// Returns an iterator over references to every child node of this element.
355    ///
356    /// # Examples
357    ///
358    /// ```rust
359    /// use minidom::{Element, Node};
360    ///
361    /// let elem: Element = "<root>a<c1 />b<c2 />c</root>".parse().unwrap();
362    ///
363    /// let mut iter = elem.nodes();
364    ///
365    /// assert_eq!(iter.next().unwrap().as_text().unwrap(), "a");
366    /// assert_eq!(iter.next().unwrap().as_element().unwrap().name(), "c1");
367    /// assert_eq!(iter.next().unwrap().as_text().unwrap(), "b");
368    /// assert_eq!(iter.next().unwrap().as_element().unwrap().name(), "c2");
369    /// assert_eq!(iter.next().unwrap().as_text().unwrap(), "c");
370    /// assert_eq!(iter.next(), None);
371    /// ```
372    #[inline] pub fn nodes<'a>(&'a self) -> Nodes<'a> {
373        self.children.iter()
374    }
375
376    /// Returns an iterator over mutable references to every child node of this element.
377    #[inline] pub fn nodes_mut<'a>(&'a mut self) -> NodesMut<'a> {
378        self.children.iter_mut()
379    }
380
381    /// Returns an iterator over references to every child element of this element.
382    ///
383    /// # Examples
384    ///
385    /// ```rust
386    /// use minidom::Element;
387    ///
388    /// let elem: Element = "<root>hello<child1 />this<child2 />is<child3 />ignored</root>".parse().unwrap();
389    ///
390    /// let mut iter = elem.children();
391    /// assert_eq!(iter.next().unwrap().name(), "child1");
392    /// assert_eq!(iter.next().unwrap().name(), "child2");
393    /// assert_eq!(iter.next().unwrap().name(), "child3");
394    /// assert_eq!(iter.next(), None);
395    /// ```
396    #[inline] pub fn children<'a>(&'a self) -> Children<'a> {
397        Children {
398            iter: self.children.iter(),
399        }
400    }
401
402    /// Returns an iterator over mutable references to every child element of this element.
403    #[inline] pub fn children_mut<'a>(&'a mut self) -> ChildrenMut<'a> {
404        ChildrenMut {
405            iter: self.children.iter_mut(),
406        }
407    }
408
409    /// Returns an iterator over references to every text node of this element.
410    ///
411    /// # Examples
412    ///
413    /// ```rust
414    /// use minidom::Element;
415    ///
416    /// let elem: Element = "<root>hello<c /> world!</root>".parse().unwrap();
417    ///
418    /// let mut iter = elem.texts();
419    /// assert_eq!(iter.next().unwrap(), "hello");
420    /// assert_eq!(iter.next().unwrap(), " world!");
421    /// assert_eq!(iter.next(), None);
422    /// ```
423    #[inline] pub fn texts<'a>(&'a self) -> Texts<'a> {
424        Texts {
425            iter: self.children.iter(),
426        }
427    }
428
429    /// Returns an iterator over mutable references to every text node of this element.
430    #[inline] pub fn texts_mut<'a>(&'a mut self) -> TextsMut<'a> {
431        TextsMut {
432            iter: self.children.iter_mut(),
433        }
434    }
435
436    /// Appends a child node to the `Element`, returning the appended node.
437    ///
438    /// # Examples
439    ///
440    /// ```rust
441    /// use minidom::Element;
442    ///
443    /// let mut elem = Element::bare("root");
444    ///
445    /// assert_eq!(elem.children().count(), 0);
446    ///
447    /// elem.append_child(Element::bare("child"));
448    ///
449    /// {
450    ///     let mut iter = elem.children();
451    ///     assert_eq!(iter.next().unwrap().name(), "child");
452    ///     assert_eq!(iter.next(), None);
453    /// }
454    ///
455    /// let child = elem.append_child(Element::bare("new"));
456    ///
457    /// assert_eq!(child.name(), "new");
458    /// ```
459    pub fn append_child(&mut self, mut child: Element) -> &mut Element {
460        if child.namespace.is_none() && self.namespace.is_some() {
461            child.namespace = self.namespace.clone();
462            child.propagate_namespaces();
463        }
464        self.children.push(Node::Element(child));
465        if let Node::Element(ref mut cld) = *self.children.last_mut().unwrap() {
466            cld
467        }
468        else {
469            unreachable!()
470        }
471    }
472
473    fn propagate_namespaces(&mut self) {
474        let ns = self.namespace.clone();
475        for child in self.children_mut() {
476            if child.namespace.is_none() {
477                child.namespace = ns.clone();
478                child.propagate_namespaces();
479            }
480        }
481    }
482
483    /// Appends a text node to an `Element`.
484    ///
485    /// # Examples
486    ///
487    /// ```rust
488    /// use minidom::Element;
489    ///
490    /// let mut elem = Element::bare("node");
491    ///
492    /// assert_eq!(elem.text(), "");
493    ///
494    /// elem.append_text_node("text");
495    ///
496    /// assert_eq!(elem.text(), "text");
497    /// ```
498    pub fn append_text_node<S: Into<String>>(&mut self, child: S) {
499        self.children.push(Node::Text(child.into()));
500    }
501
502    /// Appends a node to an `Element`.
503    ///
504    /// # Examples
505    ///
506    /// ```rust
507    /// use minidom::{Element, Node};
508    ///
509    /// let mut elem = Element::bare("node");
510    ///
511    /// elem.append_node(Node::Text("hello".to_owned()));
512    ///
513    /// assert_eq!(elem.text(), "hello");
514    /// ```
515    pub fn append_node(&mut self, node: Node) {
516        self.children.push(node);
517    }
518
519    /// Returns the concatenation of all text nodes in the `Element`.
520    ///
521    /// # Examples
522    ///
523    /// ```rust
524    /// use minidom::Element;
525    ///
526    /// let elem: Element = "<node>hello,<split /> world!</node>".parse().unwrap();
527    ///
528    /// assert_eq!(elem.text(), "hello, world!");
529    /// ```
530    pub fn text(&self) -> String {
531        self.texts().fold(String::new(), |ret, new| ret + new)
532    }
533
534    /// Returns a reference to the first child element with the specific name and namespace, if it
535    /// exists in the direct descendants of this `Element`, else returns `None`.
536    ///
537    /// # Examples
538    ///
539    /// ```rust
540    /// use minidom::Element;
541    ///
542    /// let elem: Element = r#"<node xmlns="ns"><a /><a xmlns="other_ns" /><b /></node>"#.parse().unwrap();
543    ///
544    /// assert!(elem.get_child("a", "ns").unwrap().is("a", "ns"));
545    /// assert!(elem.get_child("a", "other_ns").unwrap().is("a", "other_ns"));
546    /// assert!(elem.get_child("b", "ns").unwrap().is("b", "ns"));
547    /// assert_eq!(elem.get_child("c", "ns"), None);
548    /// assert_eq!(elem.get_child("b", "other_ns"), None);
549    /// assert_eq!(elem.get_child("a", "inexistent_ns"), None);
550    /// ```
551    pub fn get_child<N: AsRef<str>, NS: AsRef<str>>(&self, name: N, namespace: NS) -> Option<&Element> {
552        for fork in &self.children {
553            if let Node::Element(ref e) = *fork {
554                if e.is(name.as_ref(), namespace.as_ref()) {
555                    return Some(e);
556                }
557            }
558        }
559        None
560    }
561
562    /// Returns a mutable reference to the first child element with the specific name and namespace,
563    /// if it exists in the direct descendants of this `Element`, else returns `None`.
564    pub fn get_child_mut<N: AsRef<str>, NS: AsRef<str>>(&mut self, name: N, namespace: NS) -> Option<&mut Element> {
565        for fork in &mut self.children {
566            if let Node::Element(ref mut e) = *fork {
567                if e.is(name.as_ref(), namespace.as_ref()) {
568                    return Some(e);
569                }
570            }
571        }
572        None
573    }
574
575    /// Returns whether a specific child with this name and namespace exists in the direct
576    /// descendants of the `Element`.
577    ///
578    /// # Examples
579    ///
580    /// ```rust
581    /// use minidom::Element;
582    ///
583    /// let elem: Element = r#"<node xmlns="ns"><a /><a xmlns="other_ns" /><b /></node>"#.parse().unwrap();
584    ///
585    /// assert_eq!(elem.has_child("a", "other_ns"), true);
586    /// assert_eq!(elem.has_child("a", "ns"), true);
587    /// assert_eq!(elem.has_child("a", "inexistent_ns"), false);
588    /// assert_eq!(elem.has_child("b", "ns"), true);
589    /// assert_eq!(elem.has_child("b", "other_ns"), false);
590    /// assert_eq!(elem.has_child("b", "inexistent_ns"), false);
591    /// ```
592    pub fn has_child<N: AsRef<str>, NS: AsRef<str>>(&self, name: N, namespace: NS) -> bool {
593        self.get_child(name, namespace).is_some()
594    }
595}
596
597/// An iterator over references to child elements of an `Element`.
598pub struct Children<'a> {
599    iter: slice::Iter<'a, Node>,
600}
601
602impl<'a> Iterator for Children<'a> {
603    type Item = &'a Element;
604
605    fn next(&mut self) -> Option<&'a Element> {
606        while let Some(item) = self.iter.next() {
607            if let Node::Element(ref child) = *item {
608                return Some(child);
609            }
610        }
611        None
612    }
613}
614
615/// An iterator over mutable references to child elements of an `Element`.
616pub struct ChildrenMut<'a> {
617    iter: slice::IterMut<'a, Node>,
618}
619
620impl<'a> Iterator for ChildrenMut<'a> {
621    type Item = &'a mut Element;
622
623    fn next(&mut self) -> Option<&'a mut Element> {
624        while let Some(item) = self.iter.next() {
625            if let Node::Element(ref mut child) = *item {
626                return Some(child);
627            }
628        }
629        None
630    }
631}
632
633/// An iterator over references to child text nodes of an `Element`.
634pub struct Texts<'a> {
635    iter: slice::Iter<'a, Node>,
636}
637
638impl<'a> Iterator for Texts<'a> {
639    type Item = &'a str;
640
641    fn next(&mut self) -> Option<&'a str> {
642        while let Some(item) = self.iter.next() {
643            if let Node::Text(ref child) = *item {
644                return Some(child);
645            }
646        }
647        None
648    }
649}
650
651/// An iterator over mutable references to child text nodes of an `Element`.
652pub struct TextsMut<'a> {
653    iter: slice::IterMut<'a, Node>,
654}
655
656impl<'a> Iterator for TextsMut<'a> {
657    type Item = &'a mut String;
658
659    fn next(&mut self) -> Option<&'a mut String> {
660        while let Some(item) = self.iter.next() {
661            if let Node::Text(ref mut child) = *item {
662                return Some(child);
663            }
664        }
665        None
666    }
667}
668
669/// An iterator over references to all child nodes of an `Element`.
670pub type Nodes<'a> = slice::Iter<'a, Node>;
671
672/// An iterator over mutable references to all child nodes of an `Element`.
673pub type NodesMut<'a> = slice::IterMut<'a, Node>;
674
675/// An iterator over the attributes of an `Element`.
676pub struct Attrs<'a> {
677    iter: btree_map::Iter<'a, String, String>,
678}
679
680impl<'a> Iterator for Attrs<'a> {
681    type Item = (&'a str, &'a str);
682
683    fn next(&mut self) -> Option<Self::Item> {
684        self.iter.next().map(|(x, y)| (x.as_ref(), y.as_ref()))
685    }
686}
687
688/// An iterator over the attributes of an `Element`, with the values mutable.
689pub struct AttrsMut<'a> {
690    iter: btree_map::IterMut<'a, String, String>,
691}
692
693impl<'a> Iterator for AttrsMut<'a> {
694    type Item = (&'a str, &'a mut String);
695
696    fn next(&mut self) -> Option<Self::Item> {
697        self.iter.next().map(|(x, y)| (x.as_ref(), y))
698    }
699}
700
701/// A builder for `Element`s.
702pub struct ElementBuilder {
703    root: Element,
704}
705
706impl ElementBuilder {
707    /// Sets the namespace.
708    pub fn ns<S: Into<String>>(mut self, namespace: S) -> ElementBuilder {
709        self.root.namespace = Some(namespace.into());
710        self
711    }
712
713    /// Sets an attribute.
714    pub fn attr<S: Into<String>, V: IntoAttributeValue>(mut self, name: S, value: V) -> ElementBuilder {
715        self.root.set_attr(name, value);
716        self
717    }
718
719    /// Appends anything implementing `IntoElements` into the tree.
720    pub fn append<T: IntoElements>(mut self, into: T) -> ElementBuilder {
721        {
722            let mut emitter = ElementEmitter::new(&mut self.root);
723            into.into_elements(&mut emitter);
724        }
725        self
726    }
727
728    /// Builds the `Element`.
729    pub fn build(self) -> Element {
730        self.root
731    }
732}
733
734#[test]
735fn test_element_new() {
736    use std::iter::FromIterator;
737
738    let elem = Element::new( "name".to_owned()
739                           , Some("namespace".to_owned())
740                           , BTreeMap::from_iter(vec![ ("name".to_string(), "value".to_string()) ].into_iter() )
741                           , Vec::new() );
742
743    assert_eq!(elem.name(), "name");
744    assert_eq!(elem.ns(), Some("namespace"));
745    assert_eq!(elem.attr("name"), Some("value"));
746    assert_eq!(elem.attr("inexistent"), None);
747}