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::namespaces::NSChoice;
  18use crate::node::Node;
  19use crate::prefixes::{Namespace, Prefix, Prefixes};
  20use crate::tree_builder::TreeBuilder;
  21
  22use std::collections::{btree_map, BTreeMap};
  23use std::io::{BufRead, Write};
  24use std::sync::Arc;
  25
  26use std::borrow::Cow;
  27use std::str;
  28
  29use rxml::writer::{Encoder, Item, TrackNamespace};
  30use rxml::{EventRead, Lexer, PullDriver, RawParser, XmlVersion};
  31
  32use std::str::FromStr;
  33
  34use std::slice;
  35
  36fn encode_and_write<W: Write, T: rxml::writer::TrackNamespace>(
  37    item: Item<'_>,
  38    enc: &mut Encoder<T>,
  39    mut w: W,
  40) -> rxml::Result<()> {
  41    let mut buf = rxml::bytes::BytesMut::new();
  42    enc.encode_into_bytes(item, &mut buf)
  43        .expect("encoder driven incorrectly");
  44    w.write_all(&buf[..])?;
  45    Ok(())
  46}
  47
  48/// Wrapper around a [`std::io::Write`] and an [`rxml::writer::Encoder`], to
  49/// provide a simple function to write an rxml Item to a writer.
  50pub struct CustomItemWriter<W, T> {
  51    writer: W,
  52    encoder: Encoder<T>,
  53}
  54
  55impl<W: Write> CustomItemWriter<W, rxml::writer::SimpleNamespaces> {
  56    pub(crate) fn new(writer: W) -> Self {
  57        Self {
  58            writer,
  59            encoder: Encoder::new(),
  60        }
  61    }
  62}
  63
  64impl<W: Write, T: rxml::writer::TrackNamespace> CustomItemWriter<W, T> {
  65    pub(crate) fn write(&mut self, item: Item<'_>) -> rxml::Result<()> {
  66        encode_and_write(item, &mut self.encoder, &mut self.writer)
  67    }
  68}
  69
  70/// Type alias to simplify the use for the default namespace tracking
  71/// implementation.
  72pub type ItemWriter<W> = CustomItemWriter<W, rxml::writer::SimpleNamespaces>;
  73
  74/// helper function to escape a `&[u8]` and replace all
  75/// xml special characters (<, >, &, ', ") with their corresponding
  76/// xml escaped value.
  77pub fn escape(raw: &[u8]) -> Cow<[u8]> {
  78    let mut escapes: Vec<(usize, &'static [u8])> = Vec::new();
  79    let mut bytes = raw.iter();
  80    fn to_escape(b: u8) -> bool {
  81        matches!(b, b'<' | b'>' | b'\'' | b'&' | b'"')
  82    }
  83
  84    let mut loc = 0;
  85    while let Some(i) = bytes.position(|&b| to_escape(b)) {
  86        loc += i;
  87        match raw[loc] {
  88            b'<' => escapes.push((loc, b"&lt;")),
  89            b'>' => escapes.push((loc, b"&gt;")),
  90            b'\'' => escapes.push((loc, b"&apos;")),
  91            b'&' => escapes.push((loc, b"&amp;")),
  92            b'"' => escapes.push((loc, b"&quot;")),
  93            _ => unreachable!("Only '<', '>','\', '&' and '\"' are escaped"),
  94        }
  95        loc += 1;
  96    }
  97
  98    if escapes.is_empty() {
  99        Cow::Borrowed(raw)
 100    } else {
 101        let len = raw.len();
 102        let mut v = Vec::with_capacity(len);
 103        let mut start = 0;
 104        for (i, r) in escapes {
 105            v.extend_from_slice(&raw[start..i]);
 106            v.extend_from_slice(r);
 107            start = i + 1;
 108        }
 109
 110        if start < len {
 111            v.extend_from_slice(&raw[start..]);
 112        }
 113        Cow::Owned(v)
 114    }
 115}
 116
 117#[derive(Clone, Eq, Debug)]
 118/// A struct representing a DOM Element.
 119pub struct Element {
 120    name: String,
 121    namespace: String,
 122    /// Namespace declarations
 123    pub prefixes: Prefixes,
 124    attributes: BTreeMap<String, String>,
 125    children: Vec<Node>,
 126}
 127
 128impl<'a> From<&'a Element> for String {
 129    fn from(elem: &'a Element) -> String {
 130        let mut writer = Vec::new();
 131        elem.write_to(&mut writer).unwrap();
 132        String::from_utf8(writer).unwrap()
 133    }
 134}
 135
 136impl FromStr for Element {
 137    type Err = Error;
 138
 139    fn from_str(s: &str) -> Result<Element> {
 140        Element::from_reader(s.as_bytes())
 141    }
 142}
 143
 144impl PartialEq for Element {
 145    fn eq(&self, other: &Self) -> bool {
 146        if self.name() == other.name() && self.ns() == other.ns() && self.attrs().eq(other.attrs())
 147        {
 148            if self.nodes().count() != other.nodes().count() {
 149                return false;
 150            }
 151            self.nodes()
 152                .zip(other.nodes())
 153                .all(|(node1, node2)| node1 == node2)
 154        } else {
 155            false
 156        }
 157    }
 158}
 159
 160impl Element {
 161    pub(crate) fn new<P: Into<Prefixes>>(
 162        name: String,
 163        namespace: String,
 164        prefixes: P,
 165        attributes: BTreeMap<String, String>,
 166        children: Vec<Node>,
 167    ) -> Element {
 168        Element {
 169            name,
 170            namespace,
 171            prefixes: prefixes.into(),
 172            attributes,
 173            children,
 174        }
 175    }
 176
 177    /// Return a builder for an `Element` with the given `name`.
 178    ///
 179    /// # Examples
 180    ///
 181    /// ```rust
 182    /// use minidom::Element;
 183    ///
 184    /// let elem = Element::builder("name", "namespace")
 185    ///                    .attr("name", "value")
 186    ///                    .append("inner")
 187    ///                    .build();
 188    ///
 189    /// assert_eq!(elem.name(), "name");
 190    /// assert_eq!(elem.ns(), "namespace".to_owned());
 191    /// assert_eq!(elem.attr("name"), Some("value"));
 192    /// assert_eq!(elem.attr("inexistent"), None);
 193    /// assert_eq!(elem.text(), "inner");
 194    /// ```
 195    pub fn builder<S: AsRef<str>, NS: Into<String>>(name: S, namespace: NS) -> ElementBuilder {
 196        ElementBuilder {
 197            root: Element::new(
 198                name.as_ref().to_string(),
 199                namespace.into(),
 200                None,
 201                BTreeMap::new(),
 202                Vec::new(),
 203            ),
 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", "namespace");
 215    ///
 216    /// assert_eq!(bare.name(), "name");
 217    /// assert_eq!(bare.ns(), "namespace");
 218    /// assert_eq!(bare.attr("name"), None);
 219    /// assert_eq!(bare.text(), "");
 220    /// ```
 221    pub fn bare<S: Into<String>, NS: Into<String>>(name: S, namespace: NS) -> Element {
 222        Element::new(
 223            name.into(),
 224            namespace.into(),
 225            None,
 226            BTreeMap::new(),
 227            Vec::new(),
 228        )
 229    }
 230
 231    /// Returns a reference to the local name of this element (that is, without a possible prefix).
 232    pub fn name(&self) -> &str {
 233        &self.name
 234    }
 235
 236    /// Returns a reference to the namespace of this element.
 237    pub fn ns(&self) -> String {
 238        self.namespace.clone()
 239    }
 240
 241    /// Returns a reference to the value of the given attribute, if it exists, else `None`.
 242    pub fn attr(&self, name: &str) -> Option<&str> {
 243        if let Some(value) = self.attributes.get(name) {
 244            return Some(value);
 245        }
 246        None
 247    }
 248
 249    /// Returns an iterator over the attributes of this element.
 250    ///
 251    /// # Example
 252    ///
 253    /// ```rust
 254    /// use minidom::Element;
 255    ///
 256    /// let elm: Element = "<elem xmlns=\"ns1\" a=\"b\" />".parse().unwrap();
 257    ///
 258    /// let mut iter = elm.attrs();
 259    ///
 260    /// assert_eq!(iter.next().unwrap(), ("a", "b"));
 261    /// assert_eq!(iter.next(), None);
 262    /// ```
 263    pub fn attrs(&self) -> Attrs {
 264        Attrs {
 265            iter: self.attributes.iter(),
 266        }
 267    }
 268
 269    /// Returns an iterator over the attributes of this element, with the value being a mutable
 270    /// reference.
 271    pub fn attrs_mut(&mut self) -> AttrsMut {
 272        AttrsMut {
 273            iter: self.attributes.iter_mut(),
 274        }
 275    }
 276
 277    /// Modifies the value of an attribute.
 278    pub fn set_attr<S: Into<String>, V: IntoAttributeValue>(&mut self, name: S, val: V) {
 279        let name = name.into();
 280        let val = val.into_attribute_value();
 281
 282        if let Some(value) = self.attributes.get_mut(&name) {
 283            *value = val
 284                .expect("removing existing value via set_attr, this is not yet supported (TODO)"); // TODO
 285            return;
 286        }
 287
 288        if let Some(val) = val {
 289            self.attributes.insert(name, val);
 290        }
 291    }
 292
 293    /// Returns whether the element has the given name and namespace.
 294    ///
 295    /// # Examples
 296    ///
 297    /// ```rust
 298    /// use minidom::{Element, NSChoice};
 299    ///
 300    /// let elem = Element::builder("name", "namespace").build();
 301    ///
 302    /// assert_eq!(elem.is("name", "namespace"), true);
 303    /// assert_eq!(elem.is("name", "wrong"), false);
 304    /// assert_eq!(elem.is("wrong", "namespace"), false);
 305    /// assert_eq!(elem.is("wrong", "wrong"), false);
 306    ///
 307    /// assert_eq!(elem.is("name", NSChoice::OneOf("namespace")), true);
 308    /// assert_eq!(elem.is("name", NSChoice::OneOf("foo")), false);
 309    /// assert_eq!(elem.is("name", NSChoice::AnyOf(&["foo", "namespace"])), true);
 310    /// assert_eq!(elem.is("name", NSChoice::Any), true);
 311    /// ```
 312    pub fn is<'a, N: AsRef<str>, NS: Into<NSChoice<'a>>>(&self, name: N, namespace: NS) -> bool {
 313        self.name == name.as_ref() && namespace.into().compare(self.namespace.as_ref())
 314    }
 315
 316    /// Returns whether the element has the given namespace.
 317    ///
 318    /// # Examples
 319    ///
 320    /// ```rust
 321    /// use minidom::{Element, NSChoice};
 322    ///
 323    /// let elem = Element::builder("name", "namespace").build();
 324    ///
 325    /// assert_eq!(elem.has_ns("namespace"), true);
 326    /// assert_eq!(elem.has_ns("wrong"), false);
 327    ///
 328    /// assert_eq!(elem.has_ns(NSChoice::OneOf("namespace")), true);
 329    /// assert_eq!(elem.has_ns(NSChoice::OneOf("foo")), false);
 330    /// assert_eq!(elem.has_ns(NSChoice::AnyOf(&["foo", "namespace"])), true);
 331    /// assert_eq!(elem.has_ns(NSChoice::Any), true);
 332    /// ```
 333    pub fn has_ns<'a, NS: Into<NSChoice<'a>>>(&self, namespace: NS) -> bool {
 334        namespace.into().compare(self.namespace.as_ref())
 335    }
 336
 337    /// Parse a document from a `BufRead`.
 338    pub fn from_reader<R: BufRead>(reader: R) -> Result<Element> {
 339        let mut tree_builder = TreeBuilder::new();
 340        let mut driver = PullDriver::wrap(reader, Lexer::new(), RawParser::new());
 341        while let Some(event) = driver.read()? {
 342            tree_builder.process_event(event)?;
 343
 344            if let Some(root) = tree_builder.root.take() {
 345                return Ok(root);
 346            }
 347        }
 348        Err(Error::EndOfDocument)
 349    }
 350
 351    /// Parse a document from a `BufRead`, allowing Prefixes to be specified. Useful to provide
 352    /// knowledge of namespaces that would have been declared on parent elements not present in the
 353    /// reader.
 354    pub fn from_reader_with_prefixes<R: BufRead, P: Into<Prefixes>>(
 355        reader: R,
 356        prefixes: P,
 357    ) -> Result<Element> {
 358        let mut tree_builder = TreeBuilder::new().with_prefixes_stack(vec![prefixes.into()]);
 359        let mut driver = PullDriver::wrap(reader, Lexer::new(), RawParser::new());
 360        while let Some(event) = driver.read()? {
 361            tree_builder.process_event(event)?;
 362
 363            if let Some(root) = tree_builder.root.take() {
 364                return Ok(root);
 365            }
 366        }
 367        Err(Error::EndOfDocument)
 368    }
 369
 370    /// Output a document to a `Writer`.
 371    pub fn write_to<W: Write>(&self, writer: &mut W) -> Result<()> {
 372        self.to_writer(&mut ItemWriter::new(writer))
 373    }
 374
 375    /// Output a document to a `Writer`.
 376    pub fn write_to_decl<W: Write>(&self, writer: &mut W) -> Result<()> {
 377        self.to_writer_decl(&mut ItemWriter::new(writer))
 378    }
 379
 380    /// Output the document to an `ItemWriter`
 381    pub fn to_writer<W: Write>(&self, writer: &mut ItemWriter<W>) -> Result<()> {
 382        self.write_to_inner(writer)
 383    }
 384
 385    /// Output the document to an `ItemWriter`
 386    pub fn to_writer_decl<W: Write>(&self, writer: &mut ItemWriter<W>) -> Result<()> {
 387        writer
 388            .write(Item::XmlDeclaration(XmlVersion::V1_0))
 389            .unwrap(); // TODO: error return
 390        self.write_to_inner(writer)
 391    }
 392
 393    /// Like `write_to()` but without the `<?xml?>` prelude
 394    pub fn write_to_inner<W: Write>(&self, writer: &mut ItemWriter<W>) -> Result<()> {
 395        for (prefix, namespace) in self.prefixes.declared_prefixes() {
 396            assert!(writer.encoder.inner_mut().declare_fixed(
 397                prefix.as_ref().map(|x| (&**x).try_into()).transpose()?,
 398                Some(Arc::new(namespace.clone().try_into()?))
 399            ));
 400        }
 401
 402        let namespace = if self.namespace.is_empty() {
 403            None
 404        } else {
 405            Some(Arc::new(self.namespace.clone().try_into()?))
 406        };
 407        writer.write(Item::ElementHeadStart(namespace, (*self.name).try_into()?))?;
 408
 409        for (key, value) in self.attributes.iter() {
 410            let (prefix, name) = <&rxml::NameStr>::try_from(&**key)
 411                .unwrap()
 412                .split_name()
 413                .unwrap();
 414            let namespace = match prefix {
 415                Some(prefix) => match writer.encoder.inner().lookup_prefix(Some(prefix)) {
 416                    Ok(v) => Some(v),
 417                    Err(rxml::writer::PrefixError::Undeclared) => return Err(Error::InvalidPrefix),
 418                },
 419                None => None,
 420            };
 421            writer.write(Item::Attribute(namespace, name, (&**value).try_into()?))?;
 422        }
 423
 424        if !self.children.is_empty() {
 425            writer.write(Item::ElementHeadEnd)?;
 426            for child in self.children.iter() {
 427                child.write_to_inner(writer)?;
 428            }
 429        }
 430        writer.write(Item::ElementFoot)?;
 431
 432        Ok(())
 433    }
 434
 435    /// Returns an iterator over references to every child node of this element.
 436    ///
 437    /// # Examples
 438    ///
 439    /// ```rust
 440    /// use minidom::Element;
 441    ///
 442    /// let elem: Element = "<root xmlns=\"ns1\">a<c1 />b<c2 />c</root>".parse().unwrap();
 443    ///
 444    /// let mut iter = elem.nodes();
 445    ///
 446    /// assert_eq!(iter.next().unwrap().as_text().unwrap(), "a");
 447    /// assert_eq!(iter.next().unwrap().as_element().unwrap().name(), "c1");
 448    /// assert_eq!(iter.next().unwrap().as_text().unwrap(), "b");
 449    /// assert_eq!(iter.next().unwrap().as_element().unwrap().name(), "c2");
 450    /// assert_eq!(iter.next().unwrap().as_text().unwrap(), "c");
 451    /// assert_eq!(iter.next(), None);
 452    /// ```
 453    #[inline]
 454    pub fn nodes(&self) -> Nodes {
 455        self.children.iter()
 456    }
 457
 458    /// Returns an iterator over mutable references to every child node of this element.
 459    #[inline]
 460    pub fn nodes_mut(&mut self) -> NodesMut {
 461        self.children.iter_mut()
 462    }
 463
 464    /// Returns an iterator over references to every child element of this element.
 465    ///
 466    /// # Examples
 467    ///
 468    /// ```rust
 469    /// use minidom::Element;
 470    ///
 471    /// let elem: Element = "<root xmlns=\"ns1\">hello<child1 xmlns=\"ns1\"/>this<child2 xmlns=\"ns1\"/>is<child3 xmlns=\"ns1\"/>ignored</root>".parse().unwrap();
 472    ///
 473    /// let mut iter = elem.children();
 474    /// assert_eq!(iter.next().unwrap().name(), "child1");
 475    /// assert_eq!(iter.next().unwrap().name(), "child2");
 476    /// assert_eq!(iter.next().unwrap().name(), "child3");
 477    /// assert_eq!(iter.next(), None);
 478    /// ```
 479    #[inline]
 480    pub fn children(&self) -> Children {
 481        Children {
 482            iter: self.children.iter(),
 483        }
 484    }
 485
 486    /// Returns an iterator over mutable references to every child element of this element.
 487    #[inline]
 488    pub fn children_mut(&mut self) -> ChildrenMut {
 489        ChildrenMut {
 490            iter: self.children.iter_mut(),
 491        }
 492    }
 493
 494    /// Returns an iterator over the child Elements, draining the element of
 495    /// all its child nodes **including text!**
 496    ///
 497    /// This is a bit of a footgun, so we make this hidden in the docs (it
 498    /// needs to be pub for macro use). Once `extract_if`
 499    /// ([rust#43244](https://github.com/rust-lang/rust/issues/43244))
 500    /// is stabilized, we can replace this with a take_children which doesn't
 501    /// remove text nodes.
 502    #[inline]
 503    #[doc(hidden)]
 504    pub fn take_contents_as_children(&mut self) -> ContentsAsChildren {
 505        ContentsAsChildren {
 506            iter: self.children.drain(..),
 507        }
 508    }
 509
 510    /// Returns an iterator over references to every text node of this element.
 511    ///
 512    /// # Examples
 513    ///
 514    /// ```rust
 515    /// use minidom::Element;
 516    ///
 517    /// let elem: Element = "<root xmlns=\"ns1\">hello<c /> world!</root>".parse().unwrap();
 518    ///
 519    /// let mut iter = elem.texts();
 520    /// assert_eq!(iter.next().unwrap(), "hello");
 521    /// assert_eq!(iter.next().unwrap(), " world!");
 522    /// assert_eq!(iter.next(), None);
 523    /// ```
 524    #[inline]
 525    pub fn texts(&self) -> Texts {
 526        Texts {
 527            iter: self.children.iter(),
 528        }
 529    }
 530
 531    /// Returns an iterator over mutable references to every text node of this element.
 532    #[inline]
 533    pub fn texts_mut(&mut self) -> TextsMut {
 534        TextsMut {
 535            iter: self.children.iter_mut(),
 536        }
 537    }
 538
 539    /// Appends a child node to the `Element`, returning the appended node.
 540    ///
 541    /// # Examples
 542    ///
 543    /// ```rust
 544    /// use minidom::Element;
 545    ///
 546    /// let mut elem = Element::bare("root", "ns1");
 547    ///
 548    /// assert_eq!(elem.children().count(), 0);
 549    ///
 550    /// elem.append_child(Element::bare("child", "ns1"));
 551    ///
 552    /// {
 553    ///     let mut iter = elem.children();
 554    ///     assert_eq!(iter.next().unwrap().name(), "child");
 555    ///     assert_eq!(iter.next(), None);
 556    /// }
 557    ///
 558    /// let child = elem.append_child(Element::bare("new", "ns1"));
 559    ///
 560    /// assert_eq!(child.name(), "new");
 561    /// ```
 562    pub fn append_child(&mut self, child: Element) -> &mut Element {
 563        self.children.push(Node::Element(child));
 564        if let Node::Element(ref mut cld) = *self.children.last_mut().unwrap() {
 565            cld
 566        } else {
 567            unreachable!()
 568        }
 569    }
 570
 571    /// Appends a text node to an `Element`.
 572    ///
 573    /// # Examples
 574    ///
 575    /// ```rust
 576    /// use minidom::Element;
 577    ///
 578    /// let mut elem = Element::bare("node", "ns1");
 579    ///
 580    /// assert_eq!(elem.text(), "");
 581    ///
 582    /// elem.append_text_node("text");
 583    ///
 584    /// assert_eq!(elem.text(), "text");
 585    /// ```
 586    pub fn append_text_node<S: Into<String>>(&mut self, child: S) {
 587        self.children.push(Node::Text(child.into()));
 588    }
 589
 590    /// Appends a node to an `Element`.
 591    ///
 592    /// # Examples
 593    ///
 594    /// ```rust
 595    /// use minidom::{Element, Node};
 596    ///
 597    /// let mut elem = Element::bare("node", "ns1");
 598    ///
 599    /// elem.append_node(Node::Text("hello".to_owned()));
 600    ///
 601    /// assert_eq!(elem.text(), "hello");
 602    /// ```
 603    pub fn append_node(&mut self, node: Node) {
 604        self.children.push(node);
 605    }
 606
 607    /// Returns the concatenation of all text nodes in the `Element`.
 608    ///
 609    /// # Examples
 610    ///
 611    /// ```rust
 612    /// use minidom::Element;
 613    ///
 614    /// let elem: Element = "<node xmlns=\"ns1\">hello,<split /> world!</node>".parse().unwrap();
 615    ///
 616    /// assert_eq!(elem.text(), "hello, world!");
 617    /// ```
 618    pub fn text(&self) -> String {
 619        self.texts().fold(String::new(), |ret, new| ret + new)
 620    }
 621
 622    /// Returns a reference to the first child element with the specific name and namespace, if it
 623    /// exists in the direct descendants of this `Element`, else returns `None`.
 624    ///
 625    /// # Examples
 626    ///
 627    /// ```rust
 628    /// use minidom::{Element, NSChoice};
 629    ///
 630    /// let elem: Element = r#"<node xmlns="ns"><a/><a xmlns="other_ns" /><b/></node>"#.parse().unwrap();
 631    /// assert!(elem.get_child("a", "ns").unwrap().is("a", "ns"));
 632    /// assert!(elem.get_child("a", "other_ns").unwrap().is("a", "other_ns"));
 633    /// assert!(elem.get_child("b", "ns").unwrap().is("b", "ns"));
 634    /// assert_eq!(elem.get_child("c", "ns"), None);
 635    /// assert_eq!(elem.get_child("b", "other_ns"), None);
 636    /// assert_eq!(elem.get_child("a", "inexistent_ns"), None);
 637    /// ```
 638    pub fn get_child<'a, N: AsRef<str>, NS: Into<NSChoice<'a>>>(
 639        &self,
 640        name: N,
 641        namespace: NS,
 642    ) -> Option<&Element> {
 643        let namespace = namespace.into();
 644        for fork in &self.children {
 645            if let Node::Element(ref e) = *fork {
 646                if e.is(name.as_ref(), namespace) {
 647                    return Some(e);
 648                }
 649            }
 650        }
 651        None
 652    }
 653
 654    /// Returns a mutable reference to the first child element with the specific name and namespace,
 655    /// if it exists in the direct descendants of this `Element`, else returns `None`.
 656    pub fn get_child_mut<'a, N: AsRef<str>, NS: Into<NSChoice<'a>>>(
 657        &mut self,
 658        name: N,
 659        namespace: NS,
 660    ) -> Option<&mut Element> {
 661        let namespace = namespace.into();
 662        for fork in &mut self.children {
 663            if let Node::Element(ref mut e) = *fork {
 664                if e.is(name.as_ref(), namespace) {
 665                    return Some(e);
 666                }
 667            }
 668        }
 669        None
 670    }
 671
 672    /// Returns whether a specific child with this name and namespace exists in the direct
 673    /// descendants of the `Element`.
 674    ///
 675    /// # Examples
 676    ///
 677    /// ```rust
 678    /// use minidom::{Element, NSChoice};
 679    ///
 680    /// let elem: Element = r#"<node xmlns="ns"><a /><a xmlns="other_ns" /><b /></node>"#.parse().unwrap();
 681    /// assert_eq!(elem.has_child("a", "other_ns"), true);
 682    /// assert_eq!(elem.has_child("a", "ns"), true);
 683    /// assert_eq!(elem.has_child("a", "inexistent_ns"), false);
 684    /// assert_eq!(elem.has_child("b", "ns"), true);
 685    /// assert_eq!(elem.has_child("b", "other_ns"), false);
 686    /// assert_eq!(elem.has_child("b", "inexistent_ns"), false);
 687    /// ```
 688    pub fn has_child<'a, N: AsRef<str>, NS: Into<NSChoice<'a>>>(
 689        &self,
 690        name: N,
 691        namespace: NS,
 692    ) -> bool {
 693        self.get_child(name, namespace).is_some()
 694    }
 695
 696    /// Removes the first child with this name and namespace, if it exists, and returns an
 697    /// `Option<Element>` containing this child if it succeeds.
 698    /// Returns `None` if no child matches this name and namespace.
 699    ///
 700    /// # Examples
 701    ///
 702    /// ```rust
 703    /// use minidom::{Element, NSChoice};
 704    ///
 705    /// let mut elem: Element = r#"<node xmlns="ns"><a /><a xmlns="other_ns" /><b /></node>"#.parse().unwrap();
 706    /// assert!(elem.remove_child("a", "ns").unwrap().is("a", "ns"));
 707    /// assert!(elem.remove_child("a", "ns").is_none());
 708    /// assert!(elem.remove_child("inexistent", "inexistent").is_none());
 709    /// ```
 710    pub fn remove_child<'a, N: AsRef<str>, NS: Into<NSChoice<'a>>>(
 711        &mut self,
 712        name: N,
 713        namespace: NS,
 714    ) -> Option<Element> {
 715        let name = name.as_ref();
 716        let namespace = namespace.into();
 717        let idx = self.children.iter().position(|x| {
 718            if let Node::Element(ref elm) = x {
 719                elm.is(name, namespace)
 720            } else {
 721                false
 722            }
 723        })?;
 724        self.children.remove(idx).into_element()
 725    }
 726
 727    /// Remove the leading nodes up to the first child element and
 728    /// return it
 729    pub fn unshift_child(&mut self) -> Option<Element> {
 730        while !self.children.is_empty() {
 731            if let Some(el) = self.children.remove(0).into_element() {
 732                return Some(el);
 733            }
 734        }
 735
 736        None
 737    }
 738}
 739
 740/// An iterator over references to child elements of an `Element`.
 741pub struct Children<'a> {
 742    iter: slice::Iter<'a, Node>,
 743}
 744
 745impl<'a> Iterator for Children<'a> {
 746    type Item = &'a Element;
 747
 748    fn next(&mut self) -> Option<&'a Element> {
 749        for item in &mut self.iter {
 750            if let Node::Element(ref child) = *item {
 751                return Some(child);
 752            }
 753        }
 754        None
 755    }
 756}
 757
 758/// An iterator over mutable references to child elements of an `Element`.
 759pub struct ChildrenMut<'a> {
 760    iter: slice::IterMut<'a, Node>,
 761}
 762
 763impl<'a> Iterator for ChildrenMut<'a> {
 764    type Item = &'a mut Element;
 765
 766    fn next(&mut self) -> Option<&'a mut Element> {
 767        for item in &mut self.iter {
 768            if let Node::Element(ref mut child) = *item {
 769                return Some(child);
 770            }
 771        }
 772        None
 773    }
 774}
 775
 776/// An iterator over references to child elements of an `Element`.
 777pub struct ContentsAsChildren<'a> {
 778    iter: std::vec::Drain<'a, Node>,
 779}
 780
 781impl<'a> Iterator for ContentsAsChildren<'a> {
 782    type Item = Element;
 783
 784    fn next(&mut self) -> Option<Element> {
 785        for item in &mut self.iter {
 786            if let Node::Element(child) = item {
 787                return Some(child);
 788            }
 789        }
 790        None
 791    }
 792}
 793
 794/// An iterator over references to child text nodes of an `Element`.
 795pub struct Texts<'a> {
 796    iter: slice::Iter<'a, Node>,
 797}
 798
 799impl<'a> Iterator for Texts<'a> {
 800    type Item = &'a str;
 801
 802    fn next(&mut self) -> Option<&'a str> {
 803        for item in &mut self.iter {
 804            if let Node::Text(ref child) = *item {
 805                return Some(child);
 806            }
 807        }
 808        None
 809    }
 810}
 811
 812/// An iterator over mutable references to child text nodes of an `Element`.
 813pub struct TextsMut<'a> {
 814    iter: slice::IterMut<'a, Node>,
 815}
 816
 817impl<'a> Iterator for TextsMut<'a> {
 818    type Item = &'a mut String;
 819
 820    fn next(&mut self) -> Option<&'a mut String> {
 821        for item in &mut self.iter {
 822            if let Node::Text(ref mut child) = *item {
 823                return Some(child);
 824            }
 825        }
 826        None
 827    }
 828}
 829
 830/// An iterator over references to all child nodes of an `Element`.
 831pub type Nodes<'a> = slice::Iter<'a, Node>;
 832
 833/// An iterator over mutable references to all child nodes of an `Element`.
 834pub type NodesMut<'a> = slice::IterMut<'a, Node>;
 835
 836/// An iterator over the attributes of an `Element`.
 837pub struct Attrs<'a> {
 838    iter: btree_map::Iter<'a, String, String>,
 839}
 840
 841impl<'a> Iterator for Attrs<'a> {
 842    type Item = (&'a str, &'a str);
 843
 844    fn next(&mut self) -> Option<Self::Item> {
 845        self.iter.next().map(|(x, y)| (x.as_ref(), y.as_ref()))
 846    }
 847}
 848
 849/// An iterator over the attributes of an `Element`, with the values mutable.
 850pub struct AttrsMut<'a> {
 851    iter: btree_map::IterMut<'a, String, String>,
 852}
 853
 854impl<'a> Iterator for AttrsMut<'a> {
 855    type Item = (&'a str, &'a mut String);
 856
 857    fn next(&mut self) -> Option<Self::Item> {
 858        self.iter.next().map(|(x, y)| (x.as_ref(), y))
 859    }
 860}
 861
 862/// A builder for `Element`s.
 863pub struct ElementBuilder {
 864    root: Element,
 865}
 866
 867impl ElementBuilder {
 868    /// Sets a custom prefix. It is not possible to set the same prefix twice.
 869    pub fn prefix<S: Into<Namespace>>(
 870        mut self,
 871        prefix: Prefix,
 872        namespace: S,
 873    ) -> Result<ElementBuilder> {
 874        if self.root.prefixes.get(&prefix).is_some() {
 875            return Err(Error::DuplicatePrefix);
 876        }
 877        self.root.prefixes.insert(prefix, namespace.into());
 878        Ok(self)
 879    }
 880
 881    /// Sets an attribute.
 882    pub fn attr<S: Into<String>, V: IntoAttributeValue>(
 883        mut self,
 884        name: S,
 885        value: V,
 886    ) -> ElementBuilder {
 887        self.root.set_attr(name, value);
 888        self
 889    }
 890
 891    /// Appends anything implementing `Into<Node>` into the tree.
 892    pub fn append<T: Into<Node>>(mut self, node: T) -> ElementBuilder {
 893        self.root.append_node(node.into());
 894        self
 895    }
 896
 897    /// Appends an iterator of things implementing `Into<Node>` into the tree.
 898    pub fn append_all<T: Into<Node>, I: IntoIterator<Item = T>>(
 899        mut self,
 900        iter: I,
 901    ) -> ElementBuilder {
 902        for node in iter {
 903            self.root.append_node(node.into());
 904        }
 905        self
 906    }
 907
 908    /// Builds the `Element`.
 909    pub fn build(self) -> Element {
 910        self.root
 911    }
 912}
 913
 914#[cfg(test)]
 915mod tests {
 916    use super::*;
 917
 918    #[test]
 919    fn test_element_new() {
 920        let elem = Element::new(
 921            "name".to_owned(),
 922            "namespace".to_owned(),
 923            (None, "namespace".to_owned()),
 924            BTreeMap::from_iter(vec![("name".to_string(), "value".to_string())].into_iter()),
 925            Vec::new(),
 926        );
 927
 928        assert_eq!(elem.name(), "name");
 929        assert_eq!(elem.ns(), "namespace".to_owned());
 930        assert_eq!(elem.attr("name"), Some("value"));
 931        assert_eq!(elem.attr("inexistent"), None);
 932    }
 933
 934    #[test]
 935    fn test_from_reader_simple() {
 936        let xml = b"<foo xmlns='ns1'></foo>";
 937        let elem = Element::from_reader(&xml[..]);
 938
 939        let elem2 = Element::builder("foo", "ns1").build();
 940
 941        assert_eq!(elem.unwrap(), elem2);
 942    }
 943
 944    #[test]
 945    fn test_from_reader_nested() {
 946        let xml = b"<foo xmlns='ns1'><bar xmlns='ns1' baz='qxx' /></foo>";
 947        let elem = Element::from_reader(&xml[..]);
 948
 949        let nested = Element::builder("bar", "ns1").attr("baz", "qxx").build();
 950        let elem2 = Element::builder("foo", "ns1").append(nested).build();
 951
 952        assert_eq!(elem.unwrap(), elem2);
 953    }
 954
 955    #[test]
 956    fn test_from_reader_with_prefix() {
 957        let xml = b"<foo xmlns='ns1'><prefix:bar xmlns:prefix='ns1' baz='qxx' /></foo>";
 958        let elem = Element::from_reader(&xml[..]);
 959
 960        let nested = Element::builder("bar", "ns1").attr("baz", "qxx").build();
 961        let elem2 = Element::builder("foo", "ns1").append(nested).build();
 962
 963        assert_eq!(elem.unwrap(), elem2);
 964    }
 965
 966    #[test]
 967    fn test_from_reader_split_prefix() {
 968        let xml = b"<foo:bar xmlns:foo='ns1'/>";
 969        let elem = Element::from_reader(&xml[..]).unwrap();
 970
 971        assert_eq!(elem.name(), String::from("bar"));
 972        assert_eq!(elem.ns(), String::from("ns1"));
 973        // Ensure the prefix is properly added to the store
 974        assert_eq!(
 975            elem.prefixes.get(&Some(String::from("foo"))),
 976            Some(&String::from("ns1"))
 977        );
 978    }
 979
 980    #[test]
 981    fn parses_spectest_xml() {
 982        // From: https://gitlab.com/lumi/minidom-rs/issues/8
 983        let xml = br#"<rng:grammar xmlns:rng="http://relaxng.org/ns/structure/1.0">
 984                <rng:name xmlns:rng="http://relaxng.org/ns/structure/1.0"></rng:name>
 985            </rng:grammar>
 986        "#;
 987        let _ = Element::from_reader(&xml[..]).unwrap();
 988    }
 989
 990    #[test]
 991    fn does_not_unescape_cdata() {
 992        let xml = b"<test xmlns='test'><![CDATA[&apos;&gt;blah<blah>]]></test>";
 993        let elem = Element::from_reader(&xml[..]).unwrap();
 994        assert_eq!(elem.text(), "&apos;&gt;blah<blah>");
 995    }
 996
 997    #[test]
 998    fn test_compare_all_ns() {
 999        let xml = b"<foo xmlns='foo' xmlns:bar='baz'><bar:meh xmlns:bar='baz' /></foo>";
1000        let elem = Element::from_reader(&xml[..]).unwrap();
1001
1002        let elem2 = elem.clone();
1003
1004        let xml3 = b"<foo xmlns='foo'><bar:meh xmlns:bar='baz'/></foo>";
1005        let elem3 = Element::from_reader(&xml3[..]).unwrap();
1006
1007        let xml4 = b"<prefix:foo xmlns:prefix='foo'><bar:meh xmlns:bar='baz'/></prefix:foo>";
1008        let elem4 = Element::from_reader(&xml4[..]).unwrap();
1009
1010        assert_eq!(elem, elem2);
1011        assert_eq!(elem, elem3);
1012        assert_eq!(elem, elem4);
1013    }
1014
1015    #[test]
1016    fn test_compare_empty_children() {
1017        let elem1 = Element::bare("p", "");
1018        let elem2 = Element::builder("p", "")
1019            .append(Node::Element(Element::bare("span", "")))
1020            .build();
1021
1022        assert_ne!(elem1, elem2);
1023    }
1024
1025    #[test]
1026    fn test_from_reader_with_prefixes() {
1027        let xml = b"<foo><bar xmlns='baz'/></foo>";
1028        let elem =
1029            Element::from_reader_with_prefixes(&xml[..], String::from("jabber:client")).unwrap();
1030
1031        let xml2 = b"<foo xmlns='jabber:client'><bar xmlns='baz'/></foo>";
1032        let elem2 = Element::from_reader(&xml2[..]).unwrap();
1033
1034        assert_eq!(elem, elem2);
1035    }
1036
1037    #[test]
1038    fn failure_with_duplicate_namespace() {
1039        let _: Element = r###"<?xml version="1.0" encoding="UTF-8"?>
1040            <wsdl:definitions
1041                    xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
1042                    xmlns:xsd="http://www.w3.org/2001/XMLSchema">
1043                <wsdl:types>
1044                    <xsd:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
1045                    </xsd:schema>
1046                </wsdl:types>
1047            </wsdl:definitions>
1048        "###
1049        .parse()
1050        .unwrap();
1051    }
1052}