我一直在尝试使用sxd-xpath crate查询XML,而我似乎无法弄清楚如何处理节点集。
Crate并使用
extern crate sxd_document;
extern crate sxd_xpath;
use sxd_document::parser;
use sxd_xpath::{Factory, Context, Value};
实际代码
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");
我想迭代每个节点并打印出<title>
的值,但我不明白该怎么做。
我在Rust世界中相当新,来自C#和Python。
答案 0 :(得分:3)
XPath::evaluate
返回Value
:
fn evaluate<'d, N>(
&self,
context: &Context<'d>,
node: N,
) -> Result<Value<'d>, ExecutionError>
where
N: Into<Node<'d>>,
Value
是XPath(数字,布尔值,字符串或节点集)的可能值的枚举。在您的情况下,您对节点集感兴趣,因此您需要匹配该变体:
if let Value::Nodeset(nodes) = value {
// ...
}
Nodeset
实施IntoIterator
,因此您可以在for
循环中使用它:
for node in nodes {
// ...
}
每个产生的值都是Node
。这是XML文档中所有不同类型节点的枚举。您对Element
感兴趣。如果您关心的 all 是元素的字符串值,则可以使用Node::string_value
。这隐藏了多个子节点的复杂性,每个子节点都有自己的文本:
println!("{}", node.string_value());
全部放在一起:
if let Value::Nodeset(nodes) = value {
for node in nodes {
println!("{}", node.string_value());
}
}
Nodeset
没有保证订单,因此如果您希望节点按照文档中的顺序排列,则可以调用Nodeset::document_order
:
if let Value::Nodeset(nodes) = value {
for node in nodes.document_order() {
println!("{}", node.string_value());
}
}
免责声明:我是SXD-Document和SXD-XPath的作者