Skip to main content

anyxml/tree/
node.rs

1use std::{
2    cell::RefCell,
3    rc::{Rc, Weak},
4};
5
6use crate::{
7    XML_XML_NAMESPACE,
8    tree::{
9        Element, NodeType, XMLTreeError, compare_document_order,
10        convert::NodeKind,
11        document::{Document, DocumentSpec},
12        document_fragment::DocumentFragmentSpec,
13    },
14    uri::URIString,
15};
16
17/// Common traits for node types.
18///
19/// This trait is not intended to be implemented by library users and should not be implemented.
20pub trait NodeSpec: std::any::Any {
21    /// Return the node type.
22    ///
23    /// For abstract node types, this method guarantees that conversion
24    /// to the specified node type will always succeed.
25    fn node_type(&self) -> NodeType;
26    /// The pointer of the first child.
27    fn first_child(&self) -> Option<Rc<RefCell<NodeCore<dyn NodeSpec>>>>;
28    /// The pointer of the last child.
29    fn last_child(&self) -> Option<Rc<RefCell<NodeCore<dyn NodeSpec>>>>;
30}
31
32/// Common traits of internal nodes (i.e., nodes that are not leaf nodes).
33///
34/// This trait is not intended to be implemented by library users and should not be implemented.
35pub trait InternalNodeSpec: NodeSpec {
36    /// Set the pointer of the first child.
37    fn set_first_child(&mut self, new: Rc<RefCell<NodeCore<dyn NodeSpec>>>);
38    /// Unset the pointer of the first child.
39    fn unset_first_child(&mut self);
40
41    /// Set the pointer of the last child.
42    fn set_last_child(&mut self, new: Rc<RefCell<NodeCore<dyn NodeSpec>>>);
43    /// Unset the pointer of the last child.
44    fn unset_last_child(&mut self);
45
46    /// The process performed immediately before deleting a child.
47    fn pre_child_removal(&mut self, removed_child: Node<dyn NodeSpec>) -> Result<(), XMLTreeError> {
48        let _ = removed_child;
49        Ok(())
50    }
51
52    /// Perform preprocessing when `inserted_child` is inserted following `preceding_node`.
53    ///
54    /// If there is no preceding node (i.e., `inserted_child` is inserted as the first child),
55    /// `preceding_node` is `None`.
56    ///
57    /// Only perform precondition checks; do not cause side effects.
58    fn pre_child_insertion(
59        &self,
60        inserted_child: Node<dyn NodeSpec>,
61        preceding_node: Option<Node<dyn NodeSpec>>,
62    ) -> Result<(), XMLTreeError> {
63        let _ = (inserted_child, preceding_node);
64        Ok(())
65    }
66
67    /// Perform postprocessing when `inserted_child` is inserted following `preceding_node`.
68    ///
69    /// If there is no preceding node (i.e., `inserted_child` is inserted as the first child),
70    /// `preceding_node` is `None`.
71    ///
72    /// Assume all prerequisites are satisfied; errors must not occur.
73    fn post_child_insertion(&mut self, inserted_child: Node<dyn NodeSpec>) {
74        let _ = inserted_child;
75    }
76}
77
78/// Common node core data.
79pub struct NodeCore<Spec: ?Sized> {
80    pub(super) parent_node: Weak<RefCell<NodeCore<dyn InternalNodeSpec>>>,
81    pub(super) previous_sibling: Weak<RefCell<NodeCore<dyn NodeSpec>>>,
82    pub(super) next_sibling: Option<Rc<RefCell<NodeCore<dyn NodeSpec>>>>,
83    pub(super) line: usize,
84    pub(super) column: usize,
85    pub(super) spec: Spec,
86}
87
88/// Pointer to a node.
89///
90/// Internally, it is a pair consisting of a reference counter for the node's data
91/// and a reference counter for the document node that owns it.
92///
93/// `Node<dyn NodeSpec>` and `Node<dyn InternalNodeSpec>` are abstract node types.  \
94/// They enable common operations on concrete node types that implement their respective traits,
95/// as well as conversion to a specific concrete node type.
96pub struct Node<Spec: ?Sized> {
97    pub(super) core: Rc<RefCell<NodeCore<Spec>>>,
98    pub(super) owner_document: Rc<RefCell<NodeCore<DocumentSpec>>>,
99}
100
101impl<Spec: NodeSpec + ?Sized> Node<Spec> {
102    /// Return the node type.
103    ///
104    /// For abstract node types, this method guarantees that conversion
105    /// to the specified node type will always succeed.
106    pub fn node_type(&self) -> NodeType {
107        self.core.borrow().spec.node_type()
108    }
109
110    /// Get the parent node of `self` if exsits.
111    ///
112    /// # Note
113    /// [`Attribute`](crate::tree::Attribute) and [`Namespace`](crate::tree::Namespace) each return
114    /// the same result as [`Attribute::owner_element`](crate::tree::Attribute::owner_element)
115    /// and [`Namespace::owner_element`](crate::tree::Namespace::owner_element),
116    /// but neither is a child of [`Element`].
117    pub fn parent_node(&self) -> Option<Node<dyn InternalNodeSpec>> {
118        self.core.borrow().parent_node.upgrade().map(|core| Node {
119            core,
120            owner_document: self.owner_document.clone(),
121        })
122    }
123    /// Get the previous sibling node of `self` if exsits.
124    ///
125    /// # Note
126    /// [`Attribute`](crate::tree::Attribute) and [`Namespace`](crate::tree::Namespace)
127    /// always return [`None`].
128    pub fn previous_sibling(&self) -> Option<Node<dyn NodeSpec>> {
129        self.core
130            .borrow()
131            .previous_sibling
132            .upgrade()
133            .map(|core| Node {
134                core: core as _,
135                owner_document: self.owner_document.clone(),
136            })
137    }
138    /// Get the previous sibling whose node type is [`Element`](NodeType::Element).
139    pub fn previous_element_sibling(&self) -> Option<Element> {
140        let mut previous = self.previous_sibling();
141        while let Some(now) = previous {
142            if let Some(element) = now.as_element() {
143                return Some(element);
144            }
145
146            if matches!(now.node_type(), NodeType::EntityReference)
147                && let Some(last) = now.last_child()
148            {
149                previous = Some(last);
150            } else if let Some(prev) = now.previous_sibling() {
151                previous = Some(prev);
152            } else {
153                previous = None;
154
155                let mut parent = now.parent_node();
156                while let Some(par) =
157                    parent.filter(|par| matches!(par.node_type(), NodeType::EntityReference))
158                {
159                    if let Some(prev) = par.previous_sibling() {
160                        previous = Some(prev);
161                        break;
162                    }
163                    parent = par.parent_node();
164                }
165            }
166        }
167        None
168    }
169    /// Get the next sibling node of `self` if exsits.
170    ///
171    /// # Note
172    /// [`Attribute`](crate::tree::Attribute) and [`Namespace`](crate::tree::Namespace)
173    /// always return [`None`].
174    pub fn next_sibling(&self) -> Option<Node<dyn NodeSpec>> {
175        self.core.borrow().next_sibling.clone().map(|core| Node {
176            core: core as _,
177            owner_document: self.owner_document.clone(),
178        })
179    }
180    /// Get the next sibling whose node type is [`Element`](NodeType::Element).
181    pub fn next_element_sibling(&self) -> Option<Element> {
182        let mut next = self.next_sibling();
183        while let Some(now) = next {
184            if let Some(element) = now.as_element() {
185                return Some(element);
186            }
187
188            if matches!(now.node_type(), NodeType::EntityReference)
189                && let Some(first) = now.first_child()
190            {
191                next = Some(first);
192            } else if let Some(nt) = now.next_sibling() {
193                next = Some(nt);
194            } else {
195                next = None;
196
197                let mut parent = now.parent_node();
198                while let Some(par) =
199                    parent.filter(|par| matches!(par.node_type(), NodeType::EntityReference))
200                {
201                    if let Some(nt) = par.next_sibling() {
202                        next = Some(nt);
203                        break;
204                    }
205                    parent = par.parent_node();
206                }
207            }
208        }
209        None
210    }
211    /// Get the first child node of `self` if exsits.
212    pub fn first_child(&self) -> Option<Node<dyn NodeSpec>> {
213        self.core.borrow().spec.first_child().map(|core| Node {
214            core,
215            owner_document: self.owner_document.clone(),
216        })
217    }
218    /// Get the first child whose node type is [`Element`](NodeType::Element).
219    pub fn first_element_child(&self) -> Option<Element> {
220        let mut children = self.first_child();
221        while let Some(child) = children {
222            if let Some(element) = child.as_element() {
223                return Some(element);
224            }
225
226            if matches!(child.node_type(), NodeType::EntityReference)
227                && let Some(first) = child.first_child()
228            {
229                children = Some(first);
230            } else if let Some(next) = child.next_sibling() {
231                children = Some(next);
232            } else {
233                children = None;
234
235                let mut parent = child.parent_node();
236                while let Some(par) =
237                    parent.filter(|par| matches!(par.node_type(), NodeType::EntityReference))
238                {
239                    if let Some(next) = par.next_sibling() {
240                        children = Some(next);
241                        break;
242                    }
243                    parent = par.parent_node();
244                }
245            }
246        }
247        None
248    }
249    /// Get the last child node of `self` if exsits.
250    pub fn last_child(&self) -> Option<Node<dyn NodeSpec>> {
251        self.core.borrow().spec.last_child().map(|core| Node {
252            core,
253            owner_document: self.owner_document.clone(),
254        })
255    }
256    /// Get the first child whose node type is [`Element`](NodeType::Element).
257    pub fn last_element_child(&self) -> Option<Element> {
258        let mut children = self.last_child();
259        while let Some(child) = children {
260            if let Some(element) = child.as_element() {
261                return Some(element);
262            }
263
264            if matches!(child.node_type(), NodeType::EntityReference)
265                && let Some(first) = child.last_child()
266            {
267                children = Some(first);
268            } else if let Some(next) = child.previous_sibling() {
269                children = Some(next);
270            } else {
271                children = None;
272
273                let mut parent = child.parent_node();
274                while let Some(par) =
275                    parent.filter(|par| matches!(par.node_type(), NodeType::EntityReference))
276                {
277                    if let Some(next) = par.previous_sibling() {
278                        children = Some(next);
279                        break;
280                    }
281                    parent = par.parent_node();
282                }
283            }
284        }
285        None
286    }
287
288    /// Get the [`Document`] node that represents the owner document of `self`.
289    pub fn owner_document(&self) -> Document {
290        Document {
291            core: self.owner_document.clone(),
292            owner_document: self.owner_document.clone(),
293        }
294    }
295
296    fn set_paretn_node(&mut self, new: Node<dyn InternalNodeSpec>) {
297        self.core.borrow_mut().parent_node = Rc::downgrade(&new.core) as _;
298    }
299    fn unset_parent_node(&mut self) {
300        // Since the type size must be known at compile time,
301        // create a weak reference to an arbitrary node as a dummy and upcast it.
302        let weak: Weak<RefCell<NodeCore<DocumentFragmentSpec>>> = Weak::new();
303        self.core.borrow_mut().parent_node = weak as _;
304    }
305
306    fn set_previous_sibling(&mut self, new: Node<dyn NodeSpec>) {
307        self.core.borrow_mut().previous_sibling = Rc::downgrade(&new.core);
308    }
309    fn unset_previous_sibling(&mut self) {
310        // Since the type size must be known at compile time,
311        // create a weak reference to an arbitrary node as a dummy and upcast it.
312        let weak: Weak<RefCell<NodeCore<DocumentFragmentSpec>>> = Weak::new();
313        self.core.borrow_mut().previous_sibling = weak as _;
314    }
315
316    fn set_next_sibling(&mut self, new: Node<dyn NodeSpec>) {
317        self.core.borrow_mut().next_sibling = Some(new.core.clone());
318    }
319    fn unset_next_sibling(&mut self) {
320        self.core.borrow_mut().next_sibling = None;
321    }
322
323    pub(super) fn is_same_owner_document<Other: NodeSpec + ?Sized>(
324        &self,
325        other: &Node<Other>,
326    ) -> bool {
327        Rc::ptr_eq(&self.owner_document, &other.owner_document)
328    }
329
330    /// The line number of the markup or text content represented by the current node
331    /// in the XML document from which the tree was constructed.
332    ///
333    /// If the tree has been edited since it was first constructed, the value returned
334    /// by this method has no meaning.
335    pub fn line(&self) -> usize {
336        self.core.borrow().line
337    }
338    pub(super) fn set_line(&mut self, line: usize) {
339        self.core.borrow_mut().line = line;
340    }
341
342    /// The column number of the markup or text content represented by the current node
343    /// in the XML document from which the tree was constructed.
344    ///
345    /// If the tree has been edited since it was first constructed, the value returned
346    /// by this method has no meaning.
347    pub fn column(&self) -> usize {
348        self.core.borrow().column
349    }
350    pub(super) fn set_column(&mut self, column: usize) {
351        self.core.borrow_mut().column = column;
352    }
353}
354
355impl Node<dyn NodeSpec> {
356    /// Detach the link between parent and self, and remove self from the sibling list.
357    ///
358    /// For attribute nodes, execute [`remove_attribute_node`](crate::tree::Element::remove_attribute_node) on the parent element for itself.  \
359    /// For namespace nodes, execute [`undeclare_namespace`](crate::tree::Element::undeclare_namespace) on the parent element for itself.
360    pub fn detach(&mut self) -> Result<(), XMLTreeError> {
361        let mut parent_node = self.parent_node();
362        if let Some(parent_node) = parent_node.as_mut() {
363            match self.downcast() {
364                NodeKind::Attribute(attribute) => {
365                    if let Some(mut element) = attribute.owner_element() {
366                        element.remove_attribute_node(attribute).ok();
367                    }
368                    return Ok(());
369                }
370                NodeKind::Namespace(namespace) => {
371                    if let Some(mut element) = namespace.owner_element() {
372                        element.undeclare_namespace(namespace.prefix().as_deref());
373                    }
374                    return Ok(());
375                }
376                _ => {
377                    parent_node.pre_child_removal(self.clone())?;
378                }
379            }
380        }
381        self.unset_parent_node();
382        let previous_sibling = self.previous_sibling();
383        self.unset_previous_sibling();
384        let next_sibling = self.next_sibling();
385        self.unset_next_sibling();
386
387        match (parent_node, previous_sibling, next_sibling) {
388            (_, Some(mut previous_sibling), Some(mut next_sibling)) => {
389                previous_sibling.set_next_sibling(next_sibling.clone());
390                next_sibling.set_previous_sibling(previous_sibling.clone());
391            }
392            (Some(mut parent_node), Some(mut previous_sibling), None) => {
393                previous_sibling.unset_next_sibling();
394                parent_node.set_last_child(previous_sibling);
395            }
396            (Some(mut parent_node), None, Some(mut next_sibling)) => {
397                next_sibling.unset_previous_sibling();
398                parent_node.set_first_child(next_sibling);
399            }
400            (Some(mut parent_node), None, None) => {
401                parent_node.unset_first_child();
402                parent_node.unset_last_child();
403            }
404            (None, Some(mut previous_sibling), None) => {
405                previous_sibling.unset_next_sibling();
406            }
407            (None, None, Some(mut next_sibling)) => {
408                next_sibling.unset_previous_sibling();
409            }
410            (None, None, None) => {}
411        }
412        Ok(())
413    }
414
415    fn cyclic_reference_check(
416        &self,
417        reference_node: &Node<dyn NodeSpec>,
418    ) -> Result<(), XMLTreeError> {
419        let mut parent_node = Some(self.clone());
420        while let Some(now) = parent_node {
421            parent_node = now.parent_node().map(From::from);
422            if Rc::ptr_eq(&reference_node.core, &now.core) {
423                return Err(XMLTreeError::CyclicReference);
424            }
425        }
426        Ok(())
427    }
428
429    fn pre_insertion_common_check(
430        &self,
431        new_sibling: &Node<dyn NodeSpec>,
432    ) -> Result<(), XMLTreeError> {
433        if matches!(
434            new_sibling.node_type(),
435            NodeType::Document
436                | NodeType::DocumentFragment
437                | NodeType::Attribute
438                | NodeType::Namespace
439        ) {
440            return Err(XMLTreeError::UnacceptableHierarchy);
441        }
442
443        self.cyclic_reference_check(new_sibling)?;
444        Ok(())
445    }
446
447    fn do_insert_previous_sibling(
448        &mut self,
449        mut new_sibling: Node<dyn NodeSpec>,
450    ) -> Result<(), XMLTreeError> {
451        if self.parent_node().is_none() {
452            return Err(XMLTreeError::UnacceptableHierarchy);
453        }
454        if let Some(frag) = new_sibling.as_document_fragment() {
455            let mut succeed = 0;
456            while let Some(mut child) = frag.first_child() {
457                let ret = self.insert_previous_sibling(child.clone());
458                if ret.is_err() {
459                    // rollback
460                    for _ in 0..succeed {
461                        if let Some(mut previous) = self.previous_sibling() {
462                            previous.detach()?;
463                            child.insert_previous_sibling(previous.clone())?;
464                            child = previous;
465                        }
466                    }
467                    return ret;
468                }
469                succeed += 1;
470            }
471            return Ok(());
472        }
473        self.pre_insertion_common_check(&new_sibling)?;
474        if let Some(parent_node) = self.parent_node() {
475            parent_node.pre_child_insertion(new_sibling.clone(), self.previous_sibling())?;
476        }
477        new_sibling.detach()?;
478        new_sibling.set_next_sibling(self.clone());
479        if let Some(mut previous_sibling) = self.previous_sibling() {
480            previous_sibling.set_next_sibling(new_sibling.clone());
481            new_sibling.set_previous_sibling(previous_sibling);
482            if let Some(parent_node) = self.parent_node() {
483                new_sibling.set_paretn_node(parent_node);
484            }
485        } else if let Some(mut parent_node) = self.parent_node() {
486            parent_node.set_first_child(new_sibling.clone());
487            new_sibling.set_paretn_node(parent_node);
488        }
489        self.set_previous_sibling(new_sibling.clone());
490        if let Some(mut parent_node) = self.parent_node() {
491            parent_node.post_child_insertion(new_sibling);
492        }
493        Ok(())
494    }
495
496    /// Insert `new_sibling` as a sibling preceding itself.
497    ///
498    /// Insertions that violate tree constraints (such as those that create cyclic references
499    /// or insert siblings at the root node) are errors.  \
500    /// Additionally, operations that generate expressions impossible in well-formed XML documents
501    /// (such as placing Text outside document elements or inserting declarations into element
502    /// content) are also errors.
503    ///
504    /// # Example
505    /// ```rust
506    /// use anyxml::tree::Document;
507    ///
508    /// let mut document = Document::new();
509    /// let mut root = document.create_element("root", None).unwrap();
510    /// let mut comment = document.create_comment("comment").unwrap();
511    /// // cyclic reference
512    /// assert!(root.insert_previous_sibling(root.clone()).is_err());
513    /// // multiple root
514    /// assert!(root.insert_previous_sibling(comment.clone()).is_err());
515    /// document.append_child(root.clone()).unwrap();
516    /// root.insert_previous_sibling(comment).unwrap();
517    /// assert!(root
518    ///     .previous_sibling()
519    ///     .and_then(|sib| sib.as_comment())
520    ///     .is_some_and(|comment| &*comment.data() == "comment")
521    /// );
522    /// ```
523    pub fn insert_previous_sibling(
524        &mut self,
525        new_sibling: impl Into<Node<dyn NodeSpec>>,
526    ) -> Result<(), XMLTreeError> {
527        self.do_insert_previous_sibling(new_sibling.into())
528    }
529
530    fn do_insert_next_sibling(
531        &mut self,
532        mut new_sibling: Node<dyn NodeSpec>,
533    ) -> Result<(), XMLTreeError> {
534        if self.parent_node().is_none() {
535            return Err(XMLTreeError::UnacceptableHierarchy);
536        }
537        if let Some(mut frag) = new_sibling.as_document_fragment() {
538            let mut succeed = 0;
539            while let Some(child) = frag.last_child() {
540                let ret = self.insert_next_sibling(child);
541                if ret.is_err() {
542                    // rollback
543                    for _ in 0..succeed {
544                        if let Some(mut next) = self.next_sibling() {
545                            next.detach()?;
546                            frag.append_child(next)?;
547                        }
548                    }
549                    return ret;
550                }
551                succeed += 1;
552            }
553            return Ok(());
554        }
555        self.pre_insertion_common_check(&new_sibling)?;
556        if let Some(parent_node) = self.parent_node() {
557            parent_node.pre_child_insertion(new_sibling.clone(), Some(self.clone()))?;
558        }
559        new_sibling.detach()?;
560        new_sibling.set_previous_sibling(self.clone());
561        if let Some(mut next_sibling) = self.next_sibling() {
562            next_sibling.set_previous_sibling(new_sibling.clone());
563            new_sibling.set_next_sibling(next_sibling);
564            if let Some(parent_node) = self.parent_node() {
565                new_sibling.set_paretn_node(parent_node);
566            }
567        } else if let Some(mut parent_node) = self.parent_node() {
568            parent_node.set_last_child(new_sibling.clone());
569            new_sibling.set_paretn_node(parent_node);
570        }
571        self.set_next_sibling(new_sibling.clone());
572        if let Some(mut parent_node) = self.parent_node() {
573            parent_node.post_child_insertion(new_sibling);
574        }
575        Ok(())
576    }
577
578    /// Insert `new_sibling` as a sibling following itself.
579    ///
580    /// Insertions that violate tree constraints (such as those that create cyclic references
581    /// or insert siblings at the root node) are errors.  \
582    /// Additionally, operations that generate expressions impossible in well-formed XML documents
583    /// (such as placing Text outside document elements or inserting declarations into element
584    /// content) are also errors.
585    ///
586    /// # Example
587    /// ```rust
588    /// use anyxml::tree::Document;
589    ///
590    /// let mut document = Document::new();
591    /// let mut root = document.create_element("root", None).unwrap();
592    /// let mut comment = document.create_comment("comment").unwrap();
593    /// // cyclic reference
594    /// assert!(root.insert_next_sibling(root.clone()).is_err());
595    /// // multiple root
596    /// assert!(root.insert_next_sibling(comment.clone()).is_err());
597    /// document.append_child(root.clone()).unwrap();
598    /// root.insert_next_sibling(comment).unwrap();
599    /// assert!(root
600    ///     .next_sibling()
601    ///     .and_then(|sib| sib.as_comment())
602    ///     .is_some_and(|comment| &*comment.data() == "comment")
603    /// );
604    /// ```
605    pub fn insert_next_sibling(
606        &mut self,
607        new_sibling: impl Into<Node<dyn NodeSpec>>,
608    ) -> Result<(), XMLTreeError> {
609        self.do_insert_next_sibling(new_sibling.into())
610    }
611
612    /// Replace the subtree rooted at `self` with the subtree rooted at `src`.
613    ///
614    /// If `self` has no parent, nothing happens.  \
615    /// If `self` has a parent, the following occurs:
616    /// - [`src.detach()`](Node::detach) is executed,
617    /// - `src` is inserted as an adjacent sibling to `self`,
618    /// - and finally [`self.detach()`](Node::detach) is executed.
619    ///
620    /// # Note
621    /// `self` is never inserted into the position where `src` was.  \
622    /// `self` simply becomes a subtree without a parent.
623    pub fn replace_subtree(
624        &mut self,
625        src: impl Into<Node<dyn NodeSpec>>,
626    ) -> Result<(), XMLTreeError> {
627        let Some(parent) = self.parent_node() else {
628            return Ok(());
629        };
630
631        if let Some(mut document) = parent.as_document() {
632            if let Some(mut prev) = self.previous_sibling() {
633                self.detach()?;
634                if let Err(err) = prev.insert_next_sibling(src) {
635                    prev.insert_next_sibling(self)?;
636                    return Err(err);
637                }
638            } else if let Some(mut next) = self.next_sibling() {
639                self.detach()?;
640                if let Err(err) = next.insert_previous_sibling(src) {
641                    next.insert_previous_sibling(self)?;
642                    return Err(err);
643                }
644            } else {
645                self.detach()?;
646                if let Err(err) = document.append_child(src) {
647                    document.append_child(self)?;
648                    return Err(err);
649                }
650            }
651        } else {
652            self.insert_previous_sibling(src)?;
653            self.detach()?;
654        }
655        Ok(())
656    }
657
658    /// Check whether `self` and `other` are the same node.
659    ///
660    /// # Note
661    /// This method does not perform equality comparison.  \
662    /// For example, `is_same_node` will always return `false` for two [`Text`](crate::tree::Text)
663    /// nodes containing exactly the same string generated from the same [`Document`],
664    /// unless one is a clone of the other.
665    ///
666    /// # Example
667    /// ```rust
668    /// use anyxml::tree::Document;
669    ///
670    /// let document = Document::new();
671    /// let text1 = document.create_text("Hello").unwrap();
672    /// let text2 = document.create_text("Hello").unwrap();
673    ///
674    /// assert!(text1.is_same_node(text1.clone()));
675    /// // These have the same character data, but are not the same node.
676    /// assert!(!text1.is_same_node(text2.clone()));
677    /// ```
678    pub fn is_same_node(&self, other: impl Into<Self>) -> bool {
679        let other: Self = other.into();
680        Rc::ptr_eq(&self.core, &other.core)
681    }
682
683    /// Compare the positions of `self` and `other` in the document order.
684    ///
685    /// If `self` appears first, return `Less`;  \
686    /// if it appears later, return `Greater`;  \
687    /// if they are the same node, return `Equal`.
688    ///
689    /// If `self` and `other` do not belong to the same document tree
690    /// (i.e., they have no common ancestor), return `None`.
691    ///
692    /// # Reference
693    /// [5 Data Model in XPath 1.0](https://www.w3.org/TR/1999/REC-xpath-19991116/#dt-document-order)
694    pub fn compare_document_order(
695        &self,
696        other: impl Into<Node<dyn NodeSpec>>,
697    ) -> Option<std::cmp::Ordering> {
698        compare_document_order(self.clone(), other.into())
699    }
700
701    /// Retrieve the base URI according to the [XML Base](https://www.w3.org/TR/xmlbase/).
702    ///
703    /// If the node is embedded as a descendant of a [`Document`] node, always return `Some`.  \
704    /// If there are insufficient ancestor nodes to resolve the base URI, return `None`.
705    pub fn base_uri(&self) -> Option<URIString> {
706        let mut node = Some(self.clone());
707        let mut uris: Vec<URIString> = vec![];
708        let mut ret = None;
709        while let Some(now) = node {
710            if let Some(base) = now
711                .as_element()
712                .and_then(|elem| elem.get_attribute("base", Some(XML_XML_NAMESPACE)))
713                .and_then(|base| URIString::parse(base).ok())
714            {
715                if base.scheme().is_some() {
716                    ret = Some(
717                        uris.into_iter()
718                            .rev()
719                            .fold(base, |base, rel| base.resolve(&rel)),
720                    );
721                    break;
722                }
723                uris.push(base);
724            } else if let Some(document) = now.as_document() {
725                let base = document.document_base_uri().as_ref().to_owned();
726                ret = Some(
727                    uris.into_iter()
728                        .rev()
729                        .fold(base, |base, rel| base.resolve(&rel)),
730                );
731                break;
732            } else if let Some(entity) = now.as_entity_reference() {
733                let name = entity.name();
734                if let Some(base) = self
735                    .owner_document()
736                    .document_type()
737                    .and_then(|doctype| doctype.get_entity_decl(&name))
738                    .and_then(|decl| decl.system_id())
739                {
740                    let base = base.as_ref().to_owned();
741                    ret = Some(
742                        uris.into_iter()
743                            .rev()
744                            .fold(base, |base, rel| base.resolve(&rel)),
745                    );
746                    break;
747                }
748            }
749            node = now.parent_node().map(From::from);
750        }
751        ret.map(|uri| {
752            // The URI returned as the base URI must be an absolute URI.
753            // However, at this point, only relative references have been resolved,
754            // and a fragment may be included.
755            // The URI returned as the base URI must be an absolute URI.
756            // Therefore, resolving the relative reference without the fragment removes the fragment.
757            //
758            // Reference:
759            // [Testing XML Base Conformance](https://www.w3.org/XML/2006/12/xmlbase-testing.html)
760            // section 4. in "Discussion of few key example"
761            uri.resolve(&URIString::parse("").unwrap())
762        })
763    }
764
765    /// If `self` and its descendants contain character data, concatenate all of it
766    /// and return the result.  \
767    /// If they do not contain character data, return an empty string.
768    ///
769    /// # Note
770    /// This method is implemented based on the `textContent` property of the `Node`
771    /// interface in DOM Level 3 Core.
772    ///
773    /// Additionally, the result for [`Document`] is an empty string.
774    pub fn text_content(&self) -> String {
775        let mut buf = String::new();
776        fn collect_text_content(node: Node<dyn NodeSpec>, buf: &mut String) {
777            match node.downcast() {
778                NodeKind::Element(_)
779                | NodeKind::Attribute(_)
780                | NodeKind::EntityDecl(_)
781                | NodeKind::EntityReference(_)
782                | NodeKind::DocumentFragment(_) => {
783                    let mut children = node.first_child();
784                    while let Some(child) = children {
785                        children = child.next_sibling();
786                        // Skip comments and processing instructions
787                        // Reference: https://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/DOM3-Core.html#core-Node3-textContent
788                        if !matches!(
789                            child.node_type(),
790                            NodeType::Comment | NodeType::ProcessingInstruction
791                        ) {
792                            collect_text_content(child, buf);
793                        }
794                    }
795                }
796                NodeKind::Text(text) => {
797                    buf.push_str(&text.data());
798                }
799                NodeKind::CDATASection(cdata) => {
800                    buf.push_str(&cdata.data());
801                }
802                NodeKind::Comment(comment) => {
803                    buf.push_str(&comment.data());
804                }
805                NodeKind::ProcessingInstruction(pi) => {
806                    buf.push_str(pi.data().as_deref().unwrap_or_default());
807                }
808                _ => {}
809            }
810        }
811        collect_text_content(self.clone(), &mut buf);
812        buf
813    }
814
815    /// Create new node and copy internal data to the new node other than pointers to neighbor nodes.
816    ///
817    /// Attribute nodes and namespace nodes are cloned.
818    ///
819    /// While [`Clone::clone`] merely copies the pointer, this method copies the internal data
820    /// to new memory, creating a completely different node. Comparing the source node and
821    /// the new node using [`Node::is_same_node`] will always return `false`.
822    pub fn deep_copy(&self) -> Result<Node<dyn NodeSpec>, XMLTreeError> {
823        match self.downcast() {
824            NodeKind::AttlistDecl(node) => Ok(node.deep_copy().into()),
825            NodeKind::Attribute(_) => Err(XMLTreeError::Unsupported),
826            NodeKind::CDATASection(node) => Ok(node.deep_copy().into()),
827            NodeKind::Comment(node) => Ok(node.deep_copy().into()),
828            NodeKind::Document(node) => Ok(node.deep_copy().into()),
829            NodeKind::DocumentFragment(node) => Ok(node.deep_copy().into()),
830            NodeKind::DocumentType(node) => Ok(node.deep_copy().into()),
831            NodeKind::Element(node) => Ok(node.deep_copy()?.into()),
832            NodeKind::ElementDecl(node) => Ok(node.deep_copy().into()),
833            NodeKind::EntityDecl(node) => Ok(node.deep_copy().into()),
834            NodeKind::EntityReference(node) => Ok(node.deep_copy().into()),
835            NodeKind::Namespace(_) => Err(XMLTreeError::Unsupported),
836            NodeKind::NotationDecl(node) => Ok(node.deep_copy().into()),
837            NodeKind::ProcessingInstruction(node) => Ok(node.deep_copy().into()),
838            NodeKind::Text(node) => Ok(node.deep_copy().into()),
839        }
840    }
841
842    /// Perform a deep copy on all descendant nodes and construct a tree with the same structure.
843    ///
844    /// The link to the parent is not preserved.
845    pub fn deep_copy_subtree(&self) -> Result<Node<dyn NodeSpec>, XMLTreeError> {
846        match self.downcast() {
847            NodeKind::AttlistDecl(node) => Ok(node.deep_copy().into()),
848            NodeKind::Attribute(_) => Err(XMLTreeError::Unsupported),
849            NodeKind::CDATASection(node) => Ok(node.deep_copy().into()),
850            NodeKind::Comment(node) => Ok(node.deep_copy().into()),
851            NodeKind::Document(node) => Ok(node.deep_copy_subtree()?.into()),
852            NodeKind::DocumentFragment(node) => Ok(node.deep_copy_subtree()?.into()),
853            NodeKind::DocumentType(node) => Ok(node.deep_copy_subtree()?.into()),
854            NodeKind::Element(node) => Ok(node.deep_copy_subtree()?.into()),
855            NodeKind::ElementDecl(node) => Ok(node.deep_copy().into()),
856            NodeKind::EntityDecl(node) => Ok(node.deep_copy_subtree()?.into()),
857            NodeKind::EntityReference(node) => Ok(node.deep_copy_subtree()?.into()),
858            NodeKind::Namespace(_) => Err(XMLTreeError::Unsupported),
859            NodeKind::NotationDecl(node) => Ok(node.deep_copy().into()),
860            NodeKind::ProcessingInstruction(node) => Ok(node.deep_copy().into()),
861            NodeKind::Text(node) => Ok(node.deep_copy().into()),
862        }
863    }
864}
865
866impl Node<dyn InternalNodeSpec> {
867    /// See [Node::detach].
868    pub fn detach(&mut self) -> Result<(), XMLTreeError> {
869        Node::<dyn NodeSpec>::from(self.clone()).detach()
870    }
871
872    /// See [Node::insert_previous_sibling].
873    pub fn insert_previous_sibling(
874        &mut self,
875        new_sibling: impl Into<Node<dyn NodeSpec>>,
876    ) -> Result<(), XMLTreeError> {
877        Node::<dyn NodeSpec>::from(self.clone()).insert_previous_sibling(new_sibling)
878    }
879
880    /// See [Node::insert_next_sibling].
881    pub fn insert_next_sibling(
882        &mut self,
883        new_sibling: impl Into<Node<dyn NodeSpec>>,
884    ) -> Result<(), XMLTreeError> {
885        Node::<dyn NodeSpec>::from(self.clone()).insert_next_sibling(new_sibling)
886    }
887
888    /// See [Node::replace_subtree].
889    pub fn replace_subtree(
890        &mut self,
891        src: impl Into<Node<dyn NodeSpec>>,
892    ) -> Result<(), XMLTreeError> {
893        Node::<dyn NodeSpec>::from(self).replace_subtree(src)
894    }
895
896    fn do_append_child(&mut self, mut new_child: Node<dyn NodeSpec>) -> Result<(), XMLTreeError> {
897        if let Some(mut last_child) = self.last_child() {
898            last_child.insert_next_sibling(new_child)?;
899        } else {
900            if let Some(mut frag) = new_child.as_document_fragment() {
901                let Some(mut child) = frag.first_child() else {
902                    return Ok(());
903                };
904
905                self.append_child(child.clone())?;
906                return match self.append_child(frag.clone()) {
907                    Ok(()) => Ok(()),
908                    Err(err) => {
909                        child.detach()?;
910                        if let Some(mut first) = frag.first_child() {
911                            first.insert_previous_sibling(child)?;
912                        } else {
913                            frag.append_child(child)?;
914                        }
915                        return Err(err);
916                    }
917                };
918            }
919            Node::<dyn NodeSpec>::from(self.clone()).pre_insertion_common_check(&new_child)?;
920            self.pre_child_insertion(new_child.clone(), None)?;
921            new_child.detach()?;
922            new_child.set_paretn_node(self.clone());
923            self.set_first_child(new_child.clone());
924            self.set_last_child(new_child.clone());
925            self.post_child_insertion(new_child);
926        }
927        Ok(())
928    }
929
930    /// Insert `new_child` as a last child of `self`.
931    ///
932    /// Insertions that violate tree constraints (such as those that create cyclic references)
933    /// are errors.  \
934    /// Additionally, operations that generate expressions impossible in well-formed XML documents
935    /// (such as placing Text outside document elements or inserting declarations into element
936    /// content) are also errors.
937    pub fn append_child(
938        &mut self,
939        new_child: impl Into<Node<dyn NodeSpec>>,
940    ) -> Result<(), XMLTreeError> {
941        self.do_append_child(new_child.into())
942    }
943
944    fn pre_child_removal(&mut self, removed_child: Node<dyn NodeSpec>) -> Result<(), XMLTreeError> {
945        self.core.borrow_mut().spec.pre_child_removal(removed_child)
946    }
947
948    fn pre_child_insertion(
949        &self,
950        inserted_child: Node<dyn NodeSpec>,
951        preceding_node: Option<Node<dyn NodeSpec>>,
952    ) -> Result<(), XMLTreeError> {
953        self.core
954            .borrow()
955            .spec
956            .pre_child_insertion(inserted_child, preceding_node)
957    }
958
959    fn post_child_insertion(&mut self, inserted_child: Node<dyn NodeSpec>) {
960        self.core
961            .borrow_mut()
962            .spec
963            .post_child_insertion(inserted_child);
964    }
965
966    /// Check whether `self` and `other` are the same node.
967    ///
968    /// For more details, please refer [`Node::is_same_node`] of [`Node<dyn NodeSpec>`]
969    pub fn is_same_node(&self, other: impl Into<Node<dyn NodeSpec>>) -> bool {
970        let left = Node::<dyn NodeSpec>::from(self);
971        let right: Node<dyn NodeSpec> = other.into();
972        Rc::ptr_eq(&left.core, &right.core)
973    }
974
975    /// Compare the positions of `self` and `other` in the document order.
976    ///
977    /// For more details, please refer [`Node::compare_document_order`] of [`Node<dyn NodeSpec>`].
978    pub fn compare_document_order(
979        &self,
980        other: impl Into<Node<dyn NodeSpec>>,
981    ) -> Option<std::cmp::Ordering> {
982        compare_document_order(self.into(), other.into())
983    }
984
985    /// Retrieve the base URI according to the [XML Base](https://www.w3.org/TR/xmlbase/).
986    ///
987    /// For more details, please refer to [Node::base_uri].
988    pub fn base_uri(&self) -> Option<URIString> {
989        Node::<dyn NodeSpec>::from(self).base_uri()
990    }
991
992    /// Please see [Node::text_content].
993    pub fn text_content(&self) -> String {
994        Node::<dyn NodeSpec>::from(self).text_content()
995    }
996
997    /// Please see [Node::deep_copy].
998    pub fn deep_copy(&self) -> Result<Node<dyn NodeSpec>, XMLTreeError> {
999        Node::<dyn NodeSpec>::from(self).deep_copy()
1000    }
1001
1002    /// Please see [Node::deep_copy_subtree].
1003    pub fn deep_copy_subtree(&self) -> Result<Node<dyn NodeSpec>, XMLTreeError> {
1004        Node::<dyn NodeSpec>::from(self).deep_copy_subtree()
1005    }
1006}
1007
1008impl<Spec: NodeSpec + 'static> Node<Spec> {
1009    pub(crate) fn create_node(spec: Spec, owner_document: Document) -> Self {
1010        let weak: Weak<RefCell<NodeCore<DocumentFragmentSpec>>> = Weak::new();
1011        Node {
1012            core: Rc::new(RefCell::new(NodeCore {
1013                parent_node: weak.clone(),
1014                previous_sibling: weak,
1015                next_sibling: None,
1016                line: 0,
1017                column: 0,
1018                spec,
1019            })),
1020            owner_document: owner_document.owner_document.clone(),
1021        }
1022    }
1023
1024    /// See [Node::detach].
1025    pub fn detach(&mut self) -> Result<(), XMLTreeError> {
1026        Node::<dyn NodeSpec>::from(self).detach()
1027    }
1028
1029    /// See [Node::insert_previous_sibling].
1030    pub fn insert_previous_sibling(
1031        &mut self,
1032        new_sibling: impl Into<Node<dyn NodeSpec>>,
1033    ) -> Result<(), XMLTreeError> {
1034        Node::<dyn NodeSpec>::from(self).insert_previous_sibling(new_sibling)
1035    }
1036
1037    /// See [Node::insert_next_sibling].
1038    pub fn insert_next_sibling(
1039        &mut self,
1040        new_sibling: impl Into<Node<dyn NodeSpec>>,
1041    ) -> Result<(), XMLTreeError> {
1042        Node::<dyn NodeSpec>::from(self).insert_next_sibling(new_sibling)
1043    }
1044
1045    /// See [Node::replace_subtree].
1046    pub fn replace_subtree(
1047        &mut self,
1048        src: impl Into<Node<dyn NodeSpec>>,
1049    ) -> Result<(), XMLTreeError> {
1050        Node::<dyn NodeSpec>::from(self).replace_subtree(src)
1051    }
1052
1053    /// Check whether `self` and `other` are the same node.
1054    ///
1055    /// For more details, please refer [`Node::is_same_node`] of [`Node<dyn NodeSpec>`]
1056    pub fn is_same_node(&self, other: impl Into<Node<dyn NodeSpec>>) -> bool {
1057        let left = Node::<dyn NodeSpec>::from(self);
1058        let right: Node<dyn NodeSpec> = other.into();
1059        Rc::ptr_eq(&left.core, &right.core)
1060    }
1061
1062    /// Compare the positions of `self` and `other` in the document order.
1063    ///
1064    /// For more details, please refer [`Node::compare_document_order`] of [`Node<dyn NodeSpec>`].
1065    pub fn compare_document_order(
1066        &self,
1067        other: impl Into<Node<dyn NodeSpec>>,
1068    ) -> Option<std::cmp::Ordering> {
1069        compare_document_order(self.into(), other.into())
1070    }
1071
1072    /// Retrieve the base URI according to the [XML Base](https://www.w3.org/TR/xmlbase/).
1073    ///
1074    /// For more details, please refer to [Node::base_uri].
1075    pub fn base_uri(&self) -> Option<URIString> {
1076        Node::<dyn NodeSpec>::from(self).base_uri()
1077    }
1078
1079    /// Please see [Node::text_content].
1080    pub fn text_content(&self) -> String {
1081        Node::<dyn NodeSpec>::from(self).text_content()
1082    }
1083}
1084
1085impl<Spec: InternalNodeSpec + ?Sized> Node<Spec> {
1086    fn set_first_child(&mut self, new: Node<dyn NodeSpec>) {
1087        self.core
1088            .borrow_mut()
1089            .spec
1090            .set_first_child(new.core.clone());
1091    }
1092    fn unset_first_child(&mut self) {
1093        self.core.borrow_mut().spec.unset_first_child();
1094    }
1095
1096    fn set_last_child(&mut self, new: Node<dyn NodeSpec>) {
1097        self.core.borrow_mut().spec.set_last_child(new.core.clone());
1098    }
1099    fn unset_last_child(&mut self) {
1100        self.core.borrow_mut().spec.unset_last_child();
1101    }
1102}
1103
1104impl<Spec: InternalNodeSpec + 'static> Node<Spec> {
1105    /// See [Node::append_child].
1106    pub fn append_child(
1107        &mut self,
1108        new_child: impl Into<Node<dyn NodeSpec>>,
1109    ) -> Result<(), XMLTreeError> {
1110        Node::<dyn InternalNodeSpec>::from(self.clone()).append_child(new_child)
1111    }
1112}
1113
1114impl<Spec: ?Sized> Clone for Node<Spec> {
1115    fn clone(&self) -> Self {
1116        Self {
1117            core: self.core.clone(),
1118            owner_document: self.owner_document.clone(),
1119        }
1120    }
1121}
1122
1123impl From<&Node<dyn NodeSpec>> for Node<dyn NodeSpec> {
1124    fn from(value: &Node<dyn NodeSpec>) -> Self {
1125        value.clone()
1126    }
1127}
1128
1129impl From<&mut Node<dyn NodeSpec>> for Node<dyn NodeSpec> {
1130    fn from(value: &mut Node<dyn NodeSpec>) -> Self {
1131        value.clone()
1132    }
1133}
1134
1135impl<Spec: NodeSpec + 'static> From<Node<Spec>> for Node<dyn NodeSpec> {
1136    fn from(value: Node<Spec>) -> Self {
1137        Node {
1138            core: value.core,
1139            owner_document: value.owner_document,
1140        }
1141    }
1142}
1143
1144impl<Spec: NodeSpec + 'static> From<&Node<Spec>> for Node<dyn NodeSpec> {
1145    fn from(value: &Node<Spec>) -> Self {
1146        value.clone().into()
1147    }
1148}
1149
1150impl<Spec: NodeSpec + 'static> From<&mut Node<Spec>> for Node<dyn NodeSpec> {
1151    fn from(value: &mut Node<Spec>) -> Self {
1152        value.clone().into()
1153    }
1154}
1155
1156impl From<Node<dyn InternalNodeSpec>> for Node<dyn NodeSpec> {
1157    fn from(value: Node<dyn InternalNodeSpec>) -> Self {
1158        Node {
1159            core: value.core,
1160            owner_document: value.owner_document,
1161        }
1162    }
1163}
1164
1165impl From<&Node<dyn InternalNodeSpec>> for Node<dyn NodeSpec> {
1166    fn from(value: &Node<dyn InternalNodeSpec>) -> Self {
1167        value.clone().into()
1168    }
1169}
1170
1171impl From<&mut Node<dyn InternalNodeSpec>> for Node<dyn NodeSpec> {
1172    fn from(value: &mut Node<dyn InternalNodeSpec>) -> Self {
1173        value.clone().into()
1174    }
1175}
1176
1177impl<Spec: InternalNodeSpec + 'static> From<Node<Spec>> for Node<dyn InternalNodeSpec> {
1178    fn from(value: Node<Spec>) -> Self {
1179        Node {
1180            core: value.core,
1181            owner_document: value.owner_document,
1182        }
1183    }
1184}
1185
1186impl<Spec: InternalNodeSpec + 'static> From<&Node<Spec>> for Node<dyn InternalNodeSpec> {
1187    fn from(value: &Node<Spec>) -> Self {
1188        value.clone().into()
1189    }
1190}
1191
1192impl<Spec: InternalNodeSpec + 'static> From<&mut Node<Spec>> for Node<dyn InternalNodeSpec> {
1193    fn from(value: &mut Node<Spec>) -> Self {
1194        value.clone().into()
1195    }
1196}
1197
1198impl std::fmt::Display for Node<dyn NodeSpec> {
1199    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1200        match self.downcast() {
1201            NodeKind::AttlistDecl(attlist) => write!(f, "{}", attlist),
1202            NodeKind::Attribute(attribute) => write!(f, "{}", attribute),
1203            NodeKind::CDATASection(cdata) => write!(f, "{}", cdata),
1204            NodeKind::Comment(comment) => write!(f, "{}", comment),
1205            NodeKind::Document(document) => write!(f, "{}", document),
1206            NodeKind::DocumentFragment(frag) => write!(f, "{}", frag),
1207            NodeKind::DocumentType(doctype) => write!(f, "{}", doctype),
1208            NodeKind::Element(element) => write!(f, "{}", element),
1209            NodeKind::ElementDecl(element) => write!(f, "{}", element),
1210            NodeKind::EntityDecl(entity) => write!(f, "{}", entity),
1211            NodeKind::EntityReference(entref) => write!(f, "{}", entref),
1212            NodeKind::Namespace(namespace) => write!(f, "{}", namespace),
1213            NodeKind::NotationDecl(notation) => write!(f, "{}", notation),
1214            NodeKind::ProcessingInstruction(pi) => write!(f, "{}", pi),
1215            NodeKind::Text(text) => write!(f, "{}", text),
1216        }
1217    }
1218}
1219
1220impl std::fmt::Display for Node<dyn InternalNodeSpec> {
1221    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1222        write!(f, "{}", Node::<dyn NodeSpec>::from(self.clone()))
1223    }
1224}
1225
1226pub(super) fn drop_tree_non_recursive(root: Rc<RefCell<NodeCore<dyn NodeSpec>>>) {
1227    let mut children = root.borrow().spec.first_child();
1228    while let Some(child) = children {
1229        if let Some(first) = child.borrow().spec.first_child() {
1230            children = Some(first);
1231        } else if let Some(next) = child.borrow_mut().next_sibling.take() {
1232            children = Some(next);
1233        } else {
1234            children = None;
1235            let mut parent = child.borrow().parent_node.upgrade();
1236            while let Some(par) = parent {
1237                par.borrow_mut().spec.unset_first_child();
1238                par.borrow_mut().spec.unset_last_child();
1239                let par = par as _;
1240                if Rc::ptr_eq(&root, &par) {
1241                    break;
1242                }
1243                if let Some(next) = par.borrow_mut().next_sibling.take() {
1244                    children = Some(next);
1245                }
1246                parent = par.borrow().parent_node.upgrade();
1247            }
1248        }
1249    }
1250}
1251
1252#[cfg(test)]
1253mod tests {
1254    use crate::{sax::XMLReader, tree::TreeBuildHandler};
1255
1256    use super::*;
1257
1258    #[test]
1259    fn cyclic_reference_tests() {
1260        let mut document = Document::new();
1261        let mut elem = document.create_element("elem", None).unwrap();
1262        let mut elem2 = document.create_element("elem2", None).unwrap();
1263        elem.append_child(elem2.clone()).unwrap();
1264        document.append_child(elem.clone()).unwrap();
1265
1266        assert!(
1267            elem2
1268                .append_child(elem.clone())
1269                .is_err_and(|err| matches!(err, XMLTreeError::CyclicReference))
1270        );
1271        assert!(
1272            elem.insert_previous_sibling(elem.clone())
1273                .is_err_and(|err| matches!(err, XMLTreeError::CyclicReference))
1274        );
1275        assert!(
1276            elem.append_child(elem.clone())
1277                .is_err_and(|err| matches!(err, XMLTreeError::CyclicReference))
1278        );
1279        assert!(
1280            elem.insert_next_sibling(elem.clone())
1281                .is_err_and(|err| matches!(err, XMLTreeError::CyclicReference))
1282        );
1283        assert!(
1284            elem2
1285                .append_child(elem2.clone())
1286                .is_err_and(|err| matches!(err, XMLTreeError::CyclicReference))
1287        );
1288        assert!(
1289            elem2
1290                .insert_previous_sibling(elem2.clone())
1291                .is_err_and(|err| matches!(err, XMLTreeError::CyclicReference))
1292        );
1293        assert!(
1294            elem2
1295                .insert_next_sibling(elem2.clone())
1296                .is_err_and(|err| matches!(err, XMLTreeError::CyclicReference))
1297        );
1298    }
1299
1300    #[test]
1301    fn document_order_comparison_tests() {
1302        let mut parser = XMLReader::builder()
1303            .set_handler(TreeBuildHandler::default())
1304            .build();
1305
1306        const CASE: &str = r#"<?xml version="1.0"?>
1307        <!DOCTYPE root [
1308            <!ELEMENT root   ANY>
1309            <!ATTLIST root   foo   CDATA #IMPLIED>
1310            <!ELEMENT child  ANY>
1311            <!ATTLIST child  bar   CDATA #IMPLIED
1312                             xmlns CDATA #FIXED "http://example.com/pre"
1313                             hoge  CDATA #IMPLIED>
1314            <!ELEMENT child2 ANY>
1315            <!ATTLIST child2 xmlns CDATA #FIXED "">
1316            <!ELEMENT child3 ANY>
1317            <!ENTITY  ent "in entity reference">
1318        ]>
1319        <!-- before document element -->
1320        <?pi before document element?>
1321        <root foo="foo">
1322            child of 'foo'
1323            <?pi in document element1?>
1324            <!-- in document element1 -->
1325            <child bar="bar" xmlns="http://example.com/pre" hoge="hoge">
1326                child of 'child'
1327                <child2 xmlns=""/>
1328                <![CDATA[child of 'child2']]>
1329                &ent;
1330                <?pi in document element2?>
1331                <!-- in document element2 -->
1332                <child3 xml:lang="ch" />
1333            </child>
1334        </root>
1335        <?pi after document element?>
1336        <!-- after document element -->"#;
1337
1338        parser.parse_str(CASE, None).unwrap();
1339        assert!(!parser.handler.fatal_error);
1340        let document = parser.handler.document;
1341        let mut children = Some(Node::<dyn NodeSpec>::from(document.clone()));
1342        while let Some(now) = children {
1343            let mut others = Some(Node::<dyn NodeSpec>::from(document.clone()));
1344            let mut pre = true;
1345            while let Some(other) = others {
1346                if now.is_same_node(other.clone()) {
1347                    assert!(now.compare_document_order(other.clone()).unwrap().is_eq());
1348                    pre = false;
1349                    if let Some(element) = now.as_element() {
1350                        for att in element.attributes() {
1351                            assert!(att.compare_document_order(other.clone()).unwrap().is_gt());
1352                            assert!(now.compare_document_order(att).unwrap().is_lt());
1353                        }
1354                    }
1355                } else {
1356                    assert_eq!(
1357                        pre,
1358                        now.compare_document_order(other.clone()).unwrap().is_gt()
1359                    );
1360                    if let Some(element) = now.as_element() {
1361                        for att in element.attributes() {
1362                            assert_eq!(
1363                                pre,
1364                                att.compare_document_order(other.clone()).unwrap().is_gt()
1365                            );
1366                        }
1367                    }
1368                    if let Some(element) = other.as_element() {
1369                        for att in element.attributes() {
1370                            assert_eq!(pre, now.compare_document_order(att).unwrap().is_gt());
1371                        }
1372                    }
1373                }
1374
1375                if let Some(first) = other.first_child() {
1376                    others = Some(first);
1377                } else if let Some(next) = other.next_sibling() {
1378                    others = Some(next);
1379                } else {
1380                    others = None;
1381                    let mut parent = other.parent_node();
1382                    while let Some(now) = parent {
1383                        if let Some(next) = now.next_sibling() {
1384                            others = Some(next);
1385                            break;
1386                        }
1387                        parent = now.parent_node();
1388                    }
1389                }
1390            }
1391
1392            if let Some(first) = now.first_child() {
1393                children = Some(first);
1394            } else if let Some(next) = now.next_sibling() {
1395                children = Some(next);
1396            } else {
1397                children = None;
1398                let mut parent = now.parent_node();
1399                while let Some(now) = parent {
1400                    if let Some(next) = now.next_sibling() {
1401                        children = Some(next);
1402                        break;
1403                    }
1404                    parent = now.parent_node();
1405                }
1406            }
1407        }
1408    }
1409
1410    #[test]
1411    fn base_uri_tests() {
1412        // Testing XML Base Conformance
1413        // https://www.w3.org/XML/2006/12/xmlbase-testing.html
1414
1415        const CASES: &[&str] = &[
1416            r#"<elt xml:base="http://www.example.org/~Dürst/"/>"#,
1417            r#"<outer xml:base="http://www.example.org/one/two"> <inner xml:base=""/> </outer>"#,
1418            r#"<elt xml:base="http://www.example.org/one/two#frag"/>"#,
1419            r##"<outer xml:base="http://www.example.org/one/two"> <inner xml:base="#frag"/> </outer>"##,
1420        ];
1421        const TARGETS: &[&str] = &["elt", "inner", "elt", "inner"];
1422        const EXPECTED: &[&str] = &[
1423            "http://www.example.org/~Dürst/",
1424            "http://www.example.org/one/two",
1425            "http://www.example.org/one/two",
1426            "http://www.example.org/one/two",
1427        ];
1428
1429        let mut parser = XMLReader::builder()
1430            .set_handler(TreeBuildHandler::default())
1431            .build();
1432        for (i, &case) in CASES.iter().enumerate() {
1433            parser.parse_str(case, None).unwrap();
1434            let document = parser.handler.document.clone();
1435            for elem in document.get_elements_by_qname(TARGETS[i]) {
1436                assert_eq!(
1437                    elem.base_uri().unwrap().as_unescaped_str().unwrap(),
1438                    EXPECTED[i]
1439                );
1440            }
1441        }
1442    }
1443
1444    #[test]
1445    fn text_conent_tests() {
1446        const XML: &str =
1447            r#"<doc att="att"><?pi data="pi"?><!--comment-->text<![CDATA[cdata]]></doc>"#;
1448        let mut parser = XMLReader::builder()
1449            .set_handler(TreeBuildHandler::default())
1450            .build();
1451        parser.handler.coalescing = false;
1452        parser.handler.ignoring_comments = false;
1453
1454        parser.parse_str(XML, None).unwrap();
1455        assert!(!parser.handler.fatal_error);
1456        let doc = parser.handler.document;
1457        assert_eq!(doc.text_content(), "");
1458        let elem = doc.document_element().unwrap();
1459        assert_eq!(elem.text_content(), "textcdata");
1460        let att = elem.get_attribute_node("att", None).unwrap();
1461        assert_eq!(att.text_content(), "att");
1462        let pi = elem.first_child().unwrap();
1463        assert_eq!(pi.text_content(), "data=\"pi\"");
1464        let comment = pi.next_sibling().unwrap();
1465        assert_eq!(comment.text_content(), "comment");
1466        let text = comment.next_sibling().unwrap();
1467        assert_eq!(text.text_content(), "text");
1468        let cdata = text.next_sibling().unwrap();
1469        assert_eq!(cdata.text_content(), "cdata");
1470    }
1471}