You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@commons.apache.org by Dmitri Plotnikov <dm...@apache.org> on 2003/02/19 02:05:17 UTC

Re: [JXPATH] parentContext not used for XPath starting with '../'

Peter,

I have added support for relative contexts.  Here's an excerpt from the
documentation:

<quote>
If you need to evaluate multiple paths relative to a certain node in the
object graph, you might want to create a relative JXPathContext.

First obtain the pointer for the location that is supposed to define the
relative context. Then obtain the relative context by calling
context.getRelativeContext(pointer).


 JXPathContext context = JXPathContext.newContext(bean);

 Pointer addressPtr = context.getPointer("/employees[1]/addresses[2]");

 JXPathContext relativeContext =
              context.getRelativeContext(addressPtr);

 // Evaluate relative path
 String zipCode = (String)relativeContext.getValue("zipCode");

 // Evaluate absolute path
 String name = (String)relativeContext.getValue("/employees[1]/name");

 // Use the parent axis to locate the employee for the current address
 Double salary = (Double)relativeContext.getValue("../salary");

</quote>

This feature is available as of the nightly build of Feb 19.

I hope this helps.

- Dmitri


----- Original Message -----
From: "Dmitri Plotnikov" <dp...@yahoo.com>
To: "Jakarta Commons Users List" <co...@jakarta.apache.org>
Sent: Friday, February 14, 2003 10:13 AM
Subject: Re: AW: [JXPATH] parentContext not used for XPath starting with
'../'


