roxmltree/
lib.rs

1/*!
2Represent an [XML](https://www.w3.org/TR/xml/) document as a read-only tree.
3
4The root point of the documentations is [`Document::parse`].
5
6You can find more details in the [README] and the [parsing doc].
7
8The tree structure itself is a heavily modified <https://github.com/causal-agent/ego-tree>
9License: ISC.
10
11[`Document::parse`]: struct.Document.html#method.parse
12[README]: https://github.com/RazrFalcon/roxmltree/blob/master/README.md
13[parsing doc]: https://github.com/RazrFalcon/roxmltree/blob/master/docs/parsing.md
14*/
15
16#![no_std]
17#![forbid(unsafe_code)]
18#![warn(missing_docs)]
19#![warn(missing_copy_implementations)]
20#![warn(missing_debug_implementations)]
21
22extern crate alloc;
23
24#[cfg(feature = "std")]
25extern crate std;
26
27use core::cmp::Ordering;
28use core::fmt;
29use core::hash::{Hash, Hasher};
30use core::num::NonZeroU32;
31use core::ops::Range;
32
33use alloc::vec::Vec;
34
35mod parse;
36mod tokenizer;
37
38#[cfg(test)]
39mod tokenizer_tests;
40
41pub use crate::parse::*;
42
43/// The <http://www.w3.org/XML/1998/namespace> URI.
44pub const NS_XML_URI: &str = "http://www.w3.org/XML/1998/namespace";
45/// The prefix 'xml', which is by definition bound to NS_XML_URI
46const NS_XML_PREFIX: &str = "xml";
47
48/// The <http://www.w3.org/2000/xmlns/> URI.
49pub const NS_XMLNS_URI: &str = "http://www.w3.org/2000/xmlns/";
50/// The string 'xmlns', which is used to declare new namespaces
51const XMLNS: &str = "xmlns";
52
53/// Position in text.
54///
55/// Position indicates a row/line and a column in the original text. Starting from 1:1.
56#[allow(missing_docs)]
57#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
58pub struct TextPos {
59    pub row: u32,
60    pub col: u32,
61}
62
63impl TextPos {
64    /// Constructs a new `TextPos`.
65    pub fn new(row: u32, col: u32) -> TextPos {
66        TextPos { row, col }
67    }
68}
69
70impl fmt::Display for TextPos {
71    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
72        write!(f, "{}:{}", self.row, self.col)
73    }
74}
75
76/// An XML tree container.
77///
78/// A tree consists of [`Nodes`].
79/// There are no separate structs for each node type.
80/// So you should check the current node type yourself via [`Node::node_type()`].
81/// There are only [5 types](enum.NodeType.html):
82/// Root, Element, PI, Comment and Text.
83///
84/// As you can see there are no XML declaration and CDATA types.
85/// The XML declaration is basically skipped, since it doesn't contain any
86/// valuable information (we support only UTF-8 anyway).
87/// And CDATA will be converted into a Text node as is, without
88/// any preprocessing (you can read more about it
89/// [here](https://github.com/RazrFalcon/roxmltree/blob/master/docs/parsing.md)).
90///
91/// Also, the Text node data can be accessed from the text node itself or from
92/// the parent element via [`Node::text()`] or [`Node::tail()`].
93///
94/// [`Nodes`]: struct.Node.html
95/// [`Node::node_type()`]: struct.Node.html#method.node_type
96/// [`Node::text()`]: struct.Node.html#method.text
97/// [`Node::tail()`]: struct.Node.html#method.tail
98pub struct Document<'input> {
99    /// An original data.
100    ///
101    /// Required for `text_pos_at` methods.
102    text: &'input str,
103    nodes: Vec<NodeData<'input>>,
104    attributes: Vec<AttributeData<'input>>,
105    namespaces: Namespaces<'input>,
106}
107
108impl<'input> Document<'input> {
109    /// Returns the root node.
110    ///
111    /// # Examples
112    ///
113    /// ```
114    /// let doc = roxmltree::Document::parse("<e/>").unwrap();
115    /// assert!(doc.root().is_root());
116    /// assert!(doc.root().first_child().unwrap().has_tag_name("e"));
117    /// ```
118    #[inline]
119    pub fn root<'a>(&'a self) -> Node<'a, 'input> {
120        Node {
121            id: NodeId::new(0),
122            d: &self.nodes[0],
123            doc: self,
124        }
125    }
126
127    /// Returns the node of the tree with the given NodeId.
128    ///
129    /// Note: NodeId::new(0) represents the root node
130    ///
131    /// # Examples
132    ///
133    /// ```
134    /// let doc = roxmltree::Document::parse("\
135    /// <p>
136    ///     text
137    /// </p>
138    /// ").unwrap();
139    ///
140    /// use roxmltree::NodeId;
141    /// assert_eq!(doc.get_node(NodeId::new(0)).unwrap(), doc.root());
142    /// assert_eq!(doc.get_node(NodeId::new(1)), doc.descendants().find(|n| n.has_tag_name("p")));
143    /// assert_eq!(doc.get_node(NodeId::new(2)), doc.descendants().find(|n| n.is_text()));
144    /// assert_eq!(doc.get_node(NodeId::new(3)), None);
145    /// ```
146    #[inline]
147    pub fn get_node<'a>(&'a self, id: NodeId) -> Option<Node<'a, 'input>> {
148        self.nodes.get(id.get_usize()).map(|data| Node {
149            id,
150            d: data,
151            doc: self,
152        })
153    }
154
155    /// Returns the root element of the document.
156    ///
157    /// Unlike `root`, will return a first element node.
158    ///
159    /// The root element always exists.
160    ///
161    /// # Examples
162    ///
163    /// ```
164    /// let doc = roxmltree::Document::parse("<!-- comment --><e/>").unwrap();
165    /// assert!(doc.root_element().has_tag_name("e"));
166    /// ```
167    #[inline]
168    pub fn root_element<'a>(&'a self) -> Node<'a, 'input> {
169        // `expect` is safe, because the `Document` is guarantee to have at least one element.
170        self.root()
171            .first_element_child()
172            .expect("XML documents must contain a root element")
173    }
174
175    /// Returns an iterator over document's descendant nodes.
176    ///
177    /// Shorthand for `doc.root().descendants()`.
178    #[inline]
179    pub fn descendants(&self) -> Descendants<'_, 'input> {
180        self.root().descendants()
181    }
182
183    /// Calculates `TextPos` in the original document from position in bytes.
184    ///
185    /// **Note:** this operation is expensive.
186    ///
187    /// # Examples
188    ///
189    /// ```
190    /// use roxmltree::*;
191    ///
192    /// let doc = Document::parse("\
193    /// <!-- comment -->
194    /// <e/>"
195    /// ).unwrap();
196    ///
197    /// assert_eq!(doc.text_pos_at(10), TextPos::new(1, 11));
198    /// assert_eq!(doc.text_pos_at(9999), TextPos::new(2, 5));
199    /// ```
200    #[inline]
201    pub fn text_pos_at(&self, pos: usize) -> TextPos {
202        tokenizer::Stream::new(self.text).gen_text_pos_from(pos)
203    }
204
205    /// Returns the input text of the original document.
206    ///
207    /// # Examples
208    ///
209    /// ```
210    /// use roxmltree::*;
211    ///
212    /// let doc = Document::parse("<e/>").unwrap();
213    ///
214    /// assert_eq!(doc.input_text(), "<e/>");
215    /// ```
216    #[inline]
217    pub fn input_text(&self) -> &'input str {
218        self.text
219    }
220}
221
222impl<'input> fmt::Debug for Document<'input> {
223    fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
224        if !self.root().has_children() {
225            return write!(f, "Document []");
226        }
227
228        macro_rules! writeln_indented {
229            ($depth:expr, $f:expr, $fmt:expr) => {
230                for _ in 0..$depth { write!($f, "    ")?; }
231                writeln!($f, $fmt)?;
232            };
233            ($depth:expr, $f:expr, $fmt:expr, $($arg:tt)*) => {
234                for _ in 0..$depth { write!($f, "    ")?; }
235                writeln!($f, $fmt, $($arg)*)?;
236            };
237        }
238
239        fn print_into_iter<
240            T: fmt::Debug,
241            E: ExactSizeIterator<Item = T>,
242            I: IntoIterator<Item = T, IntoIter = E>,
243        >(
244            prefix: &str,
245            data: I,
246            depth: usize,
247            f: &mut fmt::Formatter,
248        ) -> Result<(), fmt::Error> {
249            let data = data.into_iter();
250            if data.len() == 0 {
251                return Ok(());
252            }
253
254            writeln_indented!(depth, f, "{}: [", prefix);
255            for v in data {
256                writeln_indented!(depth + 1, f, "{:?}", v);
257            }
258            writeln_indented!(depth, f, "]");
259
260            Ok(())
261        }
262
263        fn print_children(
264            parent: Node,
265            depth: usize,
266            f: &mut fmt::Formatter,
267        ) -> Result<(), fmt::Error> {
268            for child in parent.children() {
269                if child.is_element() {
270                    writeln_indented!(depth, f, "Element {{");
271                    writeln_indented!(depth, f, "    tag_name: {:?}", child.tag_name());
272                    print_into_iter("attributes", child.attributes(), depth + 1, f)?;
273                    print_into_iter("namespaces", child.namespaces(), depth + 1, f)?;
274
275                    if child.has_children() {
276                        writeln_indented!(depth, f, "    children: [");
277                        print_children(child, depth + 2, f)?;
278                        writeln_indented!(depth, f, "    ]");
279                    }
280
281                    writeln_indented!(depth, f, "}}");
282                } else {
283                    writeln_indented!(depth, f, "{:?}", child);
284                }
285            }
286
287            Ok(())
288        }
289
290        writeln!(f, "Document [")?;
291        print_children(self.root(), 1, f)?;
292        writeln!(f, "]")?;
293
294        Ok(())
295    }
296}
297
298/// A list of supported node types.
299#[derive(Clone, Copy, PartialEq, Eq, Debug)]
300pub enum NodeType {
301    /// The root node of the `Document`.
302    Root,
303    /// An element node.
304    ///
305    /// Only an element can have a tag name and attributes.
306    Element,
307    /// A processing instruction.
308    PI,
309    /// A comment node.
310    Comment,
311    /// A text node.
312    Text,
313}
314
315/// A processing instruction.
316#[derive(Clone, Copy, PartialEq, Eq, Debug)]
317#[allow(missing_docs)]
318pub struct PI<'input> {
319    pub target: &'input str,
320    pub value: Option<&'input str>,
321}
322
323/// A short range.
324///
325/// Just like Range, but only for `u32` and copyable.
326#[derive(Clone, Copy, Debug)]
327struct ShortRange {
328    start: u32,
329    end: u32,
330}
331
332impl From<Range<usize>> for ShortRange {
333    #[inline]
334    fn from(range: Range<usize>) -> Self {
335        debug_assert!(range.start <= core::u32::MAX as usize);
336        debug_assert!(range.end <= core::u32::MAX as usize);
337        ShortRange::new(range.start as u32, range.end as u32)
338    }
339}
340
341impl ShortRange {
342    #[inline]
343    fn new(start: u32, end: u32) -> Self {
344        ShortRange { start, end }
345    }
346
347    #[inline]
348    fn to_urange(self) -> Range<usize> {
349        self.start as usize..self.end as usize
350    }
351}
352
353/// A node ID stored as `u32`.
354///
355/// An index into a `Tree`-internal `Vec`.
356///
357/// Note that this value should be used with care since `roxmltree` doesn't
358/// check that `NodeId` actually belongs to a selected `Document`.
359/// So you can end up in a situation, when `NodeId` produced by one `Document`
360/// is used to select a node in another `Document`.
361#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
362pub struct NodeId(NonZeroU32);
363
364impl NodeId {
365    /// Construct a new `NodeId` from a `u32`.
366    #[inline]
367    pub fn new(id: u32) -> Self {
368        debug_assert!(id < core::u32::MAX);
369
370        // We are using `NonZeroU32` to reduce overhead of `Option<NodeId>`.
371        NodeId(NonZeroU32::new(id + 1).unwrap())
372    }
373
374    /// Returns the `u32` representation of the `NodeId`.
375    #[inline]
376    pub fn get(self) -> u32 {
377        self.0.get() - 1
378    }
379
380    /// Returns the `usize` representation of the `NodeId`.
381    #[inline]
382    pub fn get_usize(self) -> usize {
383        self.get() as usize
384    }
385}
386
387impl From<u32> for NodeId {
388    #[inline]
389    fn from(id: u32) -> Self {
390        NodeId::new(id)
391    }
392}
393
394impl From<usize> for NodeId {
395    #[inline]
396    fn from(id: usize) -> Self {
397        // We already checked that `id` is limited by u32::MAX.
398        debug_assert!(id <= core::u32::MAX as usize);
399        NodeId::new(id as u32)
400    }
401}
402
403#[derive(Debug)]
404enum NodeKind<'input> {
405    Root,
406    Element {
407        tag_name: ExpandedNameIndexed<'input>,
408        attributes: ShortRange,
409        namespaces: ShortRange,
410    },
411    PI(PI<'input>),
412    Comment(StringStorage<'input>),
413    Text(StringStorage<'input>),
414}
415
416#[derive(Debug)]
417struct NodeData<'input> {
418    parent: Option<NodeId>,
419    prev_sibling: Option<NodeId>,
420    next_subtree: Option<NodeId>,
421    last_child: Option<NodeId>,
422    kind: NodeKind<'input>,
423    #[cfg(feature = "positions")]
424    range: Range<usize>,
425}
426
427#[cfg(target_has_atomic = "ptr")]
428type OwnedSharedString = alloc::sync::Arc<str>;
429
430#[cfg(not(target_has_atomic = "ptr"))]
431type OwnedSharedString = alloc::rc::Rc<str>;
432
433/// A string storage.
434///
435/// Used by text nodes and attributes values.
436///
437/// We try our best not to allocate strings, referencing the input string as much as possible.
438/// But in some cases post-processing is necessary and we have to allocate them.
439///
440/// All owned, allocated strings are stored as `Arc<str>` or as `Rc<str>` on targets
441/// were `Arc` isn't available.
442/// And unlike `Cow<&str>`, `StringStorage` is immutable and can be cheaply cloned.
443#[derive(Clone, Eq, Debug)]
444pub enum StringStorage<'input> {
445    /// A raw slice of the input string.
446    Borrowed(&'input str),
447
448    /// A reference-counted string.
449    Owned(OwnedSharedString),
450}
451
452impl StringStorage<'_> {
453    /// Creates a new owned string from `&str` or `String`.
454    pub fn new_owned<T: Into<OwnedSharedString>>(s: T) -> Self {
455        StringStorage::Owned(s.into())
456    }
457
458    /// Returns a string slice.
459    pub fn as_str(&self) -> &str {
460        match self {
461            StringStorage::Borrowed(s) => s,
462            StringStorage::Owned(s) => s,
463        }
464    }
465}
466
467impl PartialEq for StringStorage<'_> {
468    fn eq(&self, other: &Self) -> bool {
469        self.as_str() == other.as_str()
470    }
471}
472
473impl core::fmt::Display for StringStorage<'_> {
474    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
475        write!(f, "{}", self.as_str())
476    }
477}
478
479impl core::ops::Deref for StringStorage<'_> {
480    type Target = str;
481
482    fn deref(&self) -> &Self::Target {
483        self.as_str()
484    }
485}
486
487#[derive(Clone, Debug)]
488struct AttributeData<'input> {
489    name: ExpandedNameIndexed<'input>,
490    value: StringStorage<'input>,
491    #[cfg(feature = "positions")]
492    range: Range<usize>,
493    #[cfg(feature = "positions")]
494    qname_len: u16,
495    #[cfg(feature = "positions")]
496    eq_len: u8, // includes any surrounding spaces
497}
498
499/// An attribute.
500#[derive(Copy, Clone)]
501pub struct Attribute<'a, 'input: 'a> {
502    doc: &'a Document<'input>,
503    data: &'a AttributeData<'input>,
504}
505
506impl<'a, 'input> Attribute<'a, 'input> {
507    /// Returns attribute's namespace URI.
508    ///
509    /// # Examples
510    ///
511    /// ```
512    /// let doc = roxmltree::Document::parse(
513    ///     "<e xmlns:n='http://www.w3.org' a='b' n:a='c'/>"
514    /// ).unwrap();
515    ///
516    /// assert_eq!(doc.root_element().attributes().nth(0).unwrap().namespace(), None);
517    /// assert_eq!(doc.root_element().attributes().nth(1).unwrap().namespace(), Some("http://www.w3.org"));
518    /// ```
519    #[inline]
520    pub fn namespace(&self) -> Option<&'a str> {
521        self.data.name.namespace(self.doc).map(Namespace::uri)
522    }
523
524    /// Returns attribute's name.
525    ///
526    /// # Examples
527    ///
528    /// ```
529    /// let doc = roxmltree::Document::parse(
530    ///     "<e xmlns:n='http://www.w3.org' a='b' n:a='c'/>"
531    /// ).unwrap();
532    ///
533    /// assert_eq!(doc.root_element().attributes().nth(0).unwrap().name(), "a");
534    /// assert_eq!(doc.root_element().attributes().nth(1).unwrap().name(), "a");
535    /// ```
536    #[inline]
537    pub fn name(&self) -> &'input str {
538        self.data.name.local_name
539    }
540
541    /// Returns attribute's value.
542    ///
543    /// # Examples
544    ///
545    /// ```
546    /// let doc = roxmltree::Document::parse(
547    ///     "<e xmlns:n='http://www.w3.org' a='b' n:a='c'/>"
548    /// ).unwrap();
549    ///
550    /// assert_eq!(doc.root_element().attributes().nth(0).unwrap().value(), "b");
551    /// assert_eq!(doc.root_element().attributes().nth(1).unwrap().value(), "c");
552    /// ```
553    #[inline]
554    pub fn value(&self) -> &'a str {
555        &self.data.value
556    }
557
558    /// Returns attribute's value storage.
559    ///
560    /// Useful when you need a more low-level access to an allocated string.
561    #[inline]
562    pub fn value_storage(&self) -> &StringStorage<'input> {
563        &self.data.value
564    }
565
566    /// Returns attribute's position in bytes in the original document.
567    ///
568    /// You can calculate a human-readable text position via [Document::text_pos_at].
569    ///
570    /// ```text
571    /// <e attr='value'/>
572    ///    ^
573    /// ```
574    ///
575    /// [Document::text_pos_at]: struct.Document.html#method.text_pos_at
576    #[deprecated(note="replaced by `range`")]
577    #[cfg(feature = "positions")]
578    #[inline]
579    pub fn position(&self) -> usize {
580        self.data.range.start
581    }
582
583    /// Returns attribute's range in bytes in the original document.
584    ///
585    /// ```text
586    /// <e n:attr='value'/>
587    ///    ^^^^^^^^^^^^^^
588    /// ```
589    #[cfg(feature = "positions")]
590    #[inline]
591    pub fn range(&self) -> Range<usize> {
592        self.data.range.clone()
593    }
594
595    /// Returns attribute's qname's range in bytes in the original document.
596    ///
597    /// ```text
598    /// <e n:attr='value'/>
599    ///    ^^^^^^
600    /// ```
601    ///
602    /// To reduce memory usage the qname length is limited by u16::MAX.
603    /// If the attribute exceeds that limit then the end of the returned range will be incorrect.
604    #[cfg(feature = "positions")]
605    #[inline]
606    pub fn range_qname(&self) -> Range<usize> {
607        let end = self.data.range.start + usize::from(self.data.qname_len);
608        self.data.range.start..end
609    }
610
611    /// Returns attribute's value's range in bytes in the original document, excluding the surrounding quotes.
612    ///
613    /// If the attribute's value is an empty string then the `start` and `end` of this `Range` are equal, and indicate the closing quote.
614    ///
615    /// ```text
616    /// <e n:attr='value'/>
617    ///            ^^^^^
618    /// ```
619    ///
620    /// To reduce memory usage the qname length is limited by u16::MAX,
621    /// and the number of spaces around the equal sign is limited by u8::MAX.
622    /// If the attribute exceeds those limits then the start of the returned range will be incorrect.
623    #[cfg(feature = "positions")]
624    #[inline]
625    pub fn range_value(&self) -> Range<usize> {
626        // +1 on start and -1 on end are to exclude the quotes around the value (all valid quotes are 1 byte)
627        let start = self.data.range.start + usize::from(self.data.qname_len) + usize::from(self.data.eq_len) + 1;
628        let end = self.data.range.end - 1;
629        start..end
630    }
631}
632
633impl PartialEq for Attribute<'_, '_> {
634    #[inline]
635    fn eq(&self, other: &Attribute<'_, '_>) -> bool {
636        self.data.name.as_expanded_name(self.doc) == other.data.name.as_expanded_name(other.doc)
637            && self.data.value == other.data.value
638    }
639}
640
641impl fmt::Debug for Attribute<'_, '_> {
642    fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
643        write!(
644            f,
645            "Attribute {{ name: {:?}, value: {:?} }}",
646            self.data.name.as_expanded_name(self.doc),
647            self.data.value
648        )
649    }
650}
651
652/// A namespace.
653///
654/// Contains URI and *prefix* pair.
655#[derive(Clone, PartialEq, Eq, Debug)]
656pub struct Namespace<'input> {
657    name: Option<&'input str>,
658    uri: StringStorage<'input>,
659}
660
661impl<'input> Namespace<'input> {
662    /// Returns namespace name/prefix.
663    ///
664    /// # Examples
665    ///
666    /// ```
667    /// let doc = roxmltree::Document::parse(
668    ///     "<e xmlns:n='http://www.w3.org'/>"
669    /// ).unwrap();
670    ///
671    /// assert_eq!(doc.root_element().namespaces().nth(0).unwrap().name(), Some("n"));
672    /// ```
673    ///
674    /// ```
675    /// let doc = roxmltree::Document::parse(
676    ///     "<e xmlns='http://www.w3.org'/>"
677    /// ).unwrap();
678    ///
679    /// assert_eq!(doc.root_element().namespaces().nth(0).unwrap().name(), None);
680    /// ```
681    #[inline]
682    pub fn name(&self) -> Option<&'input str> {
683        self.name
684    }
685
686    /// Returns namespace URI.
687    ///
688    /// # Examples
689    ///
690    /// ```
691    /// let doc = roxmltree::Document::parse(
692    ///     "<e xmlns:n='http://www.w3.org'/>"
693    /// ).unwrap();
694    ///
695    /// assert_eq!(doc.root_element().namespaces().nth(0).unwrap().uri(), "http://www.w3.org");
696    /// ```
697    #[inline]
698    pub fn uri(&self) -> &str {
699        self.uri.as_ref()
700    }
701}
702
703#[derive(Default)]
704struct Namespaces<'input> {
705    // Deduplicated namespace values used throughout the document
706    values: Vec<Namespace<'input>>,
707    // Indices into the above in tree order as the document is parsed
708    tree_order: Vec<NamespaceIdx>,
709    // Indices into the above sorted by value used for deduplication
710    sorted_order: Vec<NamespaceIdx>,
711}
712
713impl<'input> Namespaces<'input> {
714    fn push_ns(
715        &mut self,
716        name: Option<&'input str>,
717        uri: StringStorage<'input>,
718    ) -> Result<(), Error> {
719        debug_assert_ne!(name, Some(""));
720
721        let idx = match self.sorted_order.binary_search_by(|idx| {
722            let value = &self.values[idx.0 as usize];
723
724            (value.name, value.uri.as_ref()).cmp(&(name, uri.as_str()))
725        }) {
726            Ok(sorted_idx) => self.sorted_order[sorted_idx],
727            Err(sorted_idx) => {
728                if self.values.len() > core::u16::MAX as usize {
729                    return Err(Error::NamespacesLimitReached);
730                }
731                let idx = NamespaceIdx(self.values.len() as u16);
732                self.values.push(Namespace { name, uri });
733                self.sorted_order.insert(sorted_idx, idx);
734                idx
735            }
736        };
737
738        self.tree_order.push(idx);
739
740        Ok(())
741    }
742
743    #[inline]
744    fn push_ref(&mut self, tree_idx: usize) {
745        let idx = self.tree_order[tree_idx];
746        self.tree_order.push(idx);
747    }
748
749    #[inline]
750    fn exists(&self, start: usize, prefix: Option<&str>) -> bool {
751        self.tree_order[start..]
752            .iter()
753            .any(|idx| self.values[idx.0 as usize].name == prefix)
754    }
755
756    fn shrink_to_fit(&mut self) {
757        self.values.shrink_to_fit();
758        self.tree_order.shrink_to_fit();
759        self.sorted_order.shrink_to_fit();
760    }
761
762    #[inline]
763    fn get(&self, idx: NamespaceIdx) -> &Namespace<'input> {
764        &self.values[idx.0 as usize]
765    }
766}
767
768#[derive(Clone, Copy, Debug)]
769#[repr(transparent)]
770struct NamespaceIdx(u16);
771
772#[derive(Clone, Copy, Debug)]
773struct ExpandedNameIndexed<'input> {
774    namespace_idx: Option<NamespaceIdx>,
775    local_name: &'input str,
776}
777
778impl<'input> ExpandedNameIndexed<'input> {
779    #[inline]
780    fn namespace<'a>(&self, doc: &'a Document<'input>) -> Option<&'a Namespace<'input>> {
781        self.namespace_idx.map(|idx| doc.namespaces.get(idx))
782    }
783
784    #[inline]
785    fn as_expanded_name<'a>(&self, doc: &'a Document<'input>) -> ExpandedName<'a, 'input> {
786        ExpandedName {
787            uri: self.namespace(doc).map(Namespace::uri),
788            name: self.local_name,
789        }
790    }
791}
792
793/// An expanded name.
794///
795/// Contains an namespace URI and name pair.
796#[derive(Clone, Copy, PartialEq, Eq)]
797pub struct ExpandedName<'a, 'b> {
798    uri: Option<&'a str>,
799    name: &'b str,
800}
801
802impl<'a, 'b> ExpandedName<'a, 'b> {
803    /// Returns a namespace URI.
804    ///
805    /// # Examples
806    ///
807    /// ```
808    /// let doc = roxmltree::Document::parse("<e xmlns='http://www.w3.org'/>").unwrap();
809    ///
810    /// assert_eq!(doc.root_element().tag_name().namespace(), Some("http://www.w3.org"));
811    /// ```
812    #[inline]
813    pub fn namespace(&self) -> Option<&'a str> {
814        self.uri
815    }
816
817    /// Returns a local name.
818    ///
819    /// # Examples
820    ///
821    /// ```
822    /// let doc = roxmltree::Document::parse("<e/>").unwrap();
823    ///
824    /// assert_eq!(doc.root_element().tag_name().name(), "e");
825    /// ```
826    #[inline]
827    pub fn name(&self) -> &'b str {
828        self.name
829    }
830}
831
832impl ExpandedName<'static, 'static> {
833    /// Create a new instance from static data.
834    ///
835    /// # Example
836    ///
837    /// ```rust
838    /// use roxmltree::ExpandedName;
839    /// const DAV_HREF: ExpandedName =
840    ///     ExpandedName::from_static("urn:ietf:params:xml:ns:caldav:", "calendar-data");
841    /// ```
842    pub const fn from_static(uri: &'static str, name: &'static str) -> Self {
843        Self {
844            uri: Some(uri),
845            name,
846        }
847    }
848}
849
850impl fmt::Debug for ExpandedName<'_, '_> {
851    fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
852        match self.namespace() {
853            Some(ns) => write!(f, "{{{}}}{}", ns, self.name),
854            None => write!(f, "{}", self.name),
855        }
856    }
857}
858
859impl<'a, 'b> From<&'b str> for ExpandedName<'a, 'b> {
860    #[inline]
861    fn from(v: &'b str) -> Self {
862        ExpandedName { uri: None, name: v }
863    }
864}
865
866impl<'a, 'b> From<(&'a str, &'b str)> for ExpandedName<'a, 'b> {
867    #[inline]
868    fn from(v: (&'a str, &'b str)) -> Self {
869        ExpandedName {
870            uri: Some(v.0),
871            name: v.1,
872        }
873    }
874}
875
876/// A node in a document.
877///
878/// # Document Order
879///
880/// The implementation of the `Ord` traits for `Node` is based on the concept of *document-order*.
881/// In layman's terms, document-order is the order in which one would see each element if
882/// one opened a document in a text editor or web browser and scrolled down.
883/// Document-order convention is followed in XPath, CSS Counters, and DOM selectors API
884/// to ensure consistent results from selection.
885/// One difference in `roxmltree` is that there is the notion of more than one document
886/// in existence at a time. While Nodes within the same document are in document-order,
887/// Nodes in different documents will be grouped together, but not in any particular
888/// order.
889///
890/// As an example, if we have a Document `a` with Nodes `[a0, a1, a2]` and a
891/// Document `b` with Nodes `[b0, b1]`, these Nodes in order could be either
892/// `[a0, a1, a2, b0, b1]` or `[b0, b1, a0, a1, a2]` and roxmltree makes no
893/// guarantee which it will be.
894///
895/// Document-order is defined here in the
896/// [W3C XPath Recommendation](https://www.w3.org/TR/xpath-3/#id-document-order)
897/// The use of document-order in DOM Selectors is described here in the
898/// [W3C Selectors API Level 1](https://www.w3.org/TR/selectors-api/#the-apis)
899#[derive(Clone, Copy)]
900pub struct Node<'a, 'input: 'a> {
901    /// Node's ID.
902    id: NodeId,
903
904    /// The tree containing the node.
905    doc: &'a Document<'input>,
906
907    /// Node's data.
908    d: &'a NodeData<'input>,
909}
910
911impl Eq for Node<'_, '_> {}
912
913impl PartialEq for Node<'_, '_> {
914    #[inline]
915    fn eq(&self, other: &Self) -> bool {
916        (self.id, self.doc as *const _) == (other.id, other.doc as *const _)
917    }
918}
919
920impl PartialOrd for Node<'_, '_> {
921    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
922        Some(self.cmp(other))
923    }
924}
925
926impl Ord for Node<'_, '_> {
927    fn cmp(&self, other: &Self) -> Ordering {
928        (self.id.0, self.doc as *const _).cmp(&(other.id.0, other.doc as *const _))
929    }
930}
931
932impl Hash for Node<'_, '_> {
933    fn hash<H: Hasher>(&self, state: &mut H) {
934        self.id.0.hash(state);
935        (self.doc as *const Document).hash(state);
936        (self.d as *const NodeData).hash(state);
937    }
938}
939
940impl<'a, 'input: 'a> Node<'a, 'input> {
941    /// Returns node's type.
942    #[inline]
943    pub fn node_type(&self) -> NodeType {
944        match self.d.kind {
945            NodeKind::Root => NodeType::Root,
946            NodeKind::Element { .. } => NodeType::Element,
947            NodeKind::PI { .. } => NodeType::PI,
948            NodeKind::Comment(_) => NodeType::Comment,
949            NodeKind::Text(_) => NodeType::Text,
950        }
951    }
952
953    /// Checks that node is a root node.
954    #[inline]
955    pub fn is_root(&self) -> bool {
956        self.node_type() == NodeType::Root
957    }
958
959    /// Checks that node is an element node.
960    #[inline]
961    pub fn is_element(&self) -> bool {
962        self.node_type() == NodeType::Element
963    }
964
965    /// Checks that node is a processing instruction node.
966    #[inline]
967    pub fn is_pi(&self) -> bool {
968        self.node_type() == NodeType::PI
969    }
970
971    /// Checks that node is a comment node.
972    #[inline]
973    pub fn is_comment(&self) -> bool {
974        self.node_type() == NodeType::Comment
975    }
976
977    /// Checks that node is a text node.
978    #[inline]
979    pub fn is_text(&self) -> bool {
980        self.node_type() == NodeType::Text
981    }
982
983    /// Returns node's document.
984    #[inline]
985    pub fn document(&self) -> &'a Document<'input> {
986        self.doc
987    }
988
989    /// Returns node's tag name.
990    ///
991    /// Returns an empty name with no namespace if the current node is not an element.
992    ///
993    /// # Examples
994    ///
995    /// ```
996    /// let doc = roxmltree::Document::parse("<e xmlns='http://www.w3.org'/>").unwrap();
997    ///
998    /// assert_eq!(doc.root_element().tag_name().namespace(), Some("http://www.w3.org"));
999    /// assert_eq!(doc.root_element().tag_name().name(), "e");
1000    /// ```
1001    #[inline]
1002    pub fn tag_name(&self) -> ExpandedName<'a, 'input> {
1003        match self.d.kind {
1004            NodeKind::Element { ref tag_name, .. } => tag_name.as_expanded_name(self.doc),
1005            _ => "".into(),
1006        }
1007    }
1008
1009    /// Checks that node has a specified tag name.
1010    ///
1011    /// # Examples
1012    ///
1013    /// ```
1014    /// let doc = roxmltree::Document::parse("<e xmlns='http://www.w3.org'/>").unwrap();
1015    ///
1016    /// assert!(doc.root_element().has_tag_name("e"));
1017    /// assert!(doc.root_element().has_tag_name(("http://www.w3.org", "e")));
1018    ///
1019    /// assert!(!doc.root_element().has_tag_name("b"));
1020    /// assert!(!doc.root_element().has_tag_name(("http://www.w4.org", "e")));
1021    /// ```
1022    pub fn has_tag_name<'n, 'm, N>(&self, name: N) -> bool
1023    where
1024        N: Into<ExpandedName<'n, 'm>>,
1025    {
1026        let name = name.into();
1027
1028        match self.d.kind {
1029            NodeKind::Element { ref tag_name, .. } => match name.namespace() {
1030                Some(_) => tag_name.as_expanded_name(self.doc) == name,
1031                None => tag_name.local_name == name.name,
1032            },
1033            _ => false,
1034        }
1035    }
1036
1037    /// Returns node's default namespace URI.
1038    ///
1039    /// # Examples
1040    ///
1041    /// ```
1042    /// let doc = roxmltree::Document::parse("<e xmlns='http://www.w3.org'/>").unwrap();
1043    ///
1044    /// assert_eq!(doc.root_element().default_namespace(), Some("http://www.w3.org"));
1045    /// ```
1046    ///
1047    /// ```
1048    /// let doc = roxmltree::Document::parse("<e xmlns:n='http://www.w3.org'/>").unwrap();
1049    ///
1050    /// assert_eq!(doc.root_element().default_namespace(), None);
1051    /// ```
1052    pub fn default_namespace(&self) -> Option<&'a str> {
1053        self.namespaces()
1054            .find(|ns| ns.name.is_none())
1055            .map(|v| v.uri.as_ref())
1056    }
1057
1058    /// Returns a prefix for a given namespace URI.
1059    ///
1060    /// # Examples
1061    ///
1062    /// ```
1063    /// let doc = roxmltree::Document::parse("<e xmlns:n='http://www.w3.org'/>").unwrap();
1064    ///
1065    /// assert_eq!(doc.root_element().lookup_prefix("http://www.w3.org"), Some("n"));
1066    /// ```
1067    ///
1068    /// ```
1069    /// let doc = roxmltree::Document::parse("<e xmlns:n=''/>").unwrap();
1070    ///
1071    /// assert_eq!(doc.root_element().lookup_prefix(""), Some("n"));
1072    /// ```
1073    pub fn lookup_prefix(&self, uri: &str) -> Option<&'input str> {
1074        if uri == NS_XML_URI {
1075            return Some(NS_XML_PREFIX);
1076        }
1077
1078        self.namespaces()
1079            .find(|ns| &*ns.uri == uri)
1080            .map(|v| v.name)
1081            .unwrap_or(None)
1082    }
1083
1084    /// Returns an URI for a given prefix.
1085    ///
1086    /// # Examples
1087    ///
1088    /// ```
1089    /// let doc = roxmltree::Document::parse("<e xmlns:n='http://www.w3.org'/>").unwrap();
1090    ///
1091    /// assert_eq!(doc.root_element().lookup_namespace_uri(Some("n")), Some("http://www.w3.org"));
1092    /// ```
1093    ///
1094    /// ```
1095    /// let doc = roxmltree::Document::parse("<e xmlns='http://www.w3.org'/>").unwrap();
1096    ///
1097    /// assert_eq!(doc.root_element().lookup_namespace_uri(None), Some("http://www.w3.org"));
1098    /// ```
1099    pub fn lookup_namespace_uri(&self, prefix: Option<&str>) -> Option<&'a str> {
1100        self.namespaces()
1101            .find(|ns| ns.name == prefix)
1102            .map(|v| v.uri.as_ref())
1103    }
1104
1105    /// Returns element's attribute value.
1106    ///
1107    /// # Examples
1108    ///
1109    /// ```
1110    /// let doc = roxmltree::Document::parse("<e a='b'/>").unwrap();
1111    ///
1112    /// assert_eq!(doc.root_element().attribute("a"), Some("b"));
1113    /// ```
1114    ///
1115    /// ```
1116    /// let doc = roxmltree::Document::parse(
1117    ///     "<e xmlns:n='http://www.w3.org' a='b' n:a='c'/>"
1118    /// ).unwrap();
1119    ///
1120    /// assert_eq!(doc.root_element().attribute("a"), Some("b"));
1121    /// assert_eq!(doc.root_element().attribute(("http://www.w3.org", "a")), Some("c"));
1122    /// ```
1123    pub fn attribute<'n, 'm, N>(&self, name: N) -> Option<&'a str>
1124    where
1125        N: Into<ExpandedName<'n, 'm>>,
1126    {
1127        let name = name.into();
1128        self.attributes()
1129            .find(|a| a.data.name.as_expanded_name(self.doc) == name)
1130            .map(|a| a.value())
1131    }
1132
1133    /// Returns element's attribute object.
1134    ///
1135    /// The same as [`attribute()`], but returns the `Attribute` itself instead of a value string.
1136    ///
1137    /// [`attribute()`]: struct.Node.html#method.attribute
1138    pub fn attribute_node<'n, 'm, N>(&self, name: N) -> Option<Attribute<'a, 'input>>
1139    where
1140        N: Into<ExpandedName<'n, 'm>>,
1141    {
1142        let name = name.into();
1143        self.attributes()
1144            .find(|a| a.data.name.as_expanded_name(self.doc) == name)
1145    }
1146
1147    /// Checks that element has a specified attribute.
1148    ///
1149    /// # Examples
1150    ///
1151    /// ```
1152    /// let doc = roxmltree::Document::parse(
1153    ///     "<e xmlns:n='http://www.w3.org' a='b' n:a='c'/>"
1154    /// ).unwrap();
1155    ///
1156    /// assert!(doc.root_element().has_attribute("a"));
1157    /// assert!(doc.root_element().has_attribute(("http://www.w3.org", "a")));
1158    ///
1159    /// assert!(!doc.root_element().has_attribute("b"));
1160    /// assert!(!doc.root_element().has_attribute(("http://www.w4.org", "a")));
1161    /// ```
1162    pub fn has_attribute<'n, 'm, N>(&self, name: N) -> bool
1163    where
1164        N: Into<ExpandedName<'n, 'm>>,
1165    {
1166        let name = name.into();
1167        self.attributes()
1168            .any(|a| a.data.name.as_expanded_name(self.doc) == name)
1169    }
1170
1171    /// Returns element's attributes.
1172    ///
1173    /// # Examples
1174    ///
1175    /// ```
1176    /// let doc = roxmltree::Document::parse(
1177    ///     "<e xmlns:n='http://www.w3.org' a='b' n:a='c'/>"
1178    /// ).unwrap();
1179    ///
1180    /// assert_eq!(doc.root_element().attributes().len(), 2);
1181    /// ```
1182    #[inline]
1183    pub fn attributes(&self) -> Attributes<'a, 'input> {
1184        Attributes::new(self)
1185    }
1186
1187    /// Returns element's namespaces.
1188    ///
1189    /// # Examples
1190    ///
1191    /// ```
1192    /// let doc = roxmltree::Document::parse(
1193    ///     "<e xmlns:n='http://www.w3.org'/>"
1194    /// ).unwrap();
1195    ///
1196    /// assert_eq!(doc.root_element().namespaces().len(), 1);
1197    /// ```
1198    #[inline]
1199    pub fn namespaces(&self) -> NamespaceIter<'a, 'input> {
1200        let namespaces = match self.d.kind {
1201            NodeKind::Element { ref namespaces, .. } => {
1202                &self.doc.namespaces.tree_order[namespaces.to_urange()]
1203            }
1204            _ => &[],
1205        };
1206
1207        NamespaceIter {
1208            doc: self.doc,
1209            namespaces: namespaces.iter(),
1210        }
1211    }
1212
1213    /// Returns node's text.
1214    ///
1215    /// - for an element will return a first text child
1216    /// - for a comment will return a self text
1217    /// - for a text node will return a self text
1218    ///
1219    /// # Examples
1220    ///
1221    /// ```
1222    /// let doc = roxmltree::Document::parse("\
1223    /// <p>
1224    ///     text
1225    /// </p>
1226    /// ").unwrap();
1227    ///
1228    /// assert_eq!(doc.root_element().text(),
1229    ///            Some("\n    text\n"));
1230    /// assert_eq!(doc.root_element().first_child().unwrap().text(),
1231    ///            Some("\n    text\n"));
1232    /// ```
1233    ///
1234    /// ```
1235    /// let doc = roxmltree::Document::parse("<!-- comment --><e/>").unwrap();
1236    ///
1237    /// assert_eq!(doc.root().first_child().unwrap().text(), Some(" comment "));
1238    /// ```
1239    #[inline]
1240    pub fn text(&self) -> Option<&'a str> {
1241        self.text_storage().map(|s| s.as_str())
1242    }
1243
1244    /// Returns node's text storage.
1245    ///
1246    /// Useful when you need a more low-level access to an allocated string.
1247    pub fn text_storage(&self) -> Option<&'a StringStorage<'input>> {
1248        match self.d.kind {
1249            NodeKind::Element { .. } => match self.first_child() {
1250                Some(child) if child.is_text() => match self.doc.nodes[child.id.get_usize()].kind {
1251                    NodeKind::Text(ref text) => Some(text),
1252                    _ => None,
1253                },
1254                _ => None,
1255            },
1256            NodeKind::Comment(ref text) => Some(text),
1257            NodeKind::Text(ref text) => Some(text),
1258            _ => None,
1259        }
1260    }
1261
1262    /// Returns element's tail text.
1263    ///
1264    /// # Examples
1265    ///
1266    /// ```
1267    /// let doc = roxmltree::Document::parse("\
1268    /// <root>
1269    ///     text1
1270    ///     <p/>
1271    ///     text2
1272    /// </root>
1273    /// ").unwrap();
1274    ///
1275    /// let p = doc.descendants().find(|n| n.has_tag_name("p")).unwrap();
1276    /// assert_eq!(p.tail(), Some("\n    text2\n"));
1277    /// ```
1278    #[inline]
1279    pub fn tail(&self) -> Option<&'a str> {
1280        self.tail_storage().map(|s| s.as_str())
1281    }
1282
1283    /// Returns element's tail text storage.
1284    ///
1285    /// Useful when you need a more low-level access to an allocated string.
1286    pub fn tail_storage(&self) -> Option<&'a StringStorage<'input>> {
1287        if !self.is_element() {
1288            return None;
1289        }
1290
1291        match self.next_sibling().map(|n| n.id) {
1292            Some(id) => match self.doc.nodes[id.get_usize()].kind {
1293                NodeKind::Text(ref text) => Some(text),
1294                _ => None,
1295            },
1296            None => None,
1297        }
1298    }
1299
1300    /// Returns node as Processing Instruction.
1301    #[inline]
1302    pub fn pi(&self) -> Option<PI<'input>> {
1303        match self.d.kind {
1304            NodeKind::PI(pi) => Some(pi),
1305            _ => None,
1306        }
1307    }
1308
1309    /// Returns the parent of this node.
1310    #[inline]
1311    pub fn parent(&self) -> Option<Self> {
1312        self.d.parent.map(|id| self.doc.get_node(id).unwrap())
1313    }
1314
1315    /// Returns the parent element of this node.
1316    pub fn parent_element(&self) -> Option<Self> {
1317        self.ancestors().skip(1).find(|n| n.is_element())
1318    }
1319
1320    /// Returns the previous sibling of this node.
1321    #[inline]
1322    pub fn prev_sibling(&self) -> Option<Self> {
1323        self.d.prev_sibling.map(|id| self.doc.get_node(id).unwrap())
1324    }
1325
1326    /// Returns the previous sibling element of this node.
1327    pub fn prev_sibling_element(&self) -> Option<Self> {
1328        self.prev_siblings().skip(1).find(|n| n.is_element())
1329    }
1330
1331    /// Returns the next sibling of this node.
1332    #[inline]
1333    pub fn next_sibling(&self) -> Option<Self> {
1334        self.d
1335            .next_subtree
1336            .map(|id| self.doc.get_node(id).unwrap())
1337            .and_then(|node| {
1338                let possibly_self = node
1339                    .d
1340                    .prev_sibling
1341                    .expect("next_subtree will always have a previous sibling");
1342                if possibly_self == self.id {
1343                    Some(node)
1344                } else {
1345                    None
1346                }
1347            })
1348    }
1349
1350    /// Returns the next sibling element of this node.
1351    pub fn next_sibling_element(&self) -> Option<Self> {
1352        self.next_siblings().skip(1).find(|n| n.is_element())
1353    }
1354
1355    /// Returns the first child of this node.
1356    #[inline]
1357    pub fn first_child(&self) -> Option<Self> {
1358        self.d
1359            .last_child
1360            .map(|_| self.doc.get_node(NodeId::new(self.id.get() + 1)).unwrap())
1361    }
1362
1363    /// Returns the first element child of this node.
1364    pub fn first_element_child(&self) -> Option<Self> {
1365        self.children().find(|n| n.is_element())
1366    }
1367
1368    /// Returns the last child of this node.
1369    #[inline]
1370    pub fn last_child(&self) -> Option<Self> {
1371        self.d.last_child.map(|id| self.doc.get_node(id).unwrap())
1372    }
1373
1374    /// Returns the last element child of this node.
1375    pub fn last_element_child(&self) -> Option<Self> {
1376        self.children().filter(|n| n.is_element()).last()
1377    }
1378
1379    /// Returns true if this node has siblings.
1380    #[inline]
1381    pub fn has_siblings(&self) -> bool {
1382        self.d.prev_sibling.is_some() || self.next_sibling().is_some()
1383    }
1384
1385    /// Returns true if this node has children.
1386    #[inline]
1387    pub fn has_children(&self) -> bool {
1388        self.d.last_child.is_some()
1389    }
1390
1391    /// Returns an iterator over ancestor nodes starting at this node.
1392    #[inline]
1393    pub fn ancestors(&self) -> AxisIter<'a, 'input> {
1394        AxisIter {
1395            node: Some(*self),
1396            next: Node::parent,
1397        }
1398    }
1399
1400    /// Returns an iterator over previous sibling nodes starting at this node.
1401    #[inline]
1402    pub fn prev_siblings(&self) -> AxisIter<'a, 'input> {
1403        AxisIter {
1404            node: Some(*self),
1405            next: Node::prev_sibling,
1406        }
1407    }
1408
1409    /// Returns an iterator over next sibling nodes starting at this node.
1410    #[inline]
1411    pub fn next_siblings(&self) -> AxisIter<'a, 'input> {
1412        AxisIter {
1413            node: Some(*self),
1414            next: Node::next_sibling,
1415        }
1416    }
1417
1418    /// Returns an iterator over first children nodes starting at this node.
1419    #[inline]
1420    pub fn first_children(&self) -> AxisIter<'a, 'input> {
1421        AxisIter {
1422            node: Some(*self),
1423            next: Node::first_child,
1424        }
1425    }
1426
1427    /// Returns an iterator over last children nodes starting at this node.
1428    #[inline]
1429    pub fn last_children(&self) -> AxisIter<'a, 'input> {
1430        AxisIter {
1431            node: Some(*self),
1432            next: Node::last_child,
1433        }
1434    }
1435
1436    /// Returns an iterator over children nodes.
1437    #[inline]
1438    pub fn children(&self) -> Children<'a, 'input> {
1439        Children {
1440            front: self.first_child(),
1441            back: self.last_child(),
1442        }
1443    }
1444
1445    /// Returns an iterator over this node and its descendants.
1446    #[inline]
1447    pub fn descendants(&self) -> Descendants<'a, 'input> {
1448        Descendants::new(*self)
1449    }
1450
1451    /// Returns node's range in bytes in the original document.
1452    #[cfg(feature = "positions")]
1453    #[inline]
1454    pub fn range(&self) -> Range<usize> {
1455        self.d.range.clone()
1456    }
1457
1458    /// Returns node's NodeId
1459    #[inline]
1460    pub fn id(&self) -> NodeId {
1461        self.id
1462    }
1463}
1464
1465impl<'a, 'input: 'a> fmt::Debug for Node<'a, 'input> {
1466    fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
1467        match self.d.kind {
1468            NodeKind::Root => write!(f, "Root"),
1469            NodeKind::Element { .. } => {
1470                write!(
1471                    f,
1472                    "Element {{ tag_name: {:?}, attributes: {:?}, namespaces: {:?} }}",
1473                    self.tag_name(),
1474                    self.attributes(),
1475                    self.namespaces()
1476                )
1477            }
1478            NodeKind::PI(pi) => {
1479                write!(f, "PI {{ target: {:?}, value: {:?} }}", pi.target, pi.value)
1480            }
1481            NodeKind::Comment(ref text) => write!(f, "Comment({:?})", text.as_str()),
1482            NodeKind::Text(ref text) => write!(f, "Text({:?})", text.as_str()),
1483        }
1484    }
1485}
1486
1487/// Iterator over a node's attributes
1488#[derive(Clone)]
1489pub struct Attributes<'a, 'input> {
1490    doc: &'a Document<'input>,
1491    attrs: core::slice::Iter<'a, AttributeData<'input>>,
1492}
1493
1494impl<'a, 'input> Attributes<'a, 'input> {
1495    #[inline]
1496    fn new(node: &Node<'a, 'input>) -> Attributes<'a, 'input> {
1497        let attrs = match node.d.kind {
1498            NodeKind::Element { ref attributes, .. } => {
1499                &node.doc.attributes[attributes.to_urange()]
1500            }
1501            _ => &[],
1502        };
1503        Attributes {
1504            doc: node.doc,
1505            attrs: attrs.iter(),
1506        }
1507    }
1508}
1509
1510impl<'a, 'input> Iterator for Attributes<'a, 'input> {
1511    type Item = Attribute<'a, 'input>;
1512
1513    #[inline]
1514    fn next(&mut self) -> Option<Self::Item> {
1515        self.attrs.next().map(|attr| Attribute {
1516            doc: self.doc,
1517            data: attr,
1518        })
1519    }
1520
1521    #[inline]
1522    fn nth(&mut self, n: usize) -> Option<Self::Item> {
1523        self.attrs.nth(n).map(|attr| Attribute {
1524            doc: self.doc,
1525            data: attr,
1526        })
1527    }
1528
1529    #[inline]
1530    fn size_hint(&self) -> (usize, Option<usize>) {
1531        self.attrs.size_hint()
1532    }
1533}
1534
1535impl<'a, 'input> DoubleEndedIterator for Attributes<'a, 'input> {
1536    #[inline]
1537    fn next_back(&mut self) -> Option<Self::Item> {
1538        self.attrs.next_back().map(|attr| Attribute {
1539            doc: self.doc,
1540            data: attr,
1541        })
1542    }
1543}
1544
1545impl ExactSizeIterator for Attributes<'_, '_> {}
1546
1547impl fmt::Debug for Attributes<'_, '_> {
1548    fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
1549        f.debug_struct("Attributes")
1550            .field("attrs", &self.attrs)
1551            .finish()
1552    }
1553}
1554
1555/// Iterator over specified axis.
1556#[derive(Clone)]
1557pub struct AxisIter<'a, 'input: 'a> {
1558    node: Option<Node<'a, 'input>>,
1559    next: fn(&Node<'a, 'input>) -> Option<Node<'a, 'input>>,
1560}
1561
1562impl<'a, 'input: 'a> Iterator for AxisIter<'a, 'input> {
1563    type Item = Node<'a, 'input>;
1564
1565    #[inline]
1566    fn next(&mut self) -> Option<Self::Item> {
1567        let node = self.node.take();
1568        self.node = node.as_ref().and_then(self.next);
1569        node
1570    }
1571}
1572
1573impl fmt::Debug for AxisIter<'_, '_> {
1574    fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
1575        f.debug_struct("AxisIter")
1576            .field("node", &self.node)
1577            .field("next", &"fn()")
1578            .finish()
1579    }
1580}
1581
1582/// Iterator over children.
1583#[derive(Clone, Debug)]
1584pub struct Children<'a, 'input: 'a> {
1585    front: Option<Node<'a, 'input>>,
1586    back: Option<Node<'a, 'input>>,
1587}
1588
1589impl<'a, 'input: 'a> Iterator for Children<'a, 'input> {
1590    type Item = Node<'a, 'input>;
1591
1592    #[inline]
1593    fn next(&mut self) -> Option<Self::Item> {
1594        if self.front == self.back {
1595            let node = self.front.take();
1596            self.back = None;
1597            node
1598        } else {
1599            let node = self.front.take();
1600            self.front = node.as_ref().and_then(Node::next_sibling);
1601            node
1602        }
1603    }
1604}
1605
1606impl<'a, 'input: 'a> DoubleEndedIterator for Children<'a, 'input> {
1607    #[inline]
1608    fn next_back(&mut self) -> Option<Self::Item> {
1609        if self.back == self.front {
1610            let node = self.back.take();
1611            self.front = None;
1612            node
1613        } else {
1614            let node = self.back.take();
1615            self.back = node.as_ref().and_then(Node::prev_sibling);
1616            node
1617        }
1618    }
1619}
1620
1621/// Iterator over a node and its descendants.
1622#[derive(Clone)]
1623pub struct Descendants<'a, 'input> {
1624    doc: &'a Document<'input>,
1625    nodes: core::iter::Enumerate<core::slice::Iter<'a, NodeData<'input>>>,
1626    from: usize,
1627}
1628
1629impl<'a, 'input> Descendants<'a, 'input> {
1630    #[inline]
1631    fn new(start: Node<'a, 'input>) -> Self {
1632        let from = start.id.get_usize();
1633
1634        let until = start
1635            .d
1636            .next_subtree
1637            .map(NodeId::get_usize)
1638            .unwrap_or(start.doc.nodes.len());
1639
1640        let nodes = start.doc.nodes[from..until].iter().enumerate();
1641
1642        Self {
1643            doc: start.doc,
1644            nodes,
1645            from,
1646        }
1647    }
1648}
1649
1650impl<'a, 'input> Iterator for Descendants<'a, 'input> {
1651    type Item = Node<'a, 'input>;
1652
1653    #[inline]
1654    fn next(&mut self) -> Option<Self::Item> {
1655        self.nodes.next().map(|(idx, data)| Node {
1656            id: NodeId::from(self.from + idx),
1657            d: data,
1658            doc: self.doc,
1659        })
1660    }
1661
1662    #[inline]
1663    fn nth(&mut self, n: usize) -> Option<Self::Item> {
1664        self.nodes.nth(n).map(|(idx, data)| Node {
1665            id: NodeId::from(self.from + idx),
1666            d: data,
1667            doc: self.doc,
1668        })
1669    }
1670
1671    #[inline]
1672    fn size_hint(&self) -> (usize, Option<usize>) {
1673        self.nodes.size_hint()
1674    }
1675}
1676
1677impl<'a, 'input> DoubleEndedIterator for Descendants<'a, 'input> {
1678    #[inline]
1679    fn next_back(&mut self) -> Option<Self::Item> {
1680        self.nodes.next_back().map(|(idx, data)| Node {
1681            id: NodeId::from(self.from + idx),
1682            d: data,
1683            doc: self.doc,
1684        })
1685    }
1686}
1687
1688impl ExactSizeIterator for Descendants<'_, '_> {}
1689
1690impl fmt::Debug for Descendants<'_, '_> {
1691    fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
1692        f.debug_struct("Descendants")
1693            .field("nodes", &self.nodes)
1694            .field("from", &self.from)
1695            .finish()
1696    }
1697}
1698
1699/// Iterator over the namespaces attached to a node.
1700#[derive(Clone)]
1701pub struct NamespaceIter<'a, 'input> {
1702    doc: &'a Document<'input>,
1703    namespaces: core::slice::Iter<'a, NamespaceIdx>,
1704}
1705
1706impl<'a, 'input> Iterator for NamespaceIter<'a, 'input> {
1707    type Item = &'a Namespace<'input>;
1708
1709    #[inline]
1710    fn next(&mut self) -> Option<Self::Item> {
1711        self.namespaces
1712            .next()
1713            .map(|idx| self.doc.namespaces.get(*idx))
1714    }
1715
1716    #[inline]
1717    fn nth(&mut self, n: usize) -> Option<Self::Item> {
1718        self.namespaces
1719            .nth(n)
1720            .map(|idx| self.doc.namespaces.get(*idx))
1721    }
1722
1723    #[inline]
1724    fn size_hint(&self) -> (usize, Option<usize>) {
1725        self.namespaces.size_hint()
1726    }
1727}
1728
1729impl<'a, 'input> DoubleEndedIterator for NamespaceIter<'a, 'input> {
1730    #[inline]
1731    fn next_back(&mut self) -> Option<Self::Item> {
1732        self.namespaces
1733            .next()
1734            .map(|idx| self.doc.namespaces.get(*idx))
1735    }
1736}
1737
1738impl ExactSizeIterator for NamespaceIter<'_, '_> {}
1739
1740impl fmt::Debug for NamespaceIter<'_, '_> {
1741    fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
1742        f.debug_struct("NamespaceIter")
1743            .field("namespaces", &self.namespaces)
1744            .finish()
1745    }
1746}