Moddy Te'eni wrote:
Thank you very much for your patience.
I'll try to be more thorough this time.
I want to give my users the ability to write XPath expressions that refer to
some XML input. There is no XSLT involved, just displaying the results.
The user should be abe to use some pre-defined variables: some are global,
and some depend on the document meta-data and on other things that i am able
to calculate. For example, i want to user to write "/pers...@name ==
$USERNAME]/@password".
My plan is to use XPathEvaluator::evaluate(), but before calling it I want
to change the context node so that $USERNAME will be meaningful. Reading
xpath documentaion in w3c, i thought there would be some obvious way to do
such things.
How variables are bound is not specified in the XPath recommendation,
since it's specific to the environment in which XPath is implemented.
At first I thought I can overcome it by changing the syntax a little and
introducing a function, e.g.
"/pers...@name == env.getValue("USERNAME")]/@password"
But I realized that I can't write this function - my code should be
thread-safe, and each thread may have different users, so there is no way I
can find the user name, short of using Thread-Local Storage.
I'm afraid I don't understand this. Each thread of execution will need
its own instance of XPathEvaluator, so you can extend the classes used
by XPathEvaluator to define the correct variable bindings.
Let me explain a bit about how variable binding works in Xalan-C, and
hopefully you can figure out how you need to implement it in your
environment.
There is an abstract base class, called XPathExecutionContext that
defines much of the run-time environment requirements for executing
XPath expressions. The member function
XPathExecutionContext::getVariable() can be implemented to define
variable bindings. If you look at the default implementation of this
base class, called XPathExecutionContextDefault, you'll see it returns
an "unknown" object, since the default implementation doesn't know
anything about variable binding. AS another point of reference, if you
look at the version of this function in
StylesheetExecutionContexDefault, you'll see it uses the XSLT variables
stack to resolve variables.
You could derive a class from XPathExecutionContextDefault and override
getVariable() to handle the specific variables you're interested in
resolving. If you get a request for a variable that you don't know
about, you can defer to the base class implementation.
Unfortunately, XPathEvaluator is not really meant to be extensible, but
we would enhance it for the purposes of extending the execution
environment. My recommendation right now would be for you to simply
copy the XPathEvaluator code and create your derivative of
XPathExecutionContextDefault.
I hope this makes sense, and please reply back if you have more questions.
Another way is, I think, to add things to the DOM instead of variables. then
the user may write
"/pers...@name == /envValues/@USERNAME)]/@password"
This is ugly, though. So I still hope I can avoid it.
Yes, that would be ugly, and would require a unique copy of the source
tree for each user.
Dave