A simple example of using XPath

The XPath language allows the selection of sets of nodes from a DOM tree in a simple way. Nodes are returned in a NodeList collection object and can be iterated using FOR OBJECT.

In this example, using our example document books.xml, we will return the titles of books tagged with a "cat" attribute of "classics" using the XPath expression

"//book[@cat='classics']/title/text()"

There are many resources on the Web that explain XPath grammar.

DIM OBJECT x, OBJECT p, OBJECT list, OBJECT i, OBJECT doc, OBJECT xp
OBJECT x = CREATE "dynamic", "klibxml"
OBJECT p = x.CreateParser()
p.DoNamespaces = FALSE
p.validationScheme = _VAL_SCHEME_NEVER
p.LoadExternalDTD = FALSE
p.parse("books.xml")
OBJECT doc = p.Document
OBJECT xp=doc.createXPath()
OBJECT list = xp.evaluate("//book[@cat='classics']/title/text()")
FOR OBJECT i IN list
	PRINT i.NodeValue$
NEXT OBJECT i
OBJECT list = NULL
OBJECT p = NULL
OBJECT x = NULL

To do a search relative to a particular node in the DOM you can specify the start position with SetCurrentNode().

Namespaces are handled by the application calling RegisterNS() to map a prefix used in the XPath expression to the URI of the namespace. If the namespace URI is blank in this method then it will be interpreted as the default namespace URI for the document.

In this example document the XPath expression needed to match the <ex> tags will have to allow fore the fact that the whole document is in a default namespace with a URI of "http://examples.schemas.Keyloop.com".

<examples xmlns="http://examples.schemas.keyloop.com">
	<ex>one</ex>
	<ex>two</ex>
</examples>

The expression will need to prefix any tags with some prefix that matches back to that URI e.g.

"//e:ex"

and the prefix of "e" needs to be registered with the XPath object before we can evaluate it with

xp.RegisterNS("e", "")

taking advantage of the fact that a blank URI in this call will be assumed to mean the document root default namespace. You could use the explicit string "http://examples.schemas.Keyloop.com" if you want though.