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