如何使用SXD-XPath迭代节点集并打印出每个值?

时间:2018-03-17 09:26:55

标签: xpath rust

我一直在尝试使用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。

1 个答案:

答案 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的作者