xml_doc/
element.rs

1use crate::document::{Document, Node};
2use crate::error::{Error, Result};
3use std::collections::HashMap;
4
5#[derive(Debug)]
6pub(crate) struct ElementData {
7    full_name: String,
8    attributes: HashMap<String, String>, // q:attr="val" => {"q:attr": "val"}
9    namespace_decls: HashMap<String, String>, // local namespace newly defined in attributes
10    parent: Option<Element>,
11    children: Vec<Node>,
12}
13
14/// An easy way to build a new element
15/// by chaining methods to add properties.
16///
17/// Call [`Element::build()`] to start building.
18/// To finish building, either call `.finish()` or `.push_to(parent)`
19/// which returns [`Element`].
20///
21/// # Examples
22///
23/// ```
24/// use xml_doc::{Document, Element, Node};
25///
26/// let mut doc = Document::new();
27///
28/// let root = Element::build(&mut doc, "root")
29///     .attribute("id", "main")
30///     .attribute("class", "main")
31///     .finish();
32/// doc.push_root_node(root.as_node());
33///
34/// let name = Element::build(&mut doc, "name")
35///     .text_content("No Name")
36///     .push_to(root);
37///
38/// /* Equivalent xml:
39///   <root id="main" class="main">
40///     <name>No Name</name>
41///   </root>
42/// */
43/// ```
44///
45pub struct ElementBuilder<'a> {
46    element: Element,
47    doc: &'a mut Document,
48}
49
50impl<'a> ElementBuilder<'a> {
51    fn new(element: Element, doc: &'a mut Document) -> ElementBuilder<'a> {
52        ElementBuilder { element, doc }
53    }
54
55    /// Removes previous prefix if it exists, and attach new prefix.
56    pub fn prefix<S: Into<String>>(self, prefix: S) -> Self {
57        self.element.set_prefix(self.doc, prefix);
58        self
59    }
60
61    pub fn attribute<S, T>(self, name: S, value: T) -> Self
62    where
63        S: Into<String>,
64        T: Into<String>,
65    {
66        self.element.set_attribute(self.doc, name, value);
67        self
68    }
69
70    pub fn namespace_decl<S, T>(self, prefix: S, namespace: T) -> Self
71    where
72        S: Into<String>,
73        T: Into<String>,
74    {
75        self.element.set_namespace_decl(self.doc, prefix, namespace);
76        self
77    }
78
79    pub fn text_content<S: Into<String>>(self, text: S) -> Self {
80        self.element.set_text_content(self.doc, text);
81        self
82    }
83
84    pub fn finish(self) -> Element {
85        self.element
86    }
87
88    /// Push this element to the parent's children.
89    pub fn push_to(self, parent: Element) -> Element {
90        self.element.push_to(self.doc, parent).unwrap();
91        self.element
92    }
93}
94
95/// Represents an XML element. It acts as a pointer to actual element data stored in Document.
96///
97/// This struct only contains a unique `usize` id and implements trait `Copy`.
98/// So you do not need to bother with having a reference.
99///
100/// Because the actual data of the element is stored in [`Document`],
101/// most methods takes `&Document` or `&mut Document` as its first argument.
102///
103/// Note that an element may only interact with elements of the same document,
104/// but the crate doesn't know which document an element is from.
105/// Trying to push an element from a different Document may result in unexpected errors.
106///
107/// # Examples
108///
109/// Find children nodes with attribute
110/// ```
111/// use xml_doc::{Document, Element};
112///
113/// let doc = Document::parse_str(r#"<?xml version="1.0"?>
114/// <data>
115///   <item class="value">a</item>
116///   <item class="value">b</item>
117///   <item></item>
118/// </data>
119/// "#).unwrap();
120///
121/// let data = doc.root_element().unwrap();
122/// let value_items: Vec<Element> = data.children(&doc)
123///     .iter()
124///     .filter_map(|node| node.as_element())
125///     .filter(|elem| elem.attribute(&doc, "class") == Some("value"))
126///     .collect();
127/// ```
128///
129#[derive(Debug, Clone, Copy, PartialEq, Eq)]
130pub struct Element {
131    id: usize,
132}
133
134impl Element {
135    /// Create a new empty element with `full_name`.
136    ///
137    /// If full_name contains `:`,
138    /// everything before that will be interpreted as a namespace prefix.
139    pub fn new<S: Into<String>>(doc: &mut Document, full_name: S) -> Self {
140        Self::with_data(doc, full_name.into(), HashMap::new(), HashMap::new())
141    }
142
143    /// Chain methods to build an element easily.
144    /// The chain can be finished with `.finish()` or `.push_to(parent)`.
145    ///
146    /// # Example
147    /// ```
148    /// use xml_doc::{Document, Element, Node};
149    ///
150    /// let mut doc = Document::new();
151    ///
152    /// let elem = Element::build(&mut doc, "root")
153    ///     .attribute("id", "main")
154    ///     .attribute("class", "main")
155    ///     .finish();
156    ///
157    /// doc.push_root_node(elem.as_node());
158    /// ```
159    pub fn build<S: Into<String>>(doc: &mut Document, name: S) -> ElementBuilder {
160        let element = Self::new(doc, name);
161        ElementBuilder::new(element, doc)
162    }
163
164    pub(crate) fn with_data(
165        doc: &mut Document,
166        full_name: String,
167        attributes: HashMap<String, String>,
168        namespace_decls: HashMap<String, String>,
169    ) -> Element {
170        let elem = Element { id: doc.counter };
171        let elem_data = ElementData {
172            full_name,
173            attributes,
174            namespace_decls,
175            parent: None,
176            children: vec![],
177        };
178        doc.store.push(elem_data);
179        doc.counter += 1;
180        elem
181    }
182
183    /// Create a container Element
184    pub(crate) fn container() -> (Element, ElementData) {
185        let elem_data = ElementData {
186            full_name: String::new(),
187            attributes: HashMap::new(),
188            namespace_decls: HashMap::new(),
189            parent: None,
190            children: Vec::new(),
191        };
192        let elem = Element { id: 0 };
193        (elem, elem_data)
194    }
195
196    /// Returns `true` if element is a container.
197    ///
198    /// See [`Document::container()`] for more information on 'container'.
199    pub fn is_container(&self) -> bool {
200        self.id == 0
201    }
202
203    /// Equivalent to `Node::Element(self)`
204    pub fn as_node(&self) -> Node {
205        Node::Element(*self)
206    }
207
208    /// Seperate full_name by `:`, returning (prefix, name).
209    ///
210    /// The first str is `""` if `full_name` has no prefix.
211    pub fn separate_prefix_name(full_name: &str) -> (&str, &str) {
212        match full_name.split_once(":") {
213            Some((prefix, name)) => (prefix, name),
214            None => ("", full_name),
215        }
216    }
217}
218
219/// Below are methods that take `&Document` as its first argument.
220impl Element {
221    fn data<'a>(&self, doc: &'a Document) -> &'a ElementData {
222        doc.store.get(self.id).unwrap()
223    }
224
225    fn mut_data<'a>(&self, doc: &'a mut Document) -> &'a mut ElementData {
226        doc.store.get_mut(self.id).unwrap()
227    }
228
229    /// Returns true if this element is the root node of document.
230    ///
231    /// Note that this crate allows Document to have multiple elements, even though it's not valid xml.
232    pub fn is_root(&self, doc: &Document) -> bool {
233        self.parent(doc).map_or(false, |p| p.is_container())
234    }
235
236    /// Get full name of element, including its namespace prefix.
237    /// Use [`Element::name()`] to get its name without the prefix.
238    pub fn full_name<'a>(&self, doc: &'a Document) -> &'a str {
239        &self.data(doc).full_name
240    }
241
242    pub fn set_full_name<S: Into<String>>(&self, doc: &mut Document, name: S) {
243        self.mut_data(doc).full_name = name.into();
244    }
245
246    /// Get prefix and name of element. If it doesn't have prefix, will return an empty string.
247    ///
248    /// `<prefix: name` -> `("prefix", "name")`
249    pub fn prefix_name<'a>(&self, doc: &'a Document) -> (&'a str, &'a str) {
250        Self::separate_prefix_name(self.full_name(doc))
251    }
252
253    /// Get namespace prefix of element, without name.
254    ///
255    /// `<prefix:name>` -> `"prefix"`
256    pub fn prefix<'a>(&self, doc: &'a Document) -> &'a str {
257        self.prefix_name(doc).0
258    }
259
260    /// Set prefix of element, preserving its name.
261    ///
262    /// `prefix` should not have a `:`,
263    /// or everything after `:` will be interpreted as part of element name.    
264    ///
265    /// If prefix is an empty string, removes prefix.
266    pub fn set_prefix<S: Into<String>>(&self, doc: &mut Document, prefix: S) {
267        let data = self.mut_data(doc);
268        let (_, name) = Self::separate_prefix_name(&data.full_name);
269        let prefix: String = prefix.into();
270        if prefix.is_empty() {
271            data.full_name = name.to_string();
272        } else {
273            data.full_name = format!("{}:{}", prefix, name);
274        }
275    }
276
277    /// Get name of element, without its namespace prefix.
278    /// Use `Element::full_name()` to get its full name with prefix.
279    ///
280    /// `<prefix:name>` -> `"name"`
281    pub fn name<'a>(&self, doc: &'a Document) -> &'a str {
282        self.prefix_name(doc).1
283    }
284
285    /// Set name of element, preserving its prefix.
286    ///
287    /// `name` should not have a `:`,
288    /// or everything before `:` may be interpreted as namespace prefix.
289    pub fn set_name<S: Into<String>>(&self, doc: &mut Document, name: S) {
290        let data = self.mut_data(doc);
291        let (prefix, _) = Self::separate_prefix_name(&data.full_name);
292        if prefix.is_empty() {
293            data.full_name = name.into();
294        } else {
295            data.full_name = format!("{}:{}", prefix, name.into());
296        }
297    }
298
299    /// Get attributes of element.
300    ///
301    /// The attribute names may have namespace prefix. To strip the prefix and only its name, call [`Element::separate_prefix_name`].
302    /// ```
303    /// use xml_doc::{Document, Element};
304    ///
305    /// let mut doc = Document::new();
306    /// let element = Element::build(&mut doc, "name")
307    ///     .attribute("id", "name")
308    ///     .attribute("pre:name", "value")
309    ///     .finish();
310    ///
311    /// let attrs = element.attributes(&doc);
312    /// for (full_name, value) in attrs {
313    ///     let (prefix, name) = Element::separate_prefix_name(full_name);
314    ///     // ("", "id"), ("pre", "name")
315    /// }
316    /// ```
317    pub fn attributes<'a>(&self, doc: &'a Document) -> &'a HashMap<String, String> {
318        &self.data(doc).attributes
319    }
320
321    /// Get attribute value of an element by its full name. (Namespace prefix isn't stripped)
322    pub fn attribute<'a>(&self, doc: &'a Document, name: &str) -> Option<&'a str> {
323        self.attributes(doc).get(name).map(|v| v.as_str())
324    }
325
326    /// Add or set attribute.
327    ///
328    /// If `name` contains a `:`,
329    /// everything before `:` will be interpreted as namespace prefix.
330    pub fn set_attribute<S, T>(&self, doc: &mut Document, name: S, value: T)
331    where
332        S: Into<String>,
333        T: Into<String>,
334    {
335        self.mut_attributes(doc).insert(name.into(), value.into());
336    }
337
338    pub fn mut_attributes<'a>(&self, doc: &'a mut Document) -> &'a mut HashMap<String, String> {
339        &mut self.mut_data(doc).attributes
340    }
341
342    /// Gets the namespace of this element.
343    ///
344    /// Shorthand for `self.namespace_for_prefix(doc, self.prefix(doc))`.
345    pub fn namespace<'a>(&self, doc: &'a Document) -> Option<&'a str> {
346        self.namespace_for_prefix(doc, self.prefix(doc))
347    }
348
349    /// Gets HashMap of `xmlns:prefix=namespace` declared in this element's attributes.
350    ///
351    /// Default namespace has empty string as key.
352    pub fn namespace_decls<'a>(&self, doc: &'a Document) -> &'a HashMap<String, String> {
353        &self.data(doc).namespace_decls
354    }
355
356    pub fn mut_namespace_decls<'a>(
357        &self,
358        doc: &'a mut Document,
359    ) -> &'a mut HashMap<String, String> {
360        &mut self.mut_data(doc).namespace_decls
361    }
362
363    pub fn set_namespace_decl<S, T>(&self, doc: &mut Document, prefix: S, namespace: T)
364    where
365        S: Into<String>,
366        T: Into<String>,
367    {
368        self.mut_namespace_decls(doc)
369            .insert(prefix.into(), namespace.into());
370    }
371
372    /// Get namespace value given prefix, for this element.
373    /// "xml" and "xmlns" returns its default namespace.
374    pub fn namespace_for_prefix<'a>(&self, doc: &'a Document, prefix: &str) -> Option<&'a str> {
375        match prefix {
376            "xml" => return Some("http://www.w3.org/XML/1998/namespace"),
377            "xmlns" => return Some("http://www.w3.org/2000/xmlns/"),
378            _ => (),
379        };
380        let mut elem = *self;
381        loop {
382            let data = elem.data(doc);
383            if let Some(value) = data.namespace_decls.get(prefix) {
384                return Some(value);
385            }
386            elem = elem.parent(doc)?;
387        }
388    }
389
390    pub(crate) fn build_text_content<'a>(&self, doc: &'a Document, buf: &'a mut String) {
391        for child in self.children(doc) {
392            child.build_text_content(doc, buf);
393        }
394    }
395
396    /// Concatenate all text content of this element, including its child elements `text_content()`.
397    ///
398    /// Implementation of [Node.textContent](https://developer.mozilla.org/en-US/docs/Web/API/Node/textContent)
399    pub fn text_content(&self, doc: &Document) -> String {
400        let mut buf = String::new();
401        self.build_text_content(doc, &mut buf);
402        buf
403    }
404
405    /// Clears all its children and inserts a [`Node::Text`] with given text.
406    pub fn set_text_content<S: Into<String>>(&self, doc: &mut Document, text: S) {
407        self.clear_children(doc);
408        let node = Node::Text(text.into());
409        self.push_child(doc, node).unwrap();
410    }
411}
412
413/// Below are methods related to finding nodes in tree.
414impl Element {
415    pub fn parent(&self, doc: &Document) -> Option<Element> {
416        self.data(doc).parent
417    }
418
419    /// `self.parent(doc).is_some()`
420    pub fn has_parent(&self, doc: &Document) -> bool {
421        self.parent(doc).is_some()
422    }
423
424    /// Get child [`Node`]s of this element.
425    pub fn children<'a>(&self, doc: &'a Document) -> &'a Vec<Node> {
426        &self.data(doc).children
427    }
428
429    fn _children_recursive<'a>(&self, doc: &'a Document, nodes: &mut Vec<&'a Node>) {
430        for node in self.children(doc) {
431            nodes.push(node);
432            if let Node::Element(elem) = &node {
433                elem._children_recursive(doc, nodes);
434            }
435        }
436    }
437
438    /// Get all child nodes recursively. (i.e. includes its children's children.)
439    pub fn children_recursive<'a>(&self, doc: &'a Document) -> Vec<&'a Node> {
440        let mut nodes = Vec::new();
441        self._children_recursive(doc, &mut nodes);
442        nodes
443    }
444
445    /// `!self.children(doc).is_empty()`
446    pub fn has_children(&self, doc: &Document) -> bool {
447        !self.children(doc).is_empty()
448    }
449
450    /// Get only child [`Element`]s of this element.
451    ///
452    /// This calls `.children().iter().filter_map().collect()`.
453    /// Use [`Element::children()`] if performance is important.
454    pub fn child_elements(&self, doc: &Document) -> Vec<Element> {
455        self.children(doc)
456            .iter()
457            .filter_map(|node| {
458                if let Node::Element(elemid) = node {
459                    Some(*elemid)
460                } else {
461                    None
462                }
463            })
464            .collect()
465    }
466
467    /// Get child [`Element`]s recursively. (i.e. includes its child element's child elements)
468    pub fn child_elements_recursive(&self, doc: &Document) -> Vec<Element> {
469        self.children_recursive(doc)
470            .iter()
471            .filter_map(|node| {
472                if let Node::Element(elemid) = node {
473                    Some(*elemid)
474                } else {
475                    None
476                }
477            })
478            .collect()
479    }
480
481    /// Find first direct child element with name `name`.
482    pub fn find(&self, doc: &Document, name: &str) -> Option<Element> {
483        self.children(doc)
484            .iter()
485            .filter_map(|n| n.as_element())
486            .find(|e| e.name(doc) == name)
487    }
488
489    /// Find all direct child element with name `name`.
490    pub fn find_all(&self, doc: &Document, name: &str) -> Vec<Element> {
491        self.children(doc)
492            .iter()
493            .filter_map(|n| n.as_element())
494            .filter(|e| e.name(doc) == name)
495            .collect()
496    }
497}
498
499/// Below are functions that modify its tree-structure.
500///
501/// Because an element has reference to both its parent and its children,
502/// an element's parent and children is not directly exposed for modification.
503/// But in return, it is not possible for a document to be in an inconsistant state,
504/// where an element's parent doesn't have the element as its children.
505impl Element {
506    /// Equivalent to `vec.push()`.
507    /// # Errors
508    /// - [`Error::HasAParent`]: When you want to replace an element's parent with another,
509    /// call `element.detatch()` to make it parentless first.
510    /// This is to make it explicit that you are changing an element's parent, not adding another.
511    /// - [`Error::ContainerCannotMove`]: The container element's parent must always be None.
512    pub fn push_child(&self, doc: &mut Document, node: Node) -> Result<()> {
513        if let Node::Element(elem) = node {
514            if elem.is_container() {
515                return Err(Error::ContainerCannotMove);
516            }
517            let data = elem.mut_data(doc);
518            if data.parent.is_some() {
519                return Err(Error::HasAParent);
520            }
521            data.parent = Some(*self);
522        }
523        self.mut_data(doc).children.push(node);
524        Ok(())
525    }
526
527    /// Equivalent to `parent.push_child()`.
528    ///
529    /// # Errors
530    /// - [`Error::HasAParent`]: When you want to replace an element's parent with another,
531    /// call `element.detatch()` to make it parentless first.
532    /// This is to make it explicit that you are changing an element's parent, not adding another.
533    /// - [`Error::ContainerCannotMove`]: The container element's parent must always be None.
534    pub fn push_to(&self, doc: &mut Document, parent: Element) -> Result<()> {
535        parent.push_child(doc, self.as_node())
536    }
537
538    /// Equivalent to `vec.insert()`.
539    ///
540    /// # Panics
541    ///
542    /// Panics if `index > self.children().len()`
543    ///
544    /// # Errors
545    /// - [`Error::HasAParent`]: When you want to replace an element's parent with another,
546    /// call `element.detatch()` to make it parentless first.
547    /// This is to make it explicit that you are changing an element's parent, not adding another.
548    /// - [`Error::ContainerCannotMove`]: The container element's parent must always be None.
549    pub fn insert_child(&self, doc: &mut Document, index: usize, node: Node) -> Result<()> {
550        if let Node::Element(elem) = node {
551            if elem.is_container() {
552                return Err(Error::ContainerCannotMove);
553            }
554            let data = elem.mut_data(doc);
555            if data.parent.is_some() {
556                return Err(Error::HasAParent);
557            }
558            data.parent = Some(*self);
559        }
560        self.mut_data(doc).children.insert(index, node);
561        Ok(())
562    }
563
564    /// Equivalent to `vec.remove()`.
565    ///
566    /// # Panics
567    ///
568    /// Panics if `index >= self.children().len()`.
569    pub fn remove_child(&self, doc: &mut Document, index: usize) -> Node {
570        let node = self.mut_data(doc).children.remove(index);
571        if let Node::Element(elem) = node {
572            elem.mut_data(doc).parent = None;
573        }
574        node
575    }
576
577    /// Equivalent to `vec.pop()`.
578    pub fn pop_child(&self, doc: &mut Document) -> Option<Node> {
579        let child = self.mut_data(doc).children.pop();
580        if let Some(Node::Element(elem)) = &child {
581            elem.mut_data(doc).parent = None;
582        }
583        child
584    }
585
586    /// Remove all children and return them.
587    pub fn clear_children(&self, doc: &mut Document) -> Vec<Node> {
588        let count = self.children(doc).len();
589        let mut removed = Vec::with_capacity(count);
590        for _ in 0..count {
591            let child = self.remove_child(doc, 0);
592            removed.push(child);
593        }
594        removed
595    }
596
597    /// Removes itself from its parent. Note that you can't attach this element to other documents.
598    ///
599    /// # Errors
600    ///
601    /// - [`Error::ContainerCannotMove`]: You can't detatch container element
602    pub fn detatch(&self, doc: &mut Document) -> Result<()> {
603        if self.is_container() {
604            return Err(Error::ContainerCannotMove);
605        }
606        let data = self.mut_data(doc);
607        if let Some(parent) = data.parent {
608            let pos = parent
609                .children(doc)
610                .iter()
611                .position(|n| n.as_element() == Some(*self))
612                .unwrap();
613            parent.remove_child(doc, pos);
614        }
615        Ok(())
616    }
617}
618
619#[cfg(test)]
620mod tests {
621    use super::{Document, Element, Node};
622
623    #[test]
624    fn test_children() {
625        let xml = r#"<?xml version="1.0" encoding="UTF-8"?>
626        <outer>
627            inside outer
628            <middle>
629                <inner>
630                    inside
631                </inner>
632                after inside
633            </middle>
634            <after>
635                inside after
636            </after>
637        </outer>
638        "#;
639        let doc = Document::parse_str(xml).unwrap();
640        let outer = doc.container().child_elements(&doc)[0];
641        let middle = outer.child_elements(&doc)[0];
642        let inner = middle.child_elements(&doc)[0];
643        let after = outer.child_elements(&doc)[1];
644        assert_eq!(doc.container().child_elements(&doc).len(), 1);
645        assert_eq!(outer.name(&doc), "outer");
646        assert_eq!(middle.name(&doc), "middle");
647        assert_eq!(inner.name(&doc), "inner");
648        assert_eq!(after.name(&doc), "after");
649        assert_eq!(outer.children(&doc).len(), 3);
650        assert_eq!(outer.child_elements(&doc).len(), 2);
651        assert_eq!(doc.container().children_recursive(&doc).len(), 8);
652        assert_eq!(
653            doc.container().child_elements_recursive(&doc),
654            vec![outer, middle, inner, after]
655        );
656    }
657
658    #[test]
659    fn test_namespace() {
660        let xml = r#"<?xml version="1.0" encoding="UTF-8"?>
661        <root xmlns="ns", xmlns:p="pns">
662            <p:foo xmlns="inner">
663                Hello
664            </p:foo>
665            <p:bar xmlns:p="in2">
666                <c />
667                World!
668            </p:bar>
669        </root>"#;
670        let doc = Document::parse_str(xml).unwrap();
671        let container = doc.container().children(&doc)[0].as_element().unwrap();
672        let child_elements = container.child_elements(&doc);
673        let foo = *child_elements.get(0).unwrap();
674        let bar = *child_elements.get(1).unwrap();
675        let c = bar.child_elements(&doc)[0];
676        assert_eq!(c.prefix_name(&doc), ("", "c"));
677        assert_eq!(bar.full_name(&doc), "p:bar");
678        assert_eq!(bar.prefix(&doc), "p");
679        assert_eq!(bar.name(&doc), "bar");
680        assert_eq!(c.namespace(&doc).unwrap(), "ns");
681        assert_eq!(c.namespace_for_prefix(&doc, "p").unwrap(), "in2");
682        assert!(c.namespace_for_prefix(&doc, "random").is_none());
683        assert_eq!(bar.namespace(&doc).unwrap(), "in2");
684        assert_eq!(bar.namespace_for_prefix(&doc, "").unwrap(), "ns");
685        assert_eq!(foo.namespace(&doc).unwrap(), "pns");
686        assert_eq!(foo.namespace_for_prefix(&doc, "").unwrap(), "inner");
687        assert_eq!(foo.namespace_for_prefix(&doc, "p").unwrap(), "pns");
688        assert_eq!(container.namespace(&doc).unwrap(), "ns");
689    }
690
691    #[test]
692    fn test_find_text_content() {
693        let xml = r#"<?xml version="1.0" encoding="UTF-8"?>
694        <core>
695            <p>Text</p>
696            <b>Text2</b>
697        </core>
698        "#;
699        let doc = Document::parse_str(xml).unwrap();
700        assert_eq!(
701            doc.root_element()
702                .unwrap()
703                .find(&doc, "p")
704                .unwrap()
705                .text_content(&doc),
706            "Text"
707        );
708        assert_eq!(
709            doc.root_element()
710                .unwrap()
711                .find(&doc, "b")
712                .unwrap()
713                .text_content(&doc),
714            "Text2"
715        );
716        assert_eq!(doc.root_element().unwrap().text_content(&doc), "TextText2")
717    }
718
719    #[test]
720    fn test_mutate_tree() {
721        // Test tree consistency after mutating tree
722        let mut doc = Document::new();
723        let container = doc.container();
724        assert_eq!(container.parent(&doc), None);
725        assert_eq!(container.children(&doc).len(), 0);
726
727        // Element::build.push_to
728        let root = Element::build(&mut doc, "root").push_to(container);
729        assert_eq!(root.parent(&doc).unwrap(), container);
730        assert_eq!(doc.root_element().unwrap(), root);
731
732        // Element::new
733        let a = Element::new(&mut doc, "a");
734        assert_eq!(a.parent(&doc), None);
735
736        // Element.push_child
737        root.push_child(&mut doc, Node::Element(a)).unwrap();
738        assert_eq!(root.children(&doc)[0].as_element().unwrap(), a);
739        assert_eq!(a.parent(&doc).unwrap(), root);
740
741        // Element.pop
742        let popped = root.pop_child(&mut doc).unwrap().as_element().unwrap();
743        assert_eq!(popped, a);
744        assert_eq!(root.children(&doc).len(), 0);
745        assert_eq!(a.parent(&doc), None);
746
747        // Element.push_to
748        let a = Element::new(&mut doc, "a");
749        a.push_to(&mut doc, root).unwrap();
750        assert_eq!(root.children(&doc)[0].as_element().unwrap(), a);
751        assert_eq!(a.parent(&doc).unwrap(), root);
752
753        // Element.remove_child
754        root.remove_child(&mut doc, 0);
755        assert_eq!(root.children(&doc).len(), 0);
756        assert_eq!(a.parent(&doc), None);
757
758        // Element.insert_child
759        let a = Element::new(&mut doc, "a");
760        root.insert_child(&mut doc, 0, Node::Element(a)).unwrap();
761        assert_eq!(root.children(&doc)[0].as_element().unwrap(), a);
762        assert_eq!(a.parent(&doc).unwrap(), root);
763
764        // Element.detatch
765        a.detatch(&mut doc).unwrap();
766        assert_eq!(root.children(&doc).len(), 0);
767        assert_eq!(a.parent(&doc), None);
768    }
769}