element.rs

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