-
Notifications
You must be signed in to change notification settings - Fork 51
Expand file tree
/
Copy pathcontext.rs
More file actions
67 lines (58 loc) · 2.13 KB
/
Copy pathcontext.rs
File metadata and controls
67 lines (58 loc) · 2.13 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
use crate::{
readonly::{RoDocument, RoNode, RoObject},
xpath::Context,
};
/// A read-only libxml2 Context
#[derive(Clone)]
pub struct RoContext(Context);
// SAFETY: we promise to only provide methods that need read-only access.
unsafe impl Sync for RoContext {}
unsafe impl Send for RoContext {}
impl RoContext {
/// create a read-only xpath context for a document
pub fn new(owner: &RoDocument) -> Result<Self, ()> {
let context = Context::new(&owner.0)?;
Ok(Self(context))
}
/// evaluate an xpath
pub fn evaluate(&self, xpath: &str) -> Result<RoObject, ()> {
self.0.evaluate(xpath).map(RoObject)
}
///evaluate an xpath on a context Node
pub fn node_evaluate(&self, xpath: &str, node: &RoNode) -> Result<RoObject, ()> {
self.0.node_evaluate_readonly(xpath, *node).map(RoObject)
}
/// evaluate an xpath on a context RoNode
pub fn node_evaluate_readonly(&self, xpath: &str, node: RoNode) -> Result<RoObject, ()> {
self.0.node_evaluate_readonly(xpath, node).map(RoObject)
}
/// find nodes via xpath, at a specified node or the document root
pub fn findnodes(&self, xpath: &str, node_opt: Option<&RoNode>) -> Result<Vec<RoNode>, ()> {
// Note: we cannot implemented this as `self.0.findnodes(...)` because that
// method takes `&mut self`.
let evaluated = if let Some(node) = node_opt {
self.node_evaluate(xpath, node)?
} else {
self.evaluate(xpath)?
};
Ok(evaluated.get_nodes_as_vec())
}
/// find literal values via xpath, at a specified node or the document root
pub fn findvalues(&self, xpath: &str, node_opt: Option<&RoNode>) -> Result<Vec<String>, ()> {
let evaluated = if let Some(node) = node_opt {
self.node_evaluate(xpath, node)?
} else {
self.evaluate(xpath)?
};
Ok(evaluated.get_nodes_as_str())
}
/// find a literal value via xpath, at a specified node or the document root
pub fn findvalue(&self, xpath: &str, node_opt: Option<&RoNode>) -> Result<String, ()> {
let evaluated = if let Some(node) = node_opt {
self.node_evaluate(xpath, node)?
} else {
self.evaluate(xpath)?
};
Ok(evaluated.to_string())
}
}