7 releases
Uses old Rust 2015
0.5.3 | Sep 18, 2018 |
---|---|
0.5.2 | Aug 7, 2018 |
0.5.1 | Jul 26, 2018 |
0.4.9 | Jul 3, 2018 |
0.4.8 | Jun 25, 2018 |
#1346 in Web programming
435 downloads per month
Used in 2 crates
(via freedesktop-categories-co…)
565KB
11K
SLoC
amxml
Rust 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 new_document() 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 root_element(), parent(), first_child(), nth_child(), attribute_value() 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. each_node() 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 document order in each_node() 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 each_node(), get_first_node(), get_nodeset() 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 every (not some) 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 append_child(), insert_as_previous_sibling(), insert_as_next_sibling(), delete_child(), replace_with(), set_attribute(), delete_attribute() methods.
See the description and example of corresponding method.