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
17pub trait NodeSpec: std::any::Any {
21 fn node_type(&self) -> NodeType;
26 fn first_child(&self) -> Option<Rc<RefCell<NodeCore<dyn NodeSpec>>>>;
28 fn last_child(&self) -> Option<Rc<RefCell<NodeCore<dyn NodeSpec>>>>;
30}
31
32pub trait InternalNodeSpec: NodeSpec {
36 fn set_first_child(&mut self, new: Rc<RefCell<NodeCore<dyn NodeSpec>>>);
38 fn unset_first_child(&mut self);
40
41 fn set_last_child(&mut self, new: Rc<RefCell<NodeCore<dyn NodeSpec>>>);
43 fn unset_last_child(&mut self);
45
46 fn pre_child_removal(&mut self, removed_child: Node<dyn NodeSpec>) -> Result<(), XMLTreeError> {
48 let _ = removed_child;
49 Ok(())
50 }
51
52 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 fn post_child_insertion(&mut self, inserted_child: Node<dyn NodeSpec>) {
74 let _ = inserted_child;
75 }
76}
77
78pub 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
88pub 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 pub fn node_type(&self) -> NodeType {
107 self.core.borrow().spec.node_type()
108 }
109
110 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 uri.resolve(&URIString::parse("").unwrap())
762 })
763 }
764
765 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 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 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 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 pub fn detach(&mut self) -> Result<(), XMLTreeError> {
869 Node::<dyn NodeSpec>::from(self.clone()).detach()
870 }
871
872 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 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 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 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 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 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 pub fn base_uri(&self) -> Option<URIString> {
989 Node::<dyn NodeSpec>::from(self).base_uri()
990 }
991
992 pub fn text_content(&self) -> String {
994 Node::<dyn NodeSpec>::from(self).text_content()
995 }
996
997 pub fn deep_copy(&self) -> Result<Node<dyn NodeSpec>, XMLTreeError> {
999 Node::<dyn NodeSpec>::from(self).deep_copy()
1000 }
1001
1002 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 pub fn detach(&mut self) -> Result<(), XMLTreeError> {
1026 Node::<dyn NodeSpec>::from(self).detach()
1027 }
1028
1029 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 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 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 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 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 pub fn base_uri(&self) -> Option<URIString> {
1076 Node::<dyn NodeSpec>::from(self).base_uri()
1077 }
1078
1079 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 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 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}