Adam,

JXPath is in fact incapable of doing what you want it to do.  Before a
collection is passed to an extension function, it undergoes some
conversions, which make it unmodifiable.  JXPath should of course throw
an exception in this case.  I have added that exception and will check
that new code in tonight.

The rationale for this behavior is that from JXPath's perspective an
extension function cannot take a collection by reference. Arguments of
an extension function are either primitive values or "node sets", which
are really results of search.  JXPath finds all nodes matching the
path, loads them into a list and then passes the list to the function. 
Consider for example this:

   context.getValue("size(//foo[bar = 3])")

>From this example it should be clear that the argument of the function
is in fact an unmodifiable collection - results of search.  

We could of course do something special for variables, but then the
extension function's code would have to be aware of the difference
between variables and general node sets.  I think we should avoid this
implicit difference.

What you could do to add a node to the collection is call
createPathAndSetValue() with a path like "$myList[24]".

Thanks for bringing this issue up - I should document it.

- Dmitri


--- Adam J Chesney <[EMAIL PROTECTED]> wrote:
> Hi,
> 
> Attached is a small test program that simply defines a Context like
> this:
> 
>  Object o = new Object ();
>  JXPathContext context = JXPathContext.newContext( o );
>  context.getVariables().declareVariable("myList", new ArrayList() );
> 
>  FunctionLibrary library = new FunctionLibrary ();
>  library.addFunctions( new ClassFunctions ( List.class, "list" ) );
>  context.setFunctions( library );
> 
> The output from executing several XPath expressions on it is thus:
> 
> getValue("list:size($myList)") returns: 0
> 
> getValue("list:add($myList, 'hello')") returns: true
> 
> getValue("list:size($myList)") returns: 0
> 
> getValue("$myList") returns: []
> 
> I would expect the String 'hello' to be added to the list, and
> therefore the second call to size should return 1.
> 
> Am I doing something wrong here?
> 
> Cheers,
> 
> Adam
> 
> =====================================================
>  
> Tel:   (+44) 117 908 1254 (Direct)
> Mobile (+44) 7780 962 961
> email: [EMAIL PROTECTED]
>  
> This communication is intended solely for the addressee and is
> confidential.
> If you are not the intended recipient, any disclosure, copying,
> distribution
> or any action taken or omitted to be taken in reliance on it, is
> prohibited
> and may be unlawful.
>  
> Although this e-mail and any attachments are believed to be free of
> any
> virus, or any other defect which might affect any computer or IT
> system into
> which they are received and opened, it is the responsibility of the
> recipient to ensure that they are virus free and no responsibility is
> accepted by Multicom Products Limited for any loss or damage arising
> in any
> way from receipt or use thereof.
> > package test;
> 
> import org.apache.commons.jxpath.*;
> import java.util.*;
> 
> /**
>  * <p>Title: </p>
>  * <p>Description: </p>
>  * <p>Copyright: Copyright (c) 2003</p>
>  * <p>Company: </p>
>  * @author unascribed
>  * @version 1.0
>  */
> 
> public class Test2
> {
> 
>   public static void main(String[] args)
>     {
>       try
>       {
>       Object o = new Object ();
>       JXPathContext context = JXPathContext.newContext( o );
>       context.getVariables().declareVariable("myList", new ArrayList() );
> 
>       FunctionLibrary library = new FunctionLibrary ();
>       library.addFunctions( new ClassFunctions ( List.class, "list" ) );
>       context.setFunctions( library );
> 
>       getValue (context, "list:size($myList)");
>       getValue (context, "list:add($myList, 'hello')");
>       getValue (context, "list:size($myList)");
>       getValue (context, "$myList");
>       }
>       catch (Exception e1)
>       {
>       e1.printStackTrace();
>       }
>   }
> 
>   public static Object getValue ( JXPathContext context, String xpath
> )
>   {
>     Object obj = context.getValue( xpath );
>     System.out.println("getValue(\"" + xpath + "\") returns: " +  obj
> );
>     return obj;
>   }
> 
> }
> >
---------------------------------------------------------------------
> To unsubscribe, e-mail: [EMAIL PROTECTED]
> For additional commands, e-mail: [EMAIL PROTECTED]


__________________________________________________
Do you Yahoo!?
Yahoo! Mail Plus - Powerful. Affordable. Sign up now.
http://mailplus.yahoo.com

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to