dmitri 2003/01/24 17:50:37
Modified: jxpath/src/java/org/apache/commons/jxpath JXPathContext.java
jxpath/src/java/org/apache/commons/jxpath/ri Compiler.java
jxpath/src/java/org/apache/commons/jxpath/ri/compiler
CoreFunction.java CoreOperation.java
jxpath/src/java/org/apache/commons/jxpath/ri/model/beans
LangAttributePointer.java
jxpath/src/java/org/apache/commons/jxpath/xml
DocumentContainer.java
jxpath/src/test/org/apache/commons/jxpath/ri
JXPathCompiledExpressionTest.java
jxpath/src/test/org/apache/commons/jxpath/ri/compiler
CoreFunctionTest.java
jxpath/src/test/org/apache/commons/jxpath/ri/model
BeanModelTestCase.java
jxpath/xdocs users-guide.xml
Added: jxpath/xdocs release-notes-1.1.xml
Log:
Added support for the format-number() function
Revision Changes Path
1.13 +36 -5
jakarta-commons/jxpath/src/java/org/apache/commons/jxpath/JXPathContext.java
Index: JXPathContext.java
===================================================================
RCS file:
/home/cvs/jakarta-commons/jxpath/src/java/org/apache/commons/jxpath/JXPathContext.java,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -r1.12 -r1.13
--- JXPathContext.java 11 Jan 2003 05:41:22 -0000 1.12
+++ JXPathContext.java 25 Jan 2003 01:50:36 -0000 1.13
@@ -61,6 +61,8 @@
*/
package org.apache.commons.jxpath;
+import java.text.DecimalFormatSymbols;
+import java.util.HashMap;
import java.util.Iterator;
import java.util.Locale;
@@ -428,6 +430,7 @@
protected boolean lenient = false;
protected IdentityManager idManager;
protected KeyManager keyManager;
+ protected HashMap decimalFormats;
private static JXPathContext compilationContext;
@@ -552,7 +555,7 @@
* the context has a parent, returns the parent's locale.
* Otherwise, returns Locale.getDefault().
*/
- protected Locale getLocale() {
+ public Locale getLocale() {
if (locale == null) {
if (parentContext != null) {
return parentContext.getLocale();
@@ -563,7 +566,35 @@
}
return locale;
}
+
+ /**
+ * Sets DecimalFormatSymbols for a given name. The DecimalFormatSymbols can
+ * be referenced as the third, optional argument in the invocation of
+ * <code>format-number (number,format,decimal-format-name)</code> function.
+ * By default, JXPath uses the symbols for the current locale.
+ *
+ * @param name the format name or null for default format.
+ */
+ public void setDecimalFormatSymbols(
+ String name,
+ DecimalFormatSymbols symbols)
+ {
+ if (decimalFormats == null) {
+ decimalFormats = new HashMap();
+ }
+ decimalFormats.put(name, symbols);
+ }
+ /**
+ * @see #setDecimalFormat(String, DecimalFormatS)
+ */
+ public DecimalFormatSymbols getDecimalFormatSymbols(String name) {
+ if (decimalFormats == null) {
+ return null;
+ }
+ return (DecimalFormatSymbols) decimalFormats.get(name);
+ }
+
/**
* If the context is in the lenient mode, then getValue() returns null
* for inexistent paths. Otherwise, a path that does not map to
1.6 +5 -4
jakarta-commons/jxpath/src/java/org/apache/commons/jxpath/ri/Compiler.java
Index: Compiler.java
===================================================================
RCS file:
/home/cvs/jakarta-commons/jxpath/src/java/org/apache/commons/jxpath/ri/Compiler.java,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- Compiler.java 11 Jan 2003 05:41:22 -0000 1.5
+++ Compiler.java 25 Jan 2003 01:50:36 -0000 1.6
@@ -140,6 +140,7 @@
public static final int FUNCTION_ROUND = 27;
public static final int FUNCTION_NULL = 28;
public static final int FUNCTION_KEY = 29;
+ public static final int FUNCTION_FORMAT_NUMBER = 30;
/**
* Produces an EXPRESSION object that represents a numeric constant.
1.11 +51 -4
jakarta-commons/jxpath/src/java/org/apache/commons/jxpath/ri/compiler/CoreFunction.java
Index: CoreFunction.java
===================================================================
RCS file:
/home/cvs/jakarta-commons/jxpath/src/java/org/apache/commons/jxpath/ri/compiler/CoreFunction.java,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -r1.10 -r1.11
--- CoreFunction.java 19 Jan 2003 23:59:23 -0000 1.10
+++ CoreFunction.java 25 Jan 2003 01:50:36 -0000 1.11
@@ -61,7 +61,11 @@
*/
package org.apache.commons.jxpath.ri.compiler;
+import java.text.DecimalFormat;
+import java.text.DecimalFormatSymbols;
+import java.text.NumberFormat;
import java.util.Collection;
+import java.util.Locale;
import org.apache.commons.jxpath.JXPathContext;
import org.apache.commons.jxpath.JXPathException;
@@ -149,6 +153,8 @@
return "round";
case Compiler.FUNCTION_KEY :
return "key";
+ case Compiler.FUNCTION_FORMAT_NUMBER:
+ return "format-number";
}
return "unknownFunction" + functionCode + "()";
}
@@ -215,6 +221,9 @@
case Compiler.FUNCTION_CEILING:
case Compiler.FUNCTION_ROUND:
return false;
+
+ case Compiler.FUNCTION_FORMAT_NUMBER:
+ return args != null && args.length == 2;
}
return false;
@@ -304,6 +313,8 @@
return functionRound(context);
case Compiler.FUNCTION_KEY :
return functionKey(context);
+ case Compiler.FUNCTION_FORMAT_NUMBER :
+ return functionFormatNumber(context);
}
return null;
}
@@ -673,6 +684,42 @@
assertArgCount(1);
double v = InfoSetUtil.doubleValue(getArg1().computeValue(context));
return new Double(Math.round(v));
+ }
+
+ private Object functionFormatNumber(EvalContext context) {
+ int ac = getArgumentCount();
+ if (ac != 2 && ac != 3) {
+ assertArgCount(2);
+ }
+
+ double number =
+ InfoSetUtil.doubleValue(getArg1().computeValue(context));
+ String pattern =
+ InfoSetUtil.stringValue(getArg2().computeValue(context));
+
+ DecimalFormatSymbols symbols = null;
+ if (ac == 3) {
+ String symbolsName =
+ InfoSetUtil.stringValue(getArg3().computeValue(context));
+ symbols =
+ context.getJXPathContext().getDecimalFormatSymbols(symbolsName);
+ }
+ else {
+ NodePointer pointer = context.getCurrentNodePointer();
+ Locale locale;
+ if (pointer != null) {
+ locale = pointer.getLocale();
+ }
+ else {
+ locale = context.getJXPathContext().getLocale();
+ }
+ symbols = new DecimalFormatSymbols(locale);
+ }
+
+ DecimalFormat format = (DecimalFormat) NumberFormat.getInstance();
+ format.setDecimalFormatSymbols(symbols);
+ format.applyLocalizedPattern(pattern);
+ return format.format(number);
}
private void assertArgCount(int count) {
1.11 +5 -5
jakarta-commons/jxpath/src/java/org/apache/commons/jxpath/ri/compiler/CoreOperation.java
Index: CoreOperation.java
===================================================================
RCS file:
/home/cvs/jakarta-commons/jxpath/src/java/org/apache/commons/jxpath/ri/compiler/CoreOperation.java,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -r1.10 -r1.11
--- CoreOperation.java 19 Jan 2003 23:59:23 -0000 1.10
+++ CoreOperation.java 25 Jan 2003 01:50:36 -0000 1.11
@@ -129,7 +129,7 @@
needParens = false;
}
else if (myPrecedence == thePrecedence) {
- if (isSymmetric()){
+ if (isSymmetric()) {
needParens = false;
}
else {
1.9 +8 -8
jakarta-commons/jxpath/src/java/org/apache/commons/jxpath/ri/model/beans/LangAttributePointer.java
Index: LangAttributePointer.java
===================================================================
RCS file:
/home/cvs/jakarta-commons/jxpath/src/java/org/apache/commons/jxpath/ri/model/beans/LangAttributePointer.java,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -r1.8 -r1.9
--- LangAttributePointer.java 11 Jan 2003 05:41:24 -0000 1.8
+++ LangAttributePointer.java 25 Jan 2003 01:50:37 -0000 1.9
@@ -78,7 +78,7 @@
}
public QName getName() {
- return new QName(null, "lang");
+ return new QName("xml", "lang");
}
public QName getExpandedName() {
@@ -92,10 +92,10 @@
public boolean isCollection() {
return false;
}
-
+
public int getLength() {
return 1;
- }
+ }
public Object getBaseValue() {
return parent.getLocale().toString().replace('_', '-');
@@ -154,7 +154,7 @@
public int compareChildNodePointers(
NodePointer pointer1,
- NodePointer pointer2)
+ NodePointer pointer2)
{
// Won't happen - lang attributes don't have children
return 0;
1.5 +12 -4
jakarta-commons/jxpath/src/java/org/apache/commons/jxpath/xml/DocumentContainer.java
Index: DocumentContainer.java
===================================================================
RCS file:
/home/cvs/jakarta-commons/jxpath/src/java/org/apache/commons/jxpath/xml/DocumentContainer.java,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- DocumentContainer.java 11 Jan 2003 05:41:27 -0000 1.4
+++ DocumentContainer.java 25 Jan 2003 01:50:37 -0000 1.5
@@ -101,6 +101,14 @@
private static HashMap parsers = new HashMap();
/**
+ * Add an XML parser. Parsers for the models "DOM" and "JDOM" are
+ * pre-registered.
+ */
+ public static void registerXMLParser(String model, XMLParser parser) {
+ parsers.put(model, parser);
+ }
+
+ /**
* Use this constructor if the desired model is DOM.
*
* @param URL is a URL for an XML file.
1.2 +27 -5
jakarta-commons/jxpath/src/test/org/apache/commons/jxpath/ri/JXPathCompiledExpressionTest.java
Index: JXPathCompiledExpressionTest.java
===================================================================
RCS file:
/home/cvs/jakarta-commons/jxpath/src/test/org/apache/commons/jxpath/ri/JXPathCompiledExpressionTest.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- JXPathCompiledExpressionTest.java 20 Jan 2003 00:00:27 -0000 1.1
+++ JXPathCompiledExpressionTest.java 25 Jan 2003 01:50:37 -0000 1.2
@@ -64,7 +64,28 @@
import org.apache.commons.jxpath.JXPathContext;
import org.apache.commons.jxpath.JXPathTestCase;
-import org.apache.commons.jxpath.ri.compiler.*;
+import org.apache.commons.jxpath.ri.compiler.Constant;
+import org.apache.commons.jxpath.ri.compiler.CoreFunction;
+import org.apache.commons.jxpath.ri.compiler.CoreOperationAdd;
+import org.apache.commons.jxpath.ri.compiler.CoreOperationAnd;
+import org.apache.commons.jxpath.ri.compiler.CoreOperationDivide;
+import org.apache.commons.jxpath.ri.compiler.CoreOperationEqual;
+import org.apache.commons.jxpath.ri.compiler.CoreOperationGreaterThan;
+import org.apache.commons.jxpath.ri.compiler.CoreOperationGreaterThanOrEqual;
+import org.apache.commons.jxpath.ri.compiler.CoreOperationLessThan;
+import org.apache.commons.jxpath.ri.compiler.CoreOperationLessThanOrEqual;
+import org.apache.commons.jxpath.ri.compiler.CoreOperationMod;
+import org.apache.commons.jxpath.ri.compiler.CoreOperationMultiply;
+import org.apache.commons.jxpath.ri.compiler.CoreOperationNegate;
+import org.apache.commons.jxpath.ri.compiler.CoreOperationNotEqual;
+import org.apache.commons.jxpath.ri.compiler.CoreOperationOr;
+import org.apache.commons.jxpath.ri.compiler.CoreOperationSubtract;
+import org.apache.commons.jxpath.ri.compiler.CoreOperationUnion;
+import org.apache.commons.jxpath.ri.compiler.ExpressionPath;
+import org.apache.commons.jxpath.ri.compiler.ExtensionFunction;
+import org.apache.commons.jxpath.ri.compiler.LocationPath;
+import org.apache.commons.jxpath.ri.compiler.NameAttributeTest;
+import org.apache.commons.jxpath.ri.compiler.VariableReference;
/**
* Test compiler.
@@ -123,6 +144,7 @@
assertXPathExpression("ceiling(11.4)", CoreFunction.class);
assertXPathExpression("round(11.4)", CoreFunction.class);
assertXPathExpression("key('title', 'Hobbit')", CoreFunction.class);
+ assertXPathExpression("format-number(12, '##')", CoreFunction.class);
}
public void testCoreOperationAnd() {
1.4 +44 -4
jakarta-commons/jxpath/src/test/org/apache/commons/jxpath/ri/compiler/CoreFunctionTest.java
Index: CoreFunctionTest.java
===================================================================
RCS file:
/home/cvs/jakarta-commons/jxpath/src/test/org/apache/commons/jxpath/ri/compiler/CoreFunctionTest.java,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- CoreFunctionTest.java 20 Jan 2003 00:00:27 -0000 1.3
+++ CoreFunctionTest.java 25 Jan 2003 01:50:37 -0000 1.4
@@ -62,6 +62,8 @@
package org.apache.commons.jxpath.ri.compiler;
+import java.text.DecimalFormatSymbols;
+
import org.apache.commons.jxpath.IdentityManager;
import org.apache.commons.jxpath.JXPathContext;
import org.apache.commons.jxpath.JXPathTestCase;
@@ -182,5 +184,43 @@
});
assertEquals("Test key", "42", context.getValue("key('a', 'b')"));
+ }
+
+ public void testFormatNumberFunction() {
+
+ DecimalFormatSymbols symbols = new DecimalFormatSymbols();
+ symbols.setDigit('D');
+
+ context.setDecimalFormatSymbols("test", symbols);
+
+ assertXPathValue(
+ context,
+ "format-number(123456789, '#.000000000')",
+ "123456789.000000000");
+
+ assertXPathValue(
+ context,
+ "format-number(123456789, '#.0')",
+ "123456789.0");
+
+ assertXPathValue(
+ context,
+ "format-number(0.123456789, '##%')",
+ "12%");
+
+ assertXPathValue(
+ context,
+ "format-number(123456789, '################')",
+ "123456789");
+
+ assertXPathValue(
+ context,
+ "format-number(123456789, 'D.0', 'test')",
+ "123456789.0");
+
+ assertXPathValue(
+ context,
+ "format-number(123456789, '$DDD,DDD,DDD.DD', 'test')",
+ "$123,456,789");
}
}
1.9 +7 -5
jakarta-commons/jxpath/src/test/org/apache/commons/jxpath/ri/model/BeanModelTestCase.java
Index: BeanModelTestCase.java
===================================================================
RCS file:
/home/cvs/jakarta-commons/jxpath/src/test/org/apache/commons/jxpath/ri/model/BeanModelTestCase.java,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -r1.8 -r1.9
--- BeanModelTestCase.java 20 Jan 2003 00:00:28 -0000 1.8
+++ BeanModelTestCase.java 25 Jan 2003 01:50:37 -0000 1.9
@@ -737,7 +737,9 @@
"integers[position()<3]",
list(new Integer(1), new Integer(2)));
- context.getVariables().declareVariable("temp", context.getValue("beans"));
+ context.getVariables().declareVariable(
+ "temp",
+ context.getValue("beans"));
assertXPathValueIterator(
context,
1.9 +171 -12 jakarta-commons/jxpath/xdocs/users-guide.xml
Index: users-guide.xml
===================================================================
RCS file: /home/cvs/jakarta-commons/jxpath/xdocs/users-guide.xml,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -r1.8 -r1.9
--- users-guide.xml 11 Jan 2003 06:22:54 -0000 1.8
+++ users-guide.xml 25 Jan 2003 01:50:37 -0000 1.9
@@ -8,9 +8,8 @@
Dmitri Plotnikov
</author>
</properties>
- <body>
-
+ <body>
<section name="What's JXPath">
<p>
JXPath provides APIs for the traversal of graphs of JavaBeans,
@@ -57,7 +56,7 @@
</li>
<li><a href="#Map Element Access">Map Element Access</a>
</li>
- <li><a href="#DOM Document Access">DOM Document Access</a>
+ <li><a href="#DOM/JDOM Document Access">DOM/JDOM Document Access</a>
</li>
<li><a href="#Containers">Containers</a>
</li>
@@ -65,6 +64,18 @@
</li>
</ul>
</li>
+ <li><a href="#XPath Axes And Object Graphs">XPath Axes And Object Graphs</a>
+ <ul>
+ <li><a href="#Parent/child Relationship">Parent/child Relationship</a>
+ </li>
+ <li><a href="#Document Order">Document Order</a>
+ </li>
+ <li><a href="#Attributes">Attributes</a>
+ </li>
+ </ul>
+ </li>
+ <li><a href="#Exceptions During XPath Evaluation">Exceptions During XPath
Evaluation</a>
+ </li>
<li><a href="#Modifying Object Graphs">Modifying Object Graphs</a>
<ul>
<li><a href="#Setting Properties">Setting Properties</a>
@@ -255,7 +266,8 @@
<p>
A collection can be an arbitrary array or an instance of
- java.util.Collection.
+ java.util.Collection. JXPath also supports indexed properties
+ according to the JavaBeans specification.
</p>
<p><b>Note:</b> in XPath the first element of a collection has
index 1, not 0.
@@ -361,21 +373,19 @@
</subsection>
- <subsection name="DOM Document Access">
+ <subsection name="DOM/JDOM Document Access">
<p>
- JXPath supports access to DOM Nodes. The DOM node can be
+ JXPath supports access to DOM and JDOM Nodes. The DOM/JDOM node can be
the context node of JXPathContext or it can be a value of a
property, element of a collection, variable value etc.
Let's say we have a path <code>"$foo/bar/baz"</code>.
It will work if, for instance, the value of the variable
- "foo" is a JavaBean, whose property "bar" contains a DOM
+ "foo" is a JavaBean, whose property "bar" contains a DOM/JDOM
Node, which has a child element named "baz".
</p>
<p>
- The intepretation of XPath over DOM structures is
- implemented in with the XPath specification. For instance,
- the "attribute" axis is supported for DOM objects, even
- though it is not applicable to JavaBeans.
+ The intepretation of XPath over DOM/JDOM structures is
+ implemented in accordance with the XPath specification.
</p>
</subsection>
@@ -499,6 +509,155 @@
</p>
</section>
+ <section name="XPath Axes And Object Graphs">
+ <p>
+ The interpretation of XPath over XML models like DOM and JDOM is governed by
+ the XPath standard. There is no official standard for the interpretation
+ of XPaths on other types of models: beans, maps etc.
+ This part describes how JXPath performs such interpretation.
+ </p>
+
+ <subsection name="Parent/child Relationship">
+ <p>
+ 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.
+ </p>
+ <p>
+ 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.
+ </p>
+ <p>
+ 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 <i>evaluation contexts</i>. For example,
+ when the <code>"/foo/bar"</code> 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.
+ </p>
+ <p>
+ 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".
+ </p>
+ <p>
+ Consider this example. The evaluated path is
+ <code>"foo//bar/../baz"</code>. In the process of evaluating of this
+ path, the engine will walk the graph forming chains of context like
+ <code>"/foo/a/b/c/bar"</code>. Once a node with the name "bar" is found,
+ the engine will "step back": in our case it will go back to the
+ <code>"/foo/a/b/c"</code> context and then look for the node with
+ the name "baz" in that context.
+ </p>
+ <p>
+ <b>Exercise:</b> think about how the path
+ <code>"//foo[../@name='bar']"</code> would be interpreted.
+ </p>
+ <p>
+ <b>Solution:</b>
+ <ol>
+ <li>
+ Descend from the root of the graph looking for a node
+ with the name "foo".
+ </li>
+ <li>
+ Let's say the engine has found such a node in the context of
+ a node called "biz". The "biz" node is the dynamic parent
+ of the node "foo".
+ </li>
+ <li>
+ Form a new context for the "foo" node.
+ </li>
+ <li>
+ To evaluate the predicate <code>"../@name='bar'"</code>, step back
+ to the previous context, which is the context of
+ the node "biz" to see if it has an attribute called "name". If so,
+ compare the value of that attribute to "bar". If it is equal,
+ include the current "foo" node in the result set.
+ </li>
+ </ol>
+ </p>
+ <p>
+ The dynamic interpretation of the parent/child relationship affects
+ most axes including "parent::", "ancestor::",
+ "preceding::", "following::" etc.
+ </p>
+ </subsection>
+
+ <subsection name="Document Order">
+ <p>
+ The XPath standard defines the term "document order" as the order
+ in which pieces of XML follow each other in the textual representation.
+ This definition is not applicable directly to non-XML models.
+ </p>
+ <p>
+ Results of many types of xpaths depend on the document order, so
+ we cannot leave it as "unpredictable" or "undefined" for such nodes
+ as JavaBeans or Maps. In order to have a predictable order,
+ JXPath sorts properties of beans and keys of maps alphabetically.
+ </p>
+ </subsection>
+
+ <subsection name="Attributes">
+ <p>
+ For JavaBeans and Maps the "attribute::" axis is interpreted
+ the same as the "child::" axis.
+ </p>
+ <p>
+ The only two distinctions are the "xml:lang" and "name".
+ </p>
+ <p>
+ Attribute <code><b>xml:lang</b></code> refers to the name of the locale
+ associated with the node. In XML the <code>xml:lang</code> attribute
+ can be specifed for an element explicitly. In non-XML models,
+ the locale is associated with the whole JXPathContext. Unless
+ explicitly set it is the application's default locale.
+ </p>
+ <p>
+ The <code><b>name</b></code> attribute is primarily used when
+ working with Maps. Often elements of a Map can be retrieved
+ using the "child::" axis. For example, if "foo" in <code>"foo/bar"</code>
+ refers to a Map then the path extracts from the map the value for the key
+ "bar". The syntax of XPath requires that a child name be a properly
+ formed identifier. Now, what if the key we are looking for is "?%$",
+ which is not an identifier. In this case we can use the "name"
+ attribute like this: <code>"foo[@name='?%$']"</code>. This path
+ is not interpreted as "find a 'foo' that has the name '?%$'". It is
+ interpreted as "find a 'foo' and get the value for the key '?%$'"
+ from it. This interpretation is used for maps and beans only.
+ In the case of XML, "name" is treated like any other attribute.
+ </p>
+ </subsection>
+
+ </section>
+
+ <section name="Exceptions During XPath Evaluation">
+ <p>
+ Exceptions thrown by accessor methods are treated differently depending
+ on the evaluated xpath and the particular method used to do the
+ evaluation.
+ </p>
+ <p>
+ The basic idea is that if JXPath is <i>looking</i> for something by
+ iterating over all properties of a bean and during that iteration
+ an accessor method for one of these properties throws an exception,
+ JXPath ignores the exception and moves on to the next property.
+ This could happen if the method is <code>iterate()</code> or
+ if the path contains search axes like "descendant::", "ancestor::" etc.
+ </p>
+ <p>
+ In all other cases, an exception thrown by an accessor method is
+ wrapped into a JXPathException and re-thrown.
+ </p>
+ </section>
<section name="Modifying Object Graphs">
<p>
@@ -1349,7 +1508,7 @@
JXPath uses JavaBeans introspection to discover properties
of JavaBeans. You can provide alternative property lists by
supplying custom JXPathBeanInfo classes (see
- <A
HREF="apidocs/org/apache/commons/jxpath/JXPathBeanInfo.html"><CODE>JXPathBeanInfo</CODE></A>).
+ <a
href="apidocs/org/apache/commons/jxpath/JXPathBeanInfo.html"><code>JXPathBeanInfo</code></a>).
</p>
</subsection>
1.1 jakarta-commons/jxpath/xdocs/release-notes-1.1.xml
Index: release-notes-1.1.xml
===================================================================
<?xml version="1.0" encoding="UTF-8"?>
<document>
<properties>
<title>
JXPath Release Notes 1.1
</title>
<author email="[EMAIL PROTECTED]">
Dmitri Plotnikov
</author>
</properties>
<body>
<section name="JXPath 1.1 Release Notes">
<p>
Most changes in 1.1 are in the internal implementation and do not affect
public APIs. However there are some new publicly visible features:
<ul>
<li>
Full support for JDOM. Just like with DOM, if a JDOM node
is the root node of a JXPathContext, the implementation strictly follows
the XPath 1.0 standard. A JDOM node can also be a part of a mixed model,
i.e. the value of a property, variable, container, collection element
etc.
</li>
<li>
Pointer has an additional method: getNode(), which returns the raw
value without converting it to a primitive value. This makes
a difference when you are working with DOM/JDOM and want to obtain
the Node itself, not the textual value of the Node.
</li>
<li>
Support for DynaBeans
(see <a href="http://jakarta.apache.org/commons/beanutils">Jakarta
Commons BeanUtils</a>).
</li>
<li>
Refactored XML parsing by container to allow for alternate parsers.
All you do now is specify which model you want the container to use -
DOM (default) or JDOM. From that point the processing is transparent.
See
<a href="apidocs/org/apache/commons/jxpath/xml/DocumentContainer.html">
<code>org.apache.commons.jxpath.xml.DocumentContainer</code>
</a>.
</li>
<li>
The <code>format-number</code> XSLT function is now supported.
In order to provide full conformance with the standard, we also
needed to introduce the format customization mechanism known in
XSLT as <code><xsl:decimal-format></code> (see
<a href="http://www.w3schools.com/xsl/el_decimal-format.asp">
W3Schools tutorial</a>). The new methods of JXPathContext:
<code>setDecimalFormatSymbols</code> and
<code>getDecimalFormatSymbols</code> fulfill that requirement.
</li>
<li>
The <code>attribute::</code> axis is now supported for models other than
DOM/JDOM. For beans and maps it is interpreted the same way as
the <code>"child::"</code> axis.
</li>
<li>
In JXPath 1.0 you could only register DynamicPropertyHandlers for
concrete classes, now you can also register them for interfaces.
</li>
<li>
The implementation of <code>setValue()</code> has changed for DOM/JDOM
nodes. In JXPath 1.0 it would replace text in the element, but leave
subelements alone. The new implementation is more consistent: it
drops all subelements first. Also, if you pass a Node as the new
value, it will insert the Node in the tree.
</li>
<li>
The JUnit tests for JXPath have been completely redisigned and
significantly enhanced.
</li>
</ul>
</p>
</section>
<section name="Acknowledgements">
<p>
Great thanks to everybody who reported problems, helped to trace them,
suggested changed or simply provided encouragement. Special thanks to
<ul>
<li>Trond Aasan</li>
<li>Bjorn Bength</li>
<li>Derek A. Bodin</li>
<li>BoD</li>
<li>Stephen Colebourne</li>
<li>Torsten Curdt</li>
<li>Pierre Delisle</li>
<li>Ruud Diterwich</li>
<li>Peter Donald</li>
<li>Kate Dvortsova</li>
<li>Eduardo Francos</li>
<li>dIon Gillard</li>
<li>Mike Hogan</li>
<li>Ivelin Ivanov</li>
<li>Per Kreipke</li>
<li>Kees Kuip</li>
<li>David Li</li>
<li>Ulrich Nicolas Lissé</li>
<li>Costin Manolache</li>
<li>Thorsten Mauch</li>
<li>Craig R. McClanahan</li>
<li>Markus Menner</li>
<li>Daniel Michalik</li>
<li>Steve Pannier</li>
<li>Ed Peters</li>
<li>Kenneth Petersen</li>
<li>Ovidiu Predescu</li>
<li>Erik Pugh</li>
<li>Robert Rasmussen</li>
<li>Vasco C. Rocha</li>
<li>Francois Swiegers</li>
<li>Joern Turner</li>
<li>Knut Wannheden</li>
<li>Andrew Wulf</li>
<li>Jason van Zyl</li>
</ul>
Thanks!
</p>
</section>
</body>
</document>
--
To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]>
For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>