Use of JET setVariable to store commonly used XPath expressions [message #53855] |
Sat, 13 December 2008 07:49  |
Eclipse User |
|
|
|
Hello,
This post is a sort of follow on from:
http://dev.eclipse.org/newslists/news.eclipse.modeling.m2t/m sg00706.html
In my current project using JET I am finding that I use the same
expressions over and over again throughout numerous files. Some of these
expressions are quite long. In order to increase maintainability of my
templates, I require a way to store an XPath expression as a global
variable. Clearly, c:setVariable is what I need. However, I'm running into
a couple of issues...
In my main.jet file, I would like to declare the following variable:
<c:setVariable var="allEntityAttributes"
select=" //namedElements[self::Entity][@name='{$entityName}']/feature s[self::Attribute] "
/>
The issues are as follows:
- The select expression is evaluated as an XPath expression because of the
nature of setVariable, however I just want to store the actual string it
represents.
Adding spaces in this way:
select="
//namedElements[self::Entity][@name='{$entityName}']/feature s[self::Attribute]
"
could work, however, this expression is declared right at the top of my
main.jet. Consequently, the variable $entityName does not yet exist (it is
assigned later on when processing elements). When $entityName does not
exist, not only are errors thrown but the variable $allEntityAttributes is
not assigned any value and as a result cannot be used.
Are there any ways to achieve the functionality I require? I simply want
to store an XPath expression string (which itself includes variables) as a
variable so it can be reused many times.
Thanks,
Mark
|
|
|
Re: Use of JET setVariable to store commonly used XPath expressions [message #53880 is a reply to message #53855] |
Sun, 14 December 2008 17:34   |
Eclipse User |
|
|
|
Originally posted by: tmothymarc.freenet.de
Mark,
try it with the default string('xyz') function of the XPath 1.0 spec. I
don't know whether this works, but it might be another possibility.
Timothy
Mark Wood schrieb:
> Hello,
>
> This post is a sort of follow on from:
>
> http://dev.eclipse.org/newslists/news.eclipse.modeling.m2t/m sg00706.html
>
> In my current project using JET I am finding that I use the same
> expressions over and over again throughout numerous files. Some of these
> expressions are quite long. In order to increase maintainability of my
> templates, I require a way to store an XPath expression as a global
> variable. Clearly, c:setVariable is what I need. However, I'm running
> into a couple of issues...
>
> In my main.jet file, I would like to declare the following variable:
>
> <c:setVariable var="allEntityAttributes"
> select=" //namedElements[self::Entity][@name='{$entityName}']/feature s[self::Attribute] "
> />
>
> The issues are as follows:
>
> - The select expression is evaluated as an XPath expression because of
> the nature of setVariable, however I just want to store the actual
> string it represents.
>
> Adding spaces in this way:
> select="
> //namedElements[self::Entity][@name='{$entityName}']/feature s[self::Attribute]
> "
>
> could work, however, this expression is declared right at the top of my
> main.jet. Consequently, the variable $entityName does not yet exist (it
> is assigned later on when processing elements). When $entityName does
> not exist, not only are errors thrown but the variable
> $allEntityAttributes is not assigned any value and as a result cannot be
> used.
>
> Are there any ways to achieve the functionality I require? I simply want
> to store an XPath expression string (which itself includes variables) as
> a variable so it can be reused many times.
>
> Thanks,
>
> Mark
>
|
|
|
|
Re: Use of JET setVariable to store commonly used XPath expressions [message #53923 is a reply to message #53855] |
Mon, 15 December 2008 10:32   |
Eclipse User |
|
|
|
Mark:
Out of the box, JET doesn't have a way to dynamically evaluate an XPath
expression stored as a string. But, I've crafted an XPath function that can
do it.
You then have two steps:
1) store your XPath expression as a string:
2) use the custom Xpath function to evaluate it:
Storing your XPath expression as a string
-----------------------------------------
You want to store the unevaluated XPath expression, so, use a String
expression - that is, surround the expression in quotes. Of course, you are
using quotes in the expression, and the attribute itself is using quotes, so
you need to do a little escaping (this works in JET 0.9 and later). Here's
your expression, respun:
<c:setVariable var="allEntityAttributes"
select=" \"
//namedElements[self::Entity][@name=$entityName]/features[se lf::Attribute]
\" "
/>
(I've made a small change in your expression around the $entityName variable
to remove the {} and the single quotes.)
An XPath funciton to evaluate a string as an XPath
---------------------------------------------------
Declare the function using the xpathFunctions extension point. Here's a
snippet from plugin.xml:
<extension
point="org.eclipse.jet.xpathFunctions">
<function
implementation="test.jet.defered.xpaths.functions.EvalFunction "
maxArgs="1"
minArgs="1"
name="eval">
</function>
And, here's the function itself...
package test.jet.defered.xpaths.functions;
import java.util.List;
import org.eclipse.jet.xpath.Context;
import org.eclipse.jet.xpath.XPath;
import org.eclipse.jet.xpath.XPathException;
import org.eclipse.jet.xpath.XPathExpression;
import org.eclipse.jet.xpath.XPathFactory;
import org.eclipse.jet.xpath.XPathFunction;
import org.eclipse.jet.xpath.XPathFunctionWithContext;
import org.eclipse.jet.xpath.XPathRuntimeException;
import org.eclipse.jet.xpath.XPathUtil;
import org.eclipse.osgi.util.NLS;
public class EvalFunction implements XPathFunction, XPathFunctionWithContext
{
private Context context;
@Override
public Object evaluate(List args) {
// one and only argument is a string containing an unparsed XPath
expression
String unparsedXPath = XPathUtil.xpathString(args.get(0));
// create an XPath instance, on configure it from the current XPath
context.
XPath xpath =
XPathFactory.newInstance().newXPath(context.getAnnotationMan ager());
xpath.setXPathFunctionResolver(context.getFunctionResolver() );
xpath.setXPathVariableResolver(context.getVariableResolver() );
try {
// compile and return the result of the XPath
XPathExpression compiledXPath = xpath.compile(unparsedXPath);
return compiledXPath.evaluate(context.getContextNode());
} catch (XPathException e) {
throw new XPathRuntimeException(NLS.bind("XPath compilation error: %1.
Expression: %2", e.getLocalizedMessage(), unparsedXPath), e);
}
}
@Override
public void setContext(Context context) {
// save the current XPath context - used by evaluate(List)
this.context = context;
}
}
I declared the function right in the JET project I was testing with. But,
you can do this in another plug-in project if you wish (lets you re-use the
function).
Using the function
------------------
<%-- ensure the variables used are set --%>
<c:setVariable var="entityName" select=" 'SomeEntityName' "/> <%-- not
the single quotes --%>
<c:iterate select="eval($allEntityAttributes)" var="attr" >
....
</c:iterate>
Any votes for adding this to JET itself?
Paul
|
|
|
|
|
Powered by
FUDForum. Page generated in 0.06065 seconds