1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155
// // lib.rs // // amxml: XML processor with XPath. // Copyright (C) 2018 KOYAMA Hiro <tac@amris.co.jp> // //! //! XML processor with some features of XPath 2.0 / 3.0 / 3.1. //! //! # Building DOM tree from XML document string //! //! Building DOM tree can be done by calling <strong>new_document()</strong> function. //! The DOM tree can be turned into String. //! //! ``` //! use amxml::dom::*; //! let xml_string = r#"<?xml version="1.0"?><article>foo</article>"#; //! let doc = new_document(&xml_string).unwrap(); //! let result = doc.to_string(); //! assert_eq!(result, xml_string); //! ``` //! //! # Navigating DOM tree //! //! Navigating DOM tree, or retrieving the DOM node, can be done by //! <strong>root_element()</strong>, <strong>parent()</strong>, //! <strong>first_child()</strong>, <strong>nth_child()</strong>, //! <strong>attribute_value()</strong> methods. //! //! See the description and example of corresponding method. //! //! # Retrieving the DOM node by XPath //! //! But more convenient way for retrieving the DOM node is, perhaps, //! using XPath, especially when the search criteria is not trivial. //! //! First XPath example is somewhat straightforward. //! <strong>each_node()</strong> method visits the DOM nodes //! that match with the given XPath, //! and apply the function (closure) to these nodes. //! //! ``` //! use amxml::dom::*; //! let xml = r#"<root><a img="a1"/><a img="a2"/></root>"#; //! let doc = new_document(xml).unwrap(); //! let mut img = String::new(); //! doc.each_node("/root/a", |n| { //! img += n.attribute_value("img").unwrap().as_str(); //! }); //! assert_eq!(img, "a1a2"); //! ``` //! //! Second XPath example is more complex. //! This finds the clerk OR engineer (NOT advisor) who has no subordinates. //! Note that clerks and enginners appear in <em>document order</em> //! in <strong>each_node()</strong> iteration. //! //! ``` //! use amxml::dom::*; //! let xml = r#" //! <root> //! <clerk name="Ann"> //! <advisor name="Betty"/> //! <clerk name="Charlie"/> //! </clerk> //! <engineer name="Dick"> //! <engineer name="Emily"/> //! </engineer> //! <clerk name="Fred"/> //! </root> //! "#; //! let doc = new_document(xml).unwrap(); //! let root = doc.root_element(); //! let xpath = "(//clerk | //engineer)[count(./*) = 0]"; //! let mut names = String::new(); //! root.each_node(xpath, |n| { //! names += n.attribute_value("name").unwrap().as_str(); //! names += "; "; //! }); //! assert_eq!(names, "Charlie; Emily; Fred; "); //! //! ``` //! //! Also see the description and example of <strong>each_node()</strong>, //! <strong>get_first_node()</strong>, <strong>get_nodeset()</strong> methods. //! //! # Evaluating XPath //! //! XPath can also be used to evaluate for the DOM tree and get boolean, //! numeric, string values as well as DOM node. //! The example below lists up the students, and whether or not each student //! got 80 or more points in <em>every</em> (not <em>some</em>) examination. //! //! ``` //! use amxml::dom::*; //! let xml = r#" //! <root> //! <student> //! <name>George</name> //! <exam subject="math" point="70"/> //! <exam subject="science" point="90"/> //! </student> //! <student> //! <name>Harry</name> //! <exam subject="math" point="80"/> //! <exam subject="science" point="95"/> //! </student> //! <student> //! <name>Ivonne</name> //! <exam subject="math" point="60"/> //! <exam subject="science" point="75"/> //! </student> //! </root> //! "#; //! let doc = new_document(xml).unwrap(); //! let root = doc.root_element(); //! let xpath= r#" //! for $student in /root/student return //! ($student/name/text(), //! every $exam in $student/exam satisfies number($exam/@point) >= 80) //! "#; //! let result = root.eval_xpath(xpath).unwrap(); //! assert_eq!(result.to_string(), "(George, false, Harry, true, Ivonne, false)"); //! //! ``` //! //! # Manipurating the DOM node //! //! Inserting / replacing / deleting the DOM node can be done by //! methods like <strong>append_child()</strong>, //! <strong>insert_as_previous_sibling()</strong>, //! <strong>insert_as_next_sibling()</strong>, //! <strong>delete_child()</strong>, <strong>replace_with()</strong>, //! <strong>set_attribute()</strong>, <strong>delete_attribute()</strong> methods. //! //! See the description and example of corresponding method. //! #[macro_use] pub mod xmlerror; pub mod sax; pub mod dom; pub mod xpath; mod xpath_impl { pub mod lexer; pub mod parser; pub mod xitem; pub mod xsequence; pub mod eval; pub mod func; pub mod oper; pub mod helpers; }