The XPath processors are highly popular for extracting parts of XML documents returned from various services. However, if the XML document uses namespaces, the processor does not support this. Normally you would have to register the namespace before executing the xpath expression, but this is not enabled through our processor.
One way to allow this is to add a configuration setting on the processor where a dialogue pops up for registering namespaces with a prefix. Then the xpath can have expressions like //tav:soup/html:table to select from two namespaces tav and html.
Reported by Stephen Crouch to taverna-users on 2007-02-21:
When using the XPath query processor (XPath_From_Text), it seems you cannot
specify a namespace for those queries when necessary.
e.g. the following XML (actually a verbatim response from a Grimoires
findService request):
<serviceList xmlns="urn:uddi-org:api_v2">
<serviceInfos>
<serviceInfo businessKey="ec29f107-6ab1-4eac-8e86-e878a7d9bceb"
serviceKey="30502c0a-7f50-48e5-93f5 2f33983c8364">
<name>GridSAM</name>
</serviceInfo>
</serviceInfos>
</serviceList>
To specify a query to pick up the serviceKey of serviceInfo you'd do
something like:
//serviceList/serviceInfos/serviceInfo[@serviceKey]
This style of query can be easily entered into the Taverna XPath query
processor. If you try to run the attached mini workflow which tries this,
it fails. To get this to work you'd also need to reference the
"urn:uddi-org:api_v2" namespace for each entry. Ordinarily, with other
XPath implementations I would have specified the namespaces like this (on
one line):
declare namespace nsx='urn:uddi-org:api_v2';
//nsx:serviceList/nsx:serviceInfos/nsx:serviceInfo[@serviceKey]
(Where there could be multiple 'declare namespace' declarations). But it
would seem that Taverna seems to ignore the namespace declaration. Is this
a bug or an omission in Taverna, or is there an accepted way to specify
namespaces?
There is a workaround which involves writing quite cumbersome xpath expressions for just checking the local name of the XML elements:
is almost the same as
So the trick is to use *[local-name(.)='tagName' instead of tagName. In effect it means 'Any element, which local name of the same element matches the string tagName'. Note that this hack would pick up any elements matching tagName, without regarding the namespace.
(Thanks to Jose Maria Fernandez Gonzales for suggesting this workaround)