[
https://issues.apache.org/jira/browse/JXPATH-86?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Matt Benson resolved JXPATH-86.
-------------------------------
Resolution: Won't Fix
Another attempt to interpret everything going on here:
JXPath has some pecularities about its implementation of the XPath 1.0
standard; this is not entirely surprising because there is not a precise
correspondence between some parts of the respective structures of Java object
graphs and XML documents. Ultimately I am referring to my concept of
collection collapsing above. Searching XPath information on the web, I can
find nothing that contradicts the following statement: "an XPath is most
correctly interpreted as a set of nodes." If we abide by this interpretation,
we can infer that any function designed to deal with an XPath result as a
single value can be considered an augmentation; its expected behavior is
therefore open-ended. When we call such methods as selectNodes(), iterate(),
or iteratePointers() against an XPath that points to an array or Collection
("collection"), it is reasonable that we receive the values of or pointers to
the component elements of that collection as our result, and this is indeed
what occurs. It is similarly reasonable that when a collection appears as an
intermediate component of a path it is expanded to its contents inline and
subsequent path elements are resolved against the collection contents rather
than the collection itself. Using these rules we can understand that
"/array/*" refers to the _children_ of the components of "/array" rather than
to the components themselves. To select "/array"'s components we would use
simply "/array". Now that we understand that a collection refers to its
components when it occurs in an XPath, we understand that, with regard to
normal (multi-result) XPath selection, "/array/." and "/array" are equivalent.
The only confusion then remaining is the discrepancy between the single-result
API methods getValue()/getPointer() versus the multi-result querying
techniques. Having already established that the single-result versions are by
definition based on assumptions we understand that when we choose to use them
we are agreeing to abide by whatever rules they may impose; e.g.: if there are
multiple results, we will return the first. A rule which preempts this
well-known rule is then this: when an xpath expression refers to a single
collection, these single-result methods will return the pointer or value of the
collection unexpanded. This is simply a convention of JXPath, whose intent
was, I'm sure, benign, though it may seem to result in inconsistent behavior.
Ultimately my diagnosis is that when using getValue()/getPointer() you must
forego some assumptions of consistency in favor of known quirks of the
implementation. I expect by now that these are entrenched in existing systems
to the degree that it would be a far greater evil to attempt to "correct" this
(again these methods are beyond any expectations imposed by the specification,
IMHO, so "correction" is a very subjective term) than to live with it. If you
want consistency my recommendation is to stick to the iteratation/multi-result
idiom which I interpret as being more "pure."
> Children returned instead of self for arrays when using . selector
> ------------------------------------------------------------------
>
> Key: JXPATH-86
> URL: https://issues.apache.org/jira/browse/JXPATH-86
> Project: Commons JXPath
> Issue Type: Bug
> Affects Versions: 1.2 Final
> Reporter: Adam Crume
>
> The . selector should always return the context node, and the * selector
> should return child elements. However, this doesn't work for arrays:
> JXPathContext context = JXPathContext.newContext(new HashMap());
> context.setValue("array", new String[] {"one", "two", "three"});
> context.setValue("array2", new String[][] { {"a", "b"}, {"c", "d"}});
> context.setValue("person", new Person("Bob", 25));
> String[] paths = {"/array", "/array/.", "/array/*", "/person", "/person/.",
> "/person/*"};
> for(int i = 0; i < paths.length; i++) {
> Pointer pointer = context.getPointer(paths[i]);
> System.out.println(pointer.asPath());
> Object value = context.getValue(paths[i]);
> System.out.println(value);
> System.out.println();
> }
> This produces the following output:
> /[EMAIL PROTECTED]'array']
> [Ljava.lang.String;@59b659b6
> /[EMAIL PROTECTED]'array'][1]
> one
> /[EMAIL PROTECTED]'array'][1]/bytes[1]
> 111
> /[EMAIL PROTECTED]'person']
> [EMAIL PROTECTED]
> /[EMAIL PROTECTED]'person']
> [EMAIL PROTECTED]
> /[EMAIL PROTECTED]'person']/age
> 25
--
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]