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