Sylvain Wallez wrote:
<snip />
I was attempting and failing to bind to an XML document. The load worked, but the save gave the exception.
Sylvain?
I know Sylvain created this:
http://cvs.apache.org/viewcvs.cgi/cocoon-2.1/src/java/org/apache/cocoon/util/jxpath/DOMFactory.java
exactly to cater for the automatic creation (factory) of DOMNodes triggered from jxpath createPath statements...
But I have to admit I can't find where that thingy gets registered on the jxpath context (too much relying on the advanced search of eclipse?)
Sorry, I'm very late on all this.
Actually, there's currently no use of this class in Cocoon samples, but I use it on my projects. Here's how: in the flow, I don't load/save the DOM directly, but through a JXPathContext as follows;
var doc = readDocument(url); var bindingCtx = createBindingContext(doc); form.load(bindingCtx); form.showForm("pipeline"); form.save(bindingCtx);
And here's the createBindingContext function:
function createBindingContext(document) {
// Create a JXPath context on the document.
var xpathContext = Packages.org.apache.commons.jxpath.JXPathContext.newContext(document);
// Set it to lenient
xpathContext.setLenient(true);
// Add the necessary factory create elements and attributes as needed on non-existing paths
xpathContext.setFactory(new Packages.org.apache.cocoon.util.jxpath.DOMFactory());
return xpathContext;
}
Thx for explaining!
Having to explain how this work yesterday during a training, I felt that it should be better hidden in the binding machinery, since this is somehow needed every time we bind a form do a DOM (unless the DOM already contains the whole XML structure).
So what about adding this into the AbstractJXPathBinding: if the object passed to load/save is a Node, then add the DOMFactory automatically.
Makes sense! (that is were I was looking for the registration in the first place :-))
Only thing to look out for is the possible combination with the insert-node binding? (haven't checked yet how jxpath handles multiple registries)
We may create a child JXPathContext in InsertNodeJXPathBinding to avoid overriding the DOMFactory, but I'm wondering if using a factory is needed at all in InsertNode: isn't a simple "appendChild" enough?
i.e. Node node = (Node)jxPathContext.getContextPointer().getNode().appendChild(toInsert)
On a side-note: isn't the utility class a more natural addition to jxpath (in the long run?)
Sure, we may contribute it. But there's still a problem that needs to be fixed, which is that it fails to create an attribute whose owner element doesn't exist.
And finally: I'm taking it you are quite ok with the rest of the proposal? (just wanted to check)
Basically, I'm ok with having the two kinds of binding sharing a similar syntax (on-bind, on-insert, etc), but I'm not sure merging them in a single binding is a good idea, as apart "row-path" and "parent-path", their other attributes are very, very different.
So I would better be in favor of some more explicit names such as "delta-repeater" for "repeater" and "override-repeater" for "simple-repeater".
WDYT?
-- Sylvain Wallez Anyware Technologies http://www.apache.org/~sylvain http://www.anyware-tech.com { XML, Java, Cocoon, OpenSource }*{ Training, Consulting, Projects } Orixo, the opensource XML business alliance - http://www.orixo.com
