# Gobo Eiffel XPointer library (XPath implementation)

The XPath library includes an implementation of the XPointer Framework and implementations for the W3C XPointer schemes element and xmlns. In addition, There is a Gexslt-specific scheme: gexslt:xpath.

## Invoking the XPointer Framework

To invoke the XPointer Framework, you must first create an instance of `XM_XPOINTER_XPATH`. This creates the XPointer Framework, but no schemes are available - only shorthand pointers.

The next step is to call `evaluate`. This takes two arguments. The second argument is the XML resource (well-formed document or external parsed entity, represented as an `XM_XPATH_DOCUMENT)`. The first argument is the pointer represented as a `STRING`.

The pointer should have no escaping, other than XPointer carat escaping, within it. So if you are starting with an `UT_URI`, simply calling it's `fragment` routine is not sufficent. Instead, you should call the `fragment_item` routine, to get an `UT_URI_STRING`, and call that object's `decoded_utf8` (??? Is this right, Franck?).

Calling `evaluate` will set `value` to a non-Void `XM_XPATH_VALUE`. If an XPointer error occured, then this object will have `value` set to an `XM_XPATH_INVALID_VALUE` in the case of an XPointer Framework syntax error, or an `XM_XPATH_EMPTY_SEQUENCE` (marked in error) if a shorthand pointer failed to locate any resources.

XPointer schemes don't signal XPointer errors - instead `value` will be set to an `XM_XPATH_EMPTY_SEQUENCE`.

If a shorthand pointer, or an element scheme find a resource, then they set `value` to an `XM_XPATH_SINGLETON_NODE`. The gexslt:xpath scheme sets `value` to an `XM_XPATH_SEQUENCE_EXTENT`, as it is possible for it to return any XPath sequence.

## XPointer schemes

If your pointer may contain anything other than a shorthand pointer, then you must configure the `XM_XPOINTER_XPATH` object with any schemes that you may wish to use. This is done by creating instances of descendants of `XM_XPOINTER_XPATH_SCHEME`, and passing them as the argument of `XM_XPOINTER_XPATH`'s `register_scheme` routine.

Schemes provided in the library:

`XM_XPOINTER_XPATH_XMLNS_SCHEME`
  The W3C xmlns scheme for defining namespace bindings.
`XM_XPOINTER_XPATH_ELEMENT_SCHEME`
  The W3C element scheme for finding a single element via a shorthand pointer and/or by stepwise navigation.
`XM_XPOINTER_XPATH_XPATH_SCHEME`
  The gexslt:xpath scheme.

## The gexslt:xpath scheme

The XPointer scheme, which is an unapproved W3C working draft, is not implemented by this library. This is because:

1. It uses XPath 1.0, whereas this library uses XPath 2.0. This means we could not make a compliant implementation.
2. A lot of work is needed to extend XPath for this scheme.
3. The benefits compared with an XPath 2.0 scheme seem slim (only text-editing applications are likely to see a clear benefit, and the implementations of the XPath data model in this library are read-only).
4. It doesn't look likely that it will ever be approved.

Instead, I have implemented a scheme which takes an XPath 2.0 expression as it's pointer. This has a local name of "xpath", and a namespace URI of "http://www.gobosoft.com/eiffel/gobo/gexslt/extension". Therefore, you have to declare a prefix, using the xmlns scheme, before you can use this scheme.

So, in order to find the third child of the document element, conditional upon it having an attribute named "test", then you will want a pointer that looks something like: "xmlns(gexslt = http://www.gobosoft.com/eiffel/gobo/gexslt/extension)gexslt:xpath(/*[1]/*[3][@test]".

Within a URI, the square brackets and spaces will need percent-encoding, so this example should actually read: "xmlns(gexslt%20=%20http://www.gobosoft.com/eiffel/gobo/gexslt/extension)gexslt:xpath(/*%5B1%5D/*%5B3%5D%5B@test%5D". although the spaces can always be omitted.

Of course, if you want to use any namespace prefixes (other than "xml", which is always declared) within your XPath expression, then you will need to declare them also using further xmlns statements.

## The extended error API

When you create the `XM_XPOINTER_XPATH`, the `make` procedure takes a single `BOOLEAN` argument. If you pass this as False, then you get the standard XPointer Framework error reporting, as described above. If you instead set it to True, and if no resources were found, then `value` will be set to a value in error, as reported by the last scheme processor which detected a syntax or semantic error in it's scheme data.