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

mem*_*org 3 xpath rust

我一直在尝试使用sxd-xpath crate查询 XML,但我似乎无法弄清楚如何处理节点集。

板条箱和使用

extern crate sxd_document;
extern crate sxd_xpath;

use sxd_document::parser;
use sxd_xpath::{Factory, Context, Value};
Run Code Online (Sandbox Code Playgroud)

实际代码

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");
Run Code Online (Sandbox Code Playgroud)

我想遍历每个节点并打印出 的值<title>,但我不明白该怎么做。

我是 Rust 世界的新手,来自 C# 和 Python。

She*_*ter 5

XPath::evaluate返回一个Value

fn evaluate<'d, N>(
    &self,
    context: &Context<'d>,
    node: N,
) -> Result<Value<'d>, ExecutionError>
where
    N: Into<Node<'d>>,
Run Code Online (Sandbox Code Playgroud)

AValue是 XPath 的可能值的枚举(数字、布尔值、字符串或节点集)。在您的情况下,您对节点集感兴趣,因此您需要匹配该变体:

if let Value::Nodeset(nodes) = value {
    // ...
}
Run Code Online (Sandbox Code Playgroud)

Nodeset实现IntoIterator,因此您可以在for循环中使用它:

for node in nodes {
    // ...
}
Run Code Online (Sandbox Code Playgroud)

每个产生的值将是一个Node. 这是 XML 文档中所有不同类型节点的枚举。你对Elements感兴趣。如果所有你关心的是元素的字符串值,你可以使用Node::string_value。这隐藏了多个子节点的任何复杂性,每个子节点都有自己的文本:

println!("{}", node.string_value());
Run Code Online (Sandbox Code Playgroud)

放在一起:

if let Value::Nodeset(nodes) = value {
    for node in nodes {
        println!("{}", node.string_value());
    }
}
Run Code Online (Sandbox Code Playgroud)

ANodeset没有保证的顺序,因此如果您希望节点按照它们在文档中的顺序,您可以调用Nodeset::document_order

if let Value::Nodeset(nodes) = value {
    for node in nodes.document_order() {
        println!("{}", node.string_value());
    }
}
Run Code Online (Sandbox Code Playgroud)

免责声明:我是 SXD-Document 和 SXD-XPath 的作者