xpath - 如何迭代使用 sxd_xpath 提取的节点的所有属性?

标签 xpath rust

我正在尝试迭代我用 sxd_xpath 提取的节点的所有属性,但我无法弄清楚如何

extern crate sxd_document;
extern crate sxd_xpath;

use std::fs;
use sxd_document::parser;
use sxd_xpath::{evaluate_xpath, Value};

fn main() {
    let content =
        fs::read_to_string("C:/afile.xml").expect("Something went wrong reading the file");
    let package = parser::parse(&content);
    match package {
        Ok(package) => {
            let document = package.as_document();
            let value = evaluate_xpath(&document, "//Node[@name=\"somenodename\"]")
                .expect("XPath evaluation failed");

            if let Value::Nodeset(nodes) = value {
                for node in nodes.document_order() {
                    //how to get all the attributes of all the nodes i'm parsing?
                }
            }
        }
        Err(err) => {
            println!("{:?}", err);
        }
    }
}

我尝试阅读文档,但我看不到这样做的方法

最佳答案

您可以做的最直接的事情是使用 //Node[@name="somenodename"]/@* 直接在 XPath 中选择属性:

let value = evaluate_xpath(&document, r#"//Node[@name="somenodename"]/@*"#)
    .expect("XPath evaluation failed");

if let Value::Nodeset(nodes) = value {
    for node in nodes.document_order() {
        if let Node::Attribute(attr) = node {
            println!("{}", attr.value());
        }
    }
}

如果出于某种原因需要对元素进行迭代,则需要检查节点集中的每个节点是否为元素,然后获取节点集的属性:

let value = evaluate_xpath(&document, r#"//Node[@name="somenodename"]"#)
    .expect("XPath evaluation failed");

if let Value::Nodeset(nodes) = value {
    for node in nodes.document_order() {
        if let Node::Element(elem) = node {
            for attr in elem.attributes() {
                println!("{}", attr.value());
            }
        }
    }
}

您还可以在 Node 上使用 Rust 的迭代器链接和一些转换方法:

let value = evaluate_xpath(&document, r#"//Node[@name="somenodename"]"#)
    .expect("XPath evaluation failed");

if let Value::Nodeset(nodes) = value {
    for attr in nodes
        .document_order()
        .into_iter()
        .flat_map(|n| n.element())
        .flat_map(|e| e.attributes())
    {
        println!("{}", attr.value());
    }
}

完成设置:

use sxd_document::parser; // 0.3.2
use sxd_xpath::{evaluate_xpath, Value}; // 0.4.2

fn main() {
    let content = r#"<?xml version="1.0"?>
    <foo>
      <Node name="somenodename" id="1" />
      <bar>
        <Node name="somenodename" id="2" />
      </bar>
    </foo>
    "#;

    let package = parser::parse(&content).expect("unable to parse");
    let document = package.as_document();

    // Various methods here
}

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

关于xpath - 如何迭代使用 sxd_xpath 提取的节点的所有属性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58733477/

相关文章:

java - XPath 和链接的问题

xml - 在 XPath 中通过 concat() 换行符 (\n)?

xml - XPath-选择所有属于类型的唯一子节点

xslt - 跨XSLT节点集的不同值

rust - 为什么我不能阻止一个盒子?

rust - 有没有办法在 Rust 中创建指向方法的函数指针?

java - 如何在java中的某个元素之后/之前将元素插入到xml中

rust - 为什么 panic 时 panic 会导致非法指令?

generics - 为什么我的通用 From 实现不接受 Box<Fn()> 值?

rust - 克隆存储闭包的结构