Hello Sebastian,
On 17/01/14 09:24, Wiemer, Sebastian wrote:
Hello BaseX users and BaseX team,
I come across the following problem very often: I write an XQuery function (e.g. in a web application) which contains long and complicated XPath expressions. (BTW: is it really faster to use the path $a/b/c/d[@id=$id] than just use $a//d[@id=$id] ?)
Most likely, yes. Using // means that there is a look-up of every child element, which (depending on your data) could be pretty huge. Using /a/b/c/d limits the search to the actual needed subtrees.
At times I misspell an element name oder make some other mistake that would yield in zero nodes selected. Up to this point I use fn:trace() to guess where I made the mistake, but this takes time.
Would it be possible (or is there a feature present, that I am not aware of) to evaluate XPath expressions in XQuery functions right in the BaseX editor? (I know I can use another editor tab, copy all "import module“ declarations needed from the current file, declare variables for the parameters, copy the function (because it is not in a repo-module, I can’t import it, or can I?) and then call the function and return the path. But this is also time consuming.)
I don't know about that in detail (I am sure Christian will answer you more knowledgeable than I can), but although this sounds like a very nice feature it also does sound quite complicated to implement. If you want to execute a value like $a/b/c/d[@id=$id] you have to know all the context variables (like $a and $id) and this can be arbitrarily complex. In the end, this sounds to me like you need a complete debugging framework - With stepping, watching variables and similar features. Additionally, each statement could be executed multiple times, e.g.
for $a in /books/book return $a/title
So how would you decided what value to show?
If there is no better way, I would like to request the following feature: an annotation (or any other means suitable) to supply sample values for function parameters, which will then be executed.
declare %basexgui:sample-data(„arg1“,“{doc(‚file.xml')}“) (: where file.xml would contain suitable example data :) %basexgui:sample-data(„arg2“,“{10}“) (: :) function local:example($arg1 as item()*,$arg2 as xs:integer) { (: the code is just a meaningless example! :) let $foo:=$arg1[position()=$arg2] let $bar:=$arg1/bar[buzz] return $bar/buzz };
In the editor, when the cursor is on $arg1 (or selected or somehow otherwise recognized as XPath expression), the expression (the function to this point?) could be evaluated and the value shown in an output window. It would be even cooler, if the count of matching elements in an XPath expression would be shown while typing, like in a live-search.
Is this feasible?
Although this solution does not exist currently, you can do it differently. Although this might be a bit longer, in the end I'd guess you will have better code. Normally you would do something like that with Unit testing and since some time BaseX also supports Unit Testing with XQuery. So instead of giving some values via annotations, you write separate unit tests using these arguments and you can always validate them. The advantage is that you would certainly delete the annotations when going live, whereas you can always keep your unit tests and hence you could also run them later, always making sure your function is delivering the expected results. For some more documentation see our wiki at https://docs.basex.org/wiki/Unit_Module
Cheers, Dirk