Hi there
I've been trying to query XML with the sxd_xpath crate and I can't seem to figure out how to handle a nodeset
let package = parser::parse("<feed><title>hest</title><title>hest2</title><title>hest3</title><title>hest4</title></feed>").expect("failed to parse XML");
let document = package.as_document();
let factory = Factory::new();
let xpath = factory.build("/feed/title").expect("Could not compile XPath");
let xpath = xpath.expect("No XPath was compiled");
let context = Context::new();
let value = xpath.evaluate(&context, document.root()).expect("XPath evaluation failed");
I would like to iterate over every node and print out the value of <title>
. But I do not understand how to do it.
I'm fairly new in the Rust world, but are comming from C# and Python and this is a experiment to port a Python project to Rust.
I've never used sxd-xpath
but looking at its docs, here's a full working example:
extern crate sxd_xpath;
extern crate sxd_document;
use sxd_document::parser;
use sxd_xpath::{Factory, Value};
use sxd_xpath::context::Context;
fn main() {
let package = parser::parse("<feed><title>hest</title><title>hest2</title><title>hest3</title><title>hest4</title></feed>").expect("failed to parse XML");
let document = package.as_document();
let factory = Factory::new();
let xpath = factory.build("/feed/title").expect("Could not compile XPath");
let xpath = xpath.expect("No XPath was compiled");
let context = Context::new();
let value = xpath.evaluate(&context, document.root()).expect("XPath evaluation failed");
if let Value::Nodeset(ref ns) = value {
ns.iter().for_each(|n| println!("{}", n.string_value()));
}
}
You can also use a normal for loop instead:
...
if let Value::Nodeset(ref ns) = value {
for node in ns {
println!("{}", node.string_value());
}
}
Edit: if you want to avoid allocating the String for string_value
, you can select the elements' text and then grab it via a slice (i.e. &str):
...
let xpath = factory.build("/feed/title/text()").expect("Could not compile XPath");
...
if let Value::Nodeset(ref ns) = value {
for node in ns {
if let Node::Text(ref t)= node {
println!("{}", t.text());
}
}
Thanks a lot for the the answer. 