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 as EventReader;
  13use quick_xml::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_plain_str(s)))?;
 130                ()
 131            },
 132            Node::Comment(ref s) => {
 133                writer.write_event(Event::Comment(BytesText::from_plain_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) => {
 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::CData(s) => {
 425                    let text = reader.decode(&s).into_owned();
 426                    if text != "" {
 427                        let mut current_elem = stack.last_mut().unwrap();
 428                        current_elem.append_text_node(text);
 429                    }
 430                },
 431                Event::Eof => {
 432                    break;
 433                },
 434                Event::Comment(s) => {
 435                    let comment = reader.decode(&s).into_owned();
 436                    if comment != "" {
 437                        let current_elem = stack.last_mut().unwrap();
 438                        current_elem.append_comment_node(comment);
 439                    }
 440                },
 441                Event::Decl { .. } |
 442                Event::PI { .. } |
 443                Event::DocType { .. } => (),
 444            }
 445        }
 446        Ok(stack.pop().unwrap())
 447    }
 448
 449    /// Output a document to a `Writer`.
 450    pub fn write_to<W: Write>(&self, writer: &mut W) -> Result<()> {
 451        self.to_writer(&mut EventWriter::new(writer))
 452    }
 453
 454    /// Output the document to quick-xml `Writer`
 455    pub fn to_writer<W: Write>(&self, writer: &mut EventWriter<W>) -> Result<()> {
 456        writer.write_event(Event::Decl(BytesDecl::new(b"1.0", Some(b"utf-8"), None)))?;
 457        self.write_to_inner(writer)
 458    }
 459
 460    /// Like `write_to()` but without the `<?xml?>` prelude
 461    pub fn write_to_inner<W: Write>(&self, writer: &mut EventWriter<W>) -> Result<()> {
 462        let name = match self.prefix {
 463            None => Cow::Borrowed(&self.name),
 464            Some(ref prefix) => Cow::Owned(format!("{}:{}", prefix, self.name)),
 465        };
 466
 467        let mut start = BytesStart::borrowed(name.as_bytes(), name.len());
 468        for (prefix, ns) in self.namespaces.declared_ns() {
 469            match *prefix {
 470                None => start.push_attribute(("xmlns", ns.as_ref())),
 471                Some(ref prefix) => {
 472                    let key = format!("xmlns:{}", prefix);
 473                    start.push_attribute((key.as_bytes(), ns.as_bytes()))
 474                },
 475            }
 476        }
 477        for (key, value) in &self.attributes {
 478            start.push_attribute((key.as_bytes(), escape(value.as_bytes()).as_ref()));
 479        }
 480
 481        if self.children.is_empty() {
 482            writer.write_event(Event::Empty(start))?;
 483            return Ok(())
 484        }
 485
 486        writer.write_event(Event::Start(start))?;
 487
 488        for child in &self.children {
 489            child.write_to_inner(writer)?;
 490        }
 491
 492        writer.write_event(Event::End(BytesEnd::borrowed(name.as_bytes())))?;
 493        Ok(())
 494    }
 495
 496    /// Returns an iterator over references to every child node of this element.
 497    ///
 498    /// # Examples
 499    ///
 500    /// ```rust
 501    /// use minidom::Element;
 502    ///
 503    /// let elem: Element = "<root>a<c1 />b<c2 />c</root>".parse().unwrap();
 504    ///
 505    /// let mut iter = elem.nodes();
 506    ///
 507    /// assert_eq!(iter.next().unwrap().as_text().unwrap(), "a");
 508    /// assert_eq!(iter.next().unwrap().as_element().unwrap().name(), "c1");
 509    /// assert_eq!(iter.next().unwrap().as_text().unwrap(), "b");
 510    /// assert_eq!(iter.next().unwrap().as_element().unwrap().name(), "c2");
 511    /// assert_eq!(iter.next().unwrap().as_text().unwrap(), "c");
 512    /// assert_eq!(iter.next(), None);
 513    /// ```
 514    #[inline] pub fn nodes(&self) -> Nodes {
 515        self.children.iter()
 516    }
 517
 518    /// Returns an iterator over mutable references to every child node of this element.
 519    #[inline] pub fn nodes_mut(&mut self) -> NodesMut {
 520        self.children.iter_mut()
 521    }
 522
 523    /// Returns an iterator over references to every child element of this element.
 524    ///
 525    /// # Examples
 526    ///
 527    /// ```rust
 528    /// use minidom::Element;
 529    ///
 530    /// let elem: Element = "<root>hello<child1 />this<child2 />is<child3 />ignored</root>".parse().unwrap();
 531    ///
 532    /// let mut iter = elem.children();
 533    /// assert_eq!(iter.next().unwrap().name(), "child1");
 534    /// assert_eq!(iter.next().unwrap().name(), "child2");
 535    /// assert_eq!(iter.next().unwrap().name(), "child3");
 536    /// assert_eq!(iter.next(), None);
 537    /// ```
 538    #[inline] pub fn children(&self) -> Children {
 539        Children {
 540            iter: self.children.iter(),
 541        }
 542    }
 543
 544    /// Returns an iterator over mutable references to every child element of this element.
 545    #[inline] pub fn children_mut(&mut self) -> ChildrenMut {
 546        ChildrenMut {
 547            iter: self.children.iter_mut(),
 548        }
 549    }
 550
 551    /// Returns an iterator over references to every text node of this element.
 552    ///
 553    /// # Examples
 554    ///
 555    /// ```rust
 556    /// use minidom::Element;
 557    ///
 558    /// let elem: Element = "<root>hello<c /> world!</root>".parse().unwrap();
 559    ///
 560    /// let mut iter = elem.texts();
 561    /// assert_eq!(iter.next().unwrap(), "hello");
 562    /// assert_eq!(iter.next().unwrap(), " world!");
 563    /// assert_eq!(iter.next(), None);
 564    /// ```
 565    #[inline] pub fn texts(&self) -> Texts {
 566        Texts {
 567            iter: self.children.iter(),
 568        }
 569    }
 570
 571    /// Returns an iterator over mutable references to every text node of this element.
 572    #[inline] pub fn texts_mut(&mut self) -> TextsMut {
 573        TextsMut {
 574            iter: self.children.iter_mut(),
 575        }
 576    }
 577
 578    /// Appends a child node to the `Element`, returning the appended node.
 579    ///
 580    /// # Examples
 581    ///
 582    /// ```rust
 583    /// use minidom::Element;
 584    ///
 585    /// let mut elem = Element::bare("root");
 586    ///
 587    /// assert_eq!(elem.children().count(), 0);
 588    ///
 589    /// elem.append_child(Element::bare("child"));
 590    ///
 591    /// {
 592    ///     let mut iter = elem.children();
 593    ///     assert_eq!(iter.next().unwrap().name(), "child");
 594    ///     assert_eq!(iter.next(), None);
 595    /// }
 596    ///
 597    /// let child = elem.append_child(Element::bare("new"));
 598    ///
 599    /// assert_eq!(child.name(), "new");
 600    /// ```
 601    pub fn append_child(&mut self, child: Element) -> &mut Element {
 602        child.namespaces.set_parent(Rc::clone(&self.namespaces));
 603
 604        self.children.push(Node::Element(child));
 605        if let Node::Element(ref mut cld) = *self.children.last_mut().unwrap() {
 606            cld
 607        } else {
 608            unreachable!()
 609        }
 610    }
 611
 612    /// Appends a text node to an `Element`.
 613    ///
 614    /// # Examples
 615    ///
 616    /// ```rust
 617    /// use minidom::Element;
 618    ///
 619    /// let mut elem = Element::bare("node");
 620    ///
 621    /// assert_eq!(elem.text(), "");
 622    ///
 623    /// elem.append_text_node("text");
 624    ///
 625    /// assert_eq!(elem.text(), "text");
 626    /// ```
 627    pub fn append_text_node<S: Into<String>>(&mut self, child: S) {
 628        self.children.push(Node::Text(child.into()));
 629    }
 630
 631    /// Appends a comment node to an `Element`.
 632    ///
 633    /// # Examples
 634    ///
 635    /// ```rust
 636    /// use minidom::Element;
 637    ///
 638    /// let mut elem = Element::bare("node");
 639    ///
 640    /// elem.append_comment_node("comment");
 641    /// ```
 642    pub fn append_comment_node<S: Into<String>>(&mut self, child: S) {
 643        self.children.push(Node::Comment(child.into()));
 644    }
 645
 646    /// Appends a node to an `Element`.
 647    ///
 648    /// # Examples
 649    ///
 650    /// ```rust
 651    /// use minidom::{Element, Node};
 652    ///
 653    /// let mut elem = Element::bare("node");
 654    ///
 655    /// elem.append_node(Node::Text("hello".to_owned()));
 656    ///
 657    /// assert_eq!(elem.text(), "hello");
 658    /// ```
 659    pub fn append_node(&mut self, node: Node) {
 660        self.children.push(node);
 661    }
 662
 663    /// Returns the concatenation of all text nodes in the `Element`.
 664    ///
 665    /// # Examples
 666    ///
 667    /// ```rust
 668    /// use minidom::Element;
 669    ///
 670    /// let elem: Element = "<node>hello,<split /> world!</node>".parse().unwrap();
 671    ///
 672    /// assert_eq!(elem.text(), "hello, world!");
 673    /// ```
 674    pub fn text(&self) -> String {
 675        self.texts().fold(String::new(), |ret, new| ret + new)
 676    }
 677
 678    /// Returns a reference to the first child element with the specific name and namespace, if it
 679    /// exists in the direct descendants of this `Element`, else returns `None`.
 680    ///
 681    /// # Examples
 682    ///
 683    /// ```rust
 684    /// use minidom::Element;
 685    ///
 686    /// let elem: Element = r#"<node xmlns="ns"><a /><a xmlns="other_ns" /><b /></node>"#.parse().unwrap();
 687    ///
 688    /// assert!(elem.get_child("a", "ns").unwrap().is("a", "ns"));
 689    /// assert!(elem.get_child("a", "other_ns").unwrap().is("a", "other_ns"));
 690    /// assert!(elem.get_child("b", "ns").unwrap().is("b", "ns"));
 691    /// assert_eq!(elem.get_child("c", "ns"), None);
 692    /// assert_eq!(elem.get_child("b", "other_ns"), None);
 693    /// assert_eq!(elem.get_child("a", "inexistent_ns"), None);
 694    /// ```
 695    pub fn get_child<N: AsRef<str>, NS: AsRef<str>>(&self, name: N, namespace: NS) -> Option<&Element> {
 696        for fork in &self.children {
 697            if let Node::Element(ref e) = *fork {
 698                if e.is(name.as_ref(), namespace.as_ref()) {
 699                    return Some(e);
 700                }
 701            }
 702        }
 703        None
 704    }
 705
 706    /// Returns a mutable reference to the first child element with the specific name and namespace,
 707    /// if it exists in the direct descendants of this `Element`, else returns `None`.
 708    pub fn get_child_mut<N: AsRef<str>, NS: AsRef<str>>(&mut self, name: N, namespace: NS) -> Option<&mut Element> {
 709        for fork in &mut self.children {
 710            if let Node::Element(ref mut e) = *fork {
 711                if e.is(name.as_ref(), namespace.as_ref()) {
 712                    return Some(e);
 713                }
 714            }
 715        }
 716        None
 717    }
 718
 719    /// Returns whether a specific child with this name and namespace exists in the direct
 720    /// descendants of the `Element`.
 721    ///
 722    /// # Examples
 723    ///
 724    /// ```rust
 725    /// use minidom::Element;
 726    ///
 727    /// let elem: Element = r#"<node xmlns="ns"><a /><a xmlns="other_ns" /><b /></node>"#.parse().unwrap();
 728    ///
 729    /// assert_eq!(elem.has_child("a", "other_ns"), true);
 730    /// assert_eq!(elem.has_child("a", "ns"), true);
 731    /// assert_eq!(elem.has_child("a", "inexistent_ns"), false);
 732    /// assert_eq!(elem.has_child("b", "ns"), true);
 733    /// assert_eq!(elem.has_child("b", "other_ns"), false);
 734    /// assert_eq!(elem.has_child("b", "inexistent_ns"), false);
 735    /// ```
 736    pub fn has_child<N: AsRef<str>, NS: AsRef<str>>(&self, name: N, namespace: NS) -> bool {
 737        self.get_child(name, namespace).is_some()
 738    }
 739}
 740
 741fn split_element_name<S: AsRef<str>>(s: S) -> Result<(Option<String>, String)> {
 742    let name_parts = s.as_ref().split(':').collect::<Vec<&str>>();
 743    match name_parts.len() {
 744        2 => Ok((Some(name_parts[0].to_owned()), name_parts[1].to_owned())),
 745        1 => Ok((None, name_parts[0].to_owned())),
 746        _ => Err(Error::InvalidElement),
 747    }
 748}
 749
 750fn build_element<R: BufRead>(reader: &EventReader<R>, event: &BytesStart) -> Result<Element> {
 751    let mut namespaces = BTreeMap::new();
 752    let attributes = event.attributes()
 753        .map(|o| {
 754            let o = o?;
 755            let key = str::from_utf8(o.key)?.to_owned();
 756            let value = o.unescape_and_decode_value(reader)?;
 757            Ok((key, value))
 758        })
 759        .filter(|o| {
 760            match *o {
 761                Ok((ref key, ref value)) if key == "xmlns" => {
 762                    namespaces.insert(None, value.to_owned());
 763                    false
 764                },
 765                Ok((ref key, ref value)) if key.starts_with("xmlns:") => {
 766                    namespaces.insert(Some(key[6..].to_owned()), value.to_owned());
 767                    false
 768                },
 769                _ => true,
 770            }
 771        })
 772        .collect::<Result<BTreeMap<String, String>>>()?;
 773
 774    let (prefix, name) = split_element_name(str::from_utf8(event.name())?)?;
 775    let element = Element::new(name, prefix, namespaces, attributes, Vec::new());
 776    Ok(element)
 777}
 778
 779/// An iterator over references to child elements of an `Element`.
 780pub struct Children<'a> {
 781    iter: slice::Iter<'a, Node>,
 782}
 783
 784impl<'a> Iterator for Children<'a> {
 785    type Item = &'a Element;
 786
 787    fn next(&mut self) -> Option<&'a Element> {
 788        for item in &mut self.iter {
 789            if let Node::Element(ref child) = *item {
 790                return Some(child);
 791            }
 792        }
 793        None
 794    }
 795}
 796
 797/// An iterator over mutable references to child elements of an `Element`.
 798pub struct ChildrenMut<'a> {
 799    iter: slice::IterMut<'a, Node>,
 800}
 801
 802impl<'a> Iterator for ChildrenMut<'a> {
 803    type Item = &'a mut Element;
 804
 805    fn next(&mut self) -> Option<&'a mut Element> {
 806        for item in &mut self.iter {
 807            if let Node::Element(ref mut child) = *item {
 808                return Some(child);
 809            }
 810        }
 811        None
 812    }
 813}
 814
 815/// An iterator over references to child text nodes of an `Element`.
 816pub struct Texts<'a> {
 817    iter: slice::Iter<'a, Node>,
 818}
 819
 820impl<'a> Iterator for Texts<'a> {
 821    type Item = &'a str;
 822
 823    fn next(&mut self) -> Option<&'a str> {
 824        for item in &mut self.iter {
 825            if let Node::Text(ref child) = *item {
 826                return Some(child);
 827            }
 828        }
 829        None
 830    }
 831}
 832
 833/// An iterator over mutable references to child text nodes of an `Element`.
 834pub struct TextsMut<'a> {
 835    iter: slice::IterMut<'a, Node>,
 836}
 837
 838impl<'a> Iterator for TextsMut<'a> {
 839    type Item = &'a mut String;
 840
 841    fn next(&mut self) -> Option<&'a mut String> {
 842        for item in &mut self.iter {
 843            if let Node::Text(ref mut child) = *item {
 844                return Some(child);
 845            }
 846        }
 847        None
 848    }
 849}
 850
 851/// An iterator over references to all child nodes of an `Element`.
 852pub type Nodes<'a> = slice::Iter<'a, Node>;
 853
 854/// An iterator over mutable references to all child nodes of an `Element`.
 855pub type NodesMut<'a> = slice::IterMut<'a, Node>;
 856
 857/// An iterator over the attributes of an `Element`.
 858pub struct Attrs<'a> {
 859    iter: btree_map::Iter<'a, String, String>,
 860}
 861
 862impl<'a> Iterator for Attrs<'a> {
 863    type Item = (&'a str, &'a str);
 864
 865    fn next(&mut self) -> Option<Self::Item> {
 866        self.iter.next().map(|(x, y)| (x.as_ref(), y.as_ref()))
 867    }
 868}
 869
 870/// An iterator over the attributes of an `Element`, with the values mutable.
 871pub struct AttrsMut<'a> {
 872    iter: btree_map::IterMut<'a, String, String>,
 873}
 874
 875impl<'a> Iterator for AttrsMut<'a> {
 876    type Item = (&'a str, &'a mut String);
 877
 878    fn next(&mut self) -> Option<Self::Item> {
 879        self.iter.next().map(|(x, y)| (x.as_ref(), y))
 880    }
 881}
 882
 883/// A builder for `Element`s.
 884pub struct ElementBuilder {
 885    root: Element,
 886    namespaces: BTreeMap<Option<String>, String>,
 887}
 888
 889impl ElementBuilder {
 890    /// Sets the namespace.
 891    pub fn ns<S: Into<String>>(mut self, namespace: S) -> ElementBuilder {
 892        self.namespaces
 893            .insert(self.root.prefix.clone(), namespace.into());
 894        self
 895    }
 896
 897    /// Sets an attribute.
 898    pub fn attr<S: Into<String>, V: IntoAttributeValue>(mut self, name: S, value: V) -> ElementBuilder {
 899        self.root.set_attr(name, value);
 900        self
 901    }
 902
 903    /// Appends anything implementing `IntoElements` into the tree.
 904    pub fn append<T: IntoElements>(mut self, into: T) -> ElementBuilder {
 905        {
 906            let mut emitter = ElementEmitter::new(&mut self.root);
 907            into.into_elements(&mut emitter);
 908        }
 909        self
 910    }
 911
 912    /// Builds the `Element`.
 913    pub fn build(self) -> Element {
 914        let mut element = self.root;
 915        // Set namespaces
 916        element.namespaces = Rc::new(NamespaceSet::from(self.namespaces));
 917        // Propagate namespaces
 918        for node in &element.children {
 919            if let Node::Element(ref e) = *node {
 920                e.namespaces.set_parent(Rc::clone(&element.namespaces));
 921            }
 922        }
 923
 924        element
 925    }
 926}
 927
 928#[cfg(test)]
 929#[test]
 930fn test_element_new() {
 931    use std::iter::FromIterator;
 932
 933    let elem = Element::new( "name".to_owned()
 934                           , None
 935                           , Some("namespace".to_owned())
 936                           , BTreeMap::from_iter(vec![ ("name".to_string(), "value".to_string()) ].into_iter() )
 937                           , Vec::new() );
 938
 939    assert_eq!(elem.name(), "name");
 940    assert_eq!(elem.ns(), Some("namespace".to_owned()));
 941    assert_eq!(elem.attr("name"), Some("value"));
 942    assert_eq!(elem.attr("inexistent"), None);
 943}
 944
 945#[test]
 946fn test_from_reader_simple() {
 947    let xml = "<foo></foo>";
 948    let mut reader = EventReader::from_str(xml);
 949    let elem = Element::from_reader(&mut reader);
 950
 951    let elem2 = Element::builder("foo").build();
 952
 953    assert_eq!(elem.unwrap(), elem2);
 954}
 955
 956#[test]
 957fn test_from_reader_nested() {
 958    let xml = "<foo><bar baz='qxx' /></foo>";
 959    let mut reader = EventReader::from_str(xml);
 960    let elem = Element::from_reader(&mut reader);
 961
 962    let nested = Element::builder("bar")
 963                         .attr("baz", "qxx")
 964                         .build();
 965    let elem2 = Element::builder("foo")
 966                        .append(nested)
 967                        .build();
 968
 969    assert_eq!(elem.unwrap(), elem2);
 970}
 971
 972#[test]
 973fn test_from_reader_with_prefix() {
 974    let xml = "<foo><prefix:bar baz='qxx' /></foo>";
 975    let mut reader = EventReader::from_str(xml);
 976    let elem = Element::from_reader(&mut reader);
 977
 978    let nested = Element::builder("prefix:bar")
 979                         .attr("baz", "qxx")
 980                         .build();
 981    let elem2 = Element::builder("foo")
 982                        .append(nested)
 983                        .build();
 984
 985    assert_eq!(elem.unwrap(), elem2);
 986}
 987
 988#[test]
 989fn parses_spectest_xml() { // From: https://gitlab.com/lumi/minidom-rs/issues/8
 990    let xml = r#"
 991        <rng:grammar xmlns:rng="http://relaxng.org/ns/structure/1.0">
 992            <rng:name xmlns:rng="http://relaxng.org/ns/structure/1.0"></rng:name>
 993        </rng:grammar>
 994    "#;
 995    let mut reader = EventReader::from_str(xml);
 996    let _ = Element::from_reader(&mut reader).unwrap();
 997}
 998
 999#[test]
1000fn does_not_unescape_cdata() {
1001    let xml = "<test><![CDATA[&apos;&gt;blah<blah>]]></test>";
1002    let mut reader = EventReader::from_str(xml);
1003    let elem = Element::from_reader(&mut reader).unwrap();
1004    assert_eq!(elem.text(), "&apos;&gt;blah<blah>");
1005}