KWARC / rust-libxml

Rust wrapper for libxml2
https://crates.io/crates/libxml
MIT License
76 stars 38 forks source link

How to receive errors from xpath queries. #133

Closed hurricane-socrates closed 5 months ago

hurricane-socrates commented 6 months ago

I have an xpath query involving namespaces that executes successfully in xmllint. The query does not execute using rust-libxml. The Result Err is, as you know, ()

This makes debugging quite difficult.

How does one debug xpath queries using rust-libxml?

        if let Ok(context) = Context::new(&doc) {
            // let ns = get_default_namespace(&mut root);
            context.register_namespace("scxml", "http://www.w3.org/2005/07/scxml").unwrap();
            println!(
                "node count: {}",
                root
                    .findnodes(".//scxml:initial/scxml:transition[@target]")
                    .unwrap()
                    .len()
            );

Gives the following error

thread 'scxml::test_scxml::test_enter_states_010' panicked at src/scxml.rs:1101:22:
called `Result::unwrap()` on an `Err` value: ()

The xmllint session

xmllint --shell /tmp/foo.xml
/ > setns scxml=http://www.w3.org/2005/07/scxml 
/ > du .//scxml:initial/scxml:transition[@target]
scxml:transition

foo.xml



<?xml version="1.0" encoding="UTF-8"?>
<scxml:scxml xmlns:scxml="http://www.w3.org/2005/07/scxml" binding="late" version="1.0">
            <state id="xyzzy">
                <initial id="elmer"/>
                <state id="elmer">
                    <state id="charlie">
                        <initial id="frank"/>
                        <state id="frank"/>
                    </state>
                </state>
            </state>
            <state id="fred">
                <initial id="fubar"/>
                <state id="fubar"/>
            </state>
        <scxml:initial><scxml:transition target="xyzzy"/></scxml:initial></scxml:scxml>
dginev commented 6 months ago

It should be possible to pass through the error information to the Rust layer. Would you like to work on a PR for that @hurricane-socrates ? It ought to be similar in spirit to #116

hurricane-socrates commented 6 months ago

Sure. I'll take a look at that PR

hurricane-socrates commented 6 months ago

@dginev It looks like the technique from #116 is deprecated. Use a context sensitve error handler

hurricane-socrates commented 6 months ago

I could use some help locating the routine xmlXPathSetErrorHandler AFAICT, this is the routine signature to declare in bindings.rs

extern "C" {
  pub fn xmlXPathSetErrorHandler(ctxt: xmlXPathContextPtr, handler: xmlStructuredErrorFunc, data: *mut ::std::os::raw::c_void,);
}

However, this routine doesn't seem to be in libxml2. For comparison, I also seached for xmlSchemaSetValidStructuredErrors

$ nm -a /opt/local/lib/libxml2.a | grep -i xmlSchemaSetValidStructuredErrors
0000000000004d18 T _xmlSchemaSetValidStructuredErrors
                 U _xmlSchemaSetValidStructuredErrors

$ nm -a /opt/local/lib/libxml2.a | grep -i xmlXPathSetErrorHandler

Not sure what to do here...

anwaralameddin commented 6 months ago

xmlXPathSetErrorHandler is declared in include/libxml/xpath.h and defined in xpath.c.

hurricane-socrates commented 6 months ago

Agreed. I'm wondering why the linker isn't finding that symbol. It doesn't seem to be in libxml2. All other symbols from libxml2 (at least the ones I've been using) are availabile. From cargo test

= note: Undefined symbols for architecture arm64:
            "_xmlXPathSetErrorHandler", referenced from:
                libxml::xpath::Context::new::h20bb50279afab52f in liblibxml-9ca532cdd5752ccb.rlib[62](libxml-9ca532cdd5752ccb.4aafaw59ux80hdpa.rcgu.o)
                libxml::xpath::Context::new_ptr::h30a1d8744591371d in liblibxml-9ca532cdd5752ccb.rlib[62](libxml-9ca532cdd5752ccb.4aafaw59ux80hdpa.rcgu.o)
          ld: symbol(s) not found for architecture arm64
          clang: error: linker command failed with exit code 1 (use -v to see invocation)
anwaralameddin commented 6 months ago

xmlXPathSetErrorHandler was added relatively recently to the master branch in this commit. It is currently unavailable in other benches or releases. So, unless you/your platform build libxml2 from the master branch, xmlXPathSetErrorHandler won't be available.

hurricane-socrates commented 6 months ago

Thanks!