#XML #XPath #DOM #SAX #XPath3

bin+lib amxml

XML processor with some features of XPath 2.0 / 3.0 / 3.1

6 releases

0.5.2 Aug 7, 2018
0.5.1 Jul 26, 2018
0.4.9 Jul 3, 2018
0.4.8 Jun 25, 2018

#76 in Parsing tools

Download history 14/week @ 2018-06-13 7/week @ 2018-06-20 24/week @ 2018-06-27 15/week @ 2018-07-04 6/week @ 2018-07-11 28/week @ 2018-07-18 15/week @ 2018-07-25 46/week @ 2018-08-01 78/week @ 2018-08-08

77 downloads per month
Used in 2 crates (1 directly)

MIT/Apache

563KB
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#"

    
        
        
    
    
        
    
    

"#;
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#"

    
        George
        
        
    
    
        Harry
        
        
    
    
        Ivonne
        
        
    

"#;
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.

No runtime deps