> Peter,
>
> --- Peter Neumcke <pn...@virbus.de> wrote:
> > Hi Dimitri,
> > thanks for your reply.
> >
> > In my case, I've got a strict tree of Objects with only on Root
> > Object.
> If there was a property on every child called "parent" or something
> like that, you could use that property instead of the ".." axis.
>
> > As far as I understand it, there's no way to evaluate an XPath
> > starting with
> > '../' on a context somewhere down that tree.
> That's correct.
>
> > There's something, I still don't really understand: if '../' can't be
> > evaluated because there's no way to get the parent node, how is an
> > absolute
> > XPath like '/foo/bar' evaluated? Does this involve getting the parent
> > context or is it evaluated against the current context?
> The initial slash in the path indicates the root node, not its parent.
>
> > What options do I have for a large tree of objects, where relative
> > XPath-Expressions need to get the parent node?
> > * always use absolute XPath expressions (I saw that expressions are
> > cached
> > using soft references, but isn't this approach rather ineffective?)
> Right. It's just the last resort for applications that cannot do their
> own caching of expressions for some reason.
>
> > * build my own 'chain of context' and evaluate starting '../' myself,
> > only
> > invoke JXPath with cleand up XPath expression
> This can indeed be done.  You would pretty much have to override
> everything starting with the JXPathContext, because you would need a
> custom Compiler that would allocate a custom LocationPath, which would
> then allocate a custom ParentContext.
>
> > Did I miss an easy option of customizing JXPath to get the desired
> > effects?
> Let me think about adding the notion of a relative context to JXPath
> itself.  This is the second or third time I hear this requirement from
> different people.  Maybe it is time to take it seriously.  How about
> something like:
>
>    context.getRelativeContext(pointer);
>
> Let me think about it.
>
>
> > Thanks for your help,
> > Peter
> Thanks for bringing up this issue.
>
> - Dmitri
>
> >
> >
> > > -----Ursprungliche Nachricht-----
> > > Von: Dmitri Plotnikov [mailto:dplotnik@yahoo.com]
> > > Gesendet: Mittwoch, 12. Februar 2003 22:33
> > > An: Jakarta Commons Users List
> > > Betreff: Re: [JXPATH] parentContext not used for XPath starting
> > with
> > > '../'
> > >
> > >
> > > Peter,
> > >
> > > The parent-child relationship between contexts has nothing to do
> > with
> > > the parent-child relationship between beans.  The child context
> > > inherits variables, extension functions, locale etc from the parent
> > > context, but nothing about the root bean.
> > >
> > > In JXPath there is no mechanism for the traversal from the
> > > root bean to
> > > its ancestors.
> > >
> > > Here's an excerpt from the documentation that explains how
> > > the parent::
> > > axis is implemented:
> > >
> > > <quote>
> > >    In DOM/JDOM the definition of a node's parent is clear: a Node
> > > always  points to its parent. XML is a strict tree, so there always
> > > exactly one parent for every node except the root.
> > >
> > >    With other models the situation is more complex. The model can
> > no
> > > longer be described as a tree.  In many cases it is a
> > > complicated graph
> > > with many paths to the same node and even referential cycles
> > > where node
> > > A is node B's child, but also node B is node A's child. Even if the
> > > graph is a strict tree, a node of that tree may not have a pointer
> > to
> > > its parent.
> > >
> > >    Because of all these issues, JXPath abandons the static notion
> > of a
> > > parent/child relationship in favor of a dynamic one.  When an XPath
> > is
> > > evaluated, the engine performs a series of searches and
> > > computations in
> > > so called evaluation contexts.  For example, when the "/foo/bar"
> > path
> > > is evaluated, JXPath first looks for a node named "foo" in the root
> > > evaluation context. If such a node is found, the interpreter forms
> > a
> > > new context for the discovered node and searches for a node
> > > named "bar"
> > > in that context.
> > >
> > >    This chain of contexts is used in JXPath to define the
> > parent-child
> > > relationship. Parent is the base node of the previous evaluation
> > > context in the chain.  A more appropriate name for the "parent::"
> > axis
> > > would then be "step back".
> > >
> > >    Consider this example.  The evaluated path is
> > > "foo//bar/../baz".  In
> > > the process of evaluating of this path, the engine will walk the
> > graph
> > > forming chains of context like "/foo/a/b/c/bar".  Once a node with
> > the
> > > name "bar" is found, the engine will "step back": in our case it
> > will
> > > go back to the "/foo/a/b/c" context and then look for the
> > > node with the
> > > name "baz" in that context.
> > > </quote>
> > >
> > > I hope this explanation helps.
> > >
> > > - Dmitri
> > >
> > >
> > > --- Peter Neumcke <pn...@virbus.de> wrote:
> > > > Hi people,
> > > > I have a question, which I couldn't answer by reading the docs.
> > > >
> > > > What happens, if the XPath uses '../' at the beginning to
> > > go back one
> > > > step?
> > > > Will the parentContext be used to evaluate the XPath?
> > > >
> > > > Here's my testcode (adapted from the original test code):
> > > >
> > > >     public void testRootHandling(){
> > > >         if (!enabled){
> > > >             return;
> > > >         }
> > > >         System.out.println("testing root handling start");
> > > >         JXPathContext context = JXPathContext.newContext(bean);
> > > >         JXPathContext nestedContext =
> > > > JXPathContext.newContext(context,
> > > > bean.getNestedBean());
> > > >         testGetValue(nestedContext, "/boolean", Boolean.FALSE);
> > > >         System.out.println("accessing /boolean in nested context
> > > > worked!");
> > > >         testGetValue(nestedContext, "../boolean", Boolean.FALSE);
> > > >         System.out.println("accessing ../boolean in nested
> > context
> > > > worked!");
> > > >     }
> > > >
> > > > The corresponding output:
> > > > test.jxpath:
> > > >      [echo] Running JXPath tests ...
> > > >      [java] .testing root handling start
> > > >      [java] accessing /boolean in nested context worked!
> > > >      [java] E.....
> > > >      [java] Time: 1.578
> > > >      [java] There was 1 error:
> > > >      [java] 1)
> > > > testRootHandling(org.virbus.websheet.jxpath.JXPathTestCase)
> > > >      [java] org.apache.commons.jxpath.JXPathException: No value
> > for
> > > > xpath:
> > > > ../boolean
> > > >      [java]     at
> > > >
> > > org.apache.commons.jxpath.ri.JXPathContextReferenceImpl.getVal
> > > ue(JXPathConte
> > > > xtReferenceImpl.java:206)
> > > >      [java]     at
> > > >
> > > org.apache.commons.jxpath.ri.JXPathContextReferenceImpl.getVal
> > > ue(JXPathConte
> > > > xtReferenceImpl.java:200)
> > > >      [java]     at
> > > >
> > > org.virbus.websheet.jxpath.JXPathTestCase.testGetValue(JXPathT
> > > estCase.java:3
> > > > 99)
> > > >      [java]     at
> > > >
> > > org.virbus.websheet.jxpath.JXPathTestCase.testRootHandling(JXP
> > > athTestCase.ja
> > > > va:178)
> > > >      [java]     at
> > > > sun.reflect.NativeMethodAccessorImpl.invoke0(Native
> > > > Method)
> > > >      [java]     at
> > > >
> > > sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccess
> > > orImpl.java:39
> > > > )
> > > >      [java]     at
> > > >
> > > sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMeth
> > > odAccessorImpl
> > > > .java:25)
> > > >
> > > >
> > > > It looks like it's possible to go back using '/' at the
> > beginning,
> > > > but using
> > > > '../' doesn't work. Has anyone got some advice?
> > > > I'm using commons-jxpath-1.0
> > > >
> > > > I'm new to JXPath, so excuse me, if I understood something wrong
> > or
> > > > if
> > > > there's an obvious solution.
> > > >
> >
> >
> === message truncated ===


---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org