我似乎无法弄清楚为什么它不起作用。我有一个要通过XPath遍历的外部XML文件。
我的代码是:
extern crate sxd_document;
extern crate sxd_xpath;
use std::fs;
use sxd_document::parser;
use sxd_xpath::{evaluate_xpath, Value};
fn main() {
let contents = fs::read_to_string("./spec/organisation.xml")
.expect("Something went wrong reading the file");
// let package = parser::parse("<root>hello</root>").expect("failed to parse XML");
let package = parser::parse(&contents).expect("failed to parse XML");
let document = package.as_document();
let value = evaluate_xpath(&document, "/root").expect("XPath evaluation failed");
assert_eq!("hello", value.string());
}
XML是:
<organisation xml:id="a17649">
<code rdf:resource="http://pbs.gov.au/code/manufacturer">CU</code>
<title>Care Pharmaceuticals Pty Limited</title>
<address>
<dbk:street>Suite 303, Level 3, 59-75 Grafton Street</dbk:street>
<dbk:city>Bondi Junction</dbk:city>
<dbk:state>NSW</dbk:state>
<dbk:postcode>2022</dbk:postcode>
<effective>
<date>2018-12-01</date>
</effective>
</address>
<contact>
<dbk:phone>1800 788 870</dbk:phone>
<effective>
<date>2018-12-01</date>
</effective>
</contact>
<effective>
<date>2012-08-27</date>
</effective>
</organisation>
堆栈跟踪如下:
Running `target/debug/pbs`
thread 'main' panicked at 'failed to parse XML: Error { location: 50, errors: {UnknownNamespacePrefix} }', libcore/result.rs:1009:5
stack backtrace:
0: std::sys::unix::backtrace::tracing::imp::unwind_backtrace
at libstd/sys/unix/backtrace/tracing/gcc_s.rs:49
1: std::sys_common::backtrace::print
at libstd/sys_common/backtrace.rs:71
at libstd/sys_common/backtrace.rs:59
2: std::panicking::default_hook::{{closure}}
at libstd/panicking.rs:211
3: std::panicking::default_hook
at libstd/panicking.rs:227
4: std::panicking::rust_panic_with_hook
at libstd/panicking.rs:476
5: std::panicking::continue_panic_fmt
at libstd/panicking.rs:390
6: rust_begin_unwind
at libstd/panicking.rs:325
7: core::panicking::panic_fmt
at libcore/panicking.rs:77
8: core::result::unwrap_failed
at libcore/macros.rs:26
9: <core::result::Result<T, E>>::expect
at libcore/result.rs:835
10: pbs::main
at src/main.rs:14
11: std::rt::lang_start::{{closure}}
at libstd/rt.rs:74
12: std::panicking::try::do_call
at libstd/rt.rs:59
at libstd/panicking.rs:310
13: __rust_maybe_catch_panic
at libpanic_unwind/lib.rs:102
14: std::rt::lang_start_internal
at libstd/panicking.rs:289
at libstd/panic.rs:392
at libstd/rt.rs:58
15: std::rt::lang_start
at libstd/rt.rs:74
16: main
17: __libc_start_main
18: _start
答案 0 :(得分:3)
当XML内容正确时,您的XML解析代码应该在幸福的道路上工作。
尽管它在幸福的道路上没有问题,但是由于您在代码中使用expect
而不是错误处理,因此程序在错误情况下会出现紧急情况。
您可以将代码更改为以下内容,以更好地显示错误:
let package = parser::parse(&contents);
match package {
Ok(package) => {
let document = package.as_document();
let value = evaluate_xpath(&document, "/root").expect("XPath evaluation failed");
println!("value: {:?}", value);
}
Err(err) => {
println!("{:?}", err);
}
}
此修复程序完成后,您将注意到代码显示了UnknownNamespacePrefix
错误。
当XML内容具有XML文件本身未声明的名称空间时,会发生此错误。
在您的XML文件中,您需要指定名称空间,而对于以下内容则没有:
<organisation xml:id="a17649">
您需要添加名称空间:
<organisation xml:id="a17649" xmlns:rdf="http://www.w3.org/1999/xhtml">
即使您这样声明了rdf
命名空间,您仍在使用dbk
命名空间,该命名空间可能取决于您的项目本身。您还需要指定此命名空间:
<organisation xml:id="a17649" xmlns:rdf="http://www.w3.org/1999/xhtml" xmlns:dbk="/path/to/dbk">
这些更改之后,您的问题应该得到解决
答案 1 :(得分:1)
鉴于错误消息,我希望您需要先在rdf
属性名称上使用rdf:resource
命名空间,然后进行声明。
(您的问题与XPath没有任何关系-在运行任何XPath代码之前尝试解析XML时失败。)
答案 2 :(得分:1)
您的XML文件使用非标准的rdf
命名空间,但未定义它。您需要在XML中定义名称空间:
<organisation xml:id="a17649"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
一些XML解析器允许您在XML文档之外的代码中声明名称空间,但是在快速浏览sxd_document
docs之后,我没有发现类似的东西。