- From: Erik Bruchez <ebruchez@orbeon.com>
- Date: Thu, 6 Mar 2008 10:14:02 -0800
- To: "Forms WG (new)" <public-forms@w3.org>
Nick, It is good that you are raising this. And yes, I think it IS because you are so used to XPath that you like the "nodes" approach ;-) But luckily, you are wrong about the index() function ;-), and this is for two reasons: 1. Using the index() function would give you the wrong result anyway. What you would need is the current position within the repeat, not the index (which may turn out to be "1" for all the iterations, for example). With XPath 2.0, something like this will work, not sure with XPath 1.0: <output name="LineTotal" calculate="$Price[context()/position()] * $Quantity[context()/position()]"/> This said don't even look at the above, it's not necessary anyway as I explain further below. But the point is taken, if you had to use the index() or position() function, it would be a big turn-off. I would not claim that such a solution satisfies the criterium of "simplicity". 2. More importantly, you WON'T need to use the index() or position() function! The implicit binds will look like this (@context, etc. notwithstanding): <xf:bind name="order" nodeset="order/row"> <xf:bind name="Product" nodeset="Product"/> ... In XForms 1.1, we now clearly define how nested binds are evaluated within repeats. See "4.7.2 References to Elements within a bind Element" [1]. This means that from within the repeat, a reference to bind "Product" will return the node associated with the current iteration. If we define XPath variables as simply resolving binds, then you can just write the following: <output name="LineTotal" calculate="$Price * $Quantity"/> and obtain the expected result, without using index() or position(). We are exactly in the case of section 4.7.2! From *outside* the repeat, the bind will resolve to the whole node-set, so you will get all the nodes you expect. In fact, this may turn out to be quite elegant IMO. -Erik [1] http://www.w3.org/TR/xforms11/#idref-resolve-bind On Mar 6, 2008, at 1:23 AM, Nick_Van_den_Bleeken@inventivegroup.com wrote: > > All, > > Personally I don't have anything against the "control()" XPath > function nor the "Variables" approach, but (as mentioned on the > call) the 'current' syntax becomes really complicated in repeats I > think: > > <repeat name="order" nodeset="row"> > <select1 name="Product"> ... > <input name="Quantity"> ... > <input name="Price"> ... > <output name="LineTotal" calculate="$Price[index('order')] * > Quantity[index('order')]"/> > </repeat> > <output name="Subtotal" calculate="sum($LineTotal)"/> > <output name="Tax" calculate="$Subtotal * 0.07"/> > <output name="Total" calculate="$Subtotal + $Tax"/> > > Please don't look at the control types nor the attributes that are > used for calculating the result. The problem that needs to be solved > I guess is that it is counter intuitive that you need to use the > index function to address the correct item in the repeat > ($Price[index('order')]) because you also sometimes want to address > all the values the control holds(e.g.: sum($LineTotal)). > > It could be that it is just because I use XPath for so long now that > I find the syntax that just refers to the nodes easier: > > <repeat name="order" nodeset="row"> > <select1 name="Product"> ... > <input name="Quantity"> ... > <input name="Price"> ... > <output name="LineTotal" calculate="Price * Quantity"/> > </repeat> > <output name="Subtotal" calculate="sum(order/row/LineTotal)"/> > <output name="Tax" calculate="Subtotal * 0.07"/> > <output name="Total" calculate="Subtotal + Tax"/> > > I think that the 80%-20% rule will apply here and that in the most > cases you want to refer to the 'nodes' in the current row and you > only want to refer to a 'node' in a different row in rare cases > (e.g.: sum every item until the current row, compare against > previous row, ...). So the XPath evaluation context we define turns > out to be quite intuitive, also for none XPath wizards, I think. > > Regards, > > > Nick Van den Bleeken - Research & Development Manager > Inventive Designers > Phone: +32 - 3 - 8210170 > Fax: +32 - 3 - 8210171 > Email: Nick_Van_den_Bleeken@inventivegroup.com > > public-forms-request@w3.org wrote on 03/05/2008 07:46:17 PM: > > > All, > > > > Following our discussion today about simplified syntax and how you > > refer to control values in expressions, I attach 3 different > examples > > of a simplified the view of the PO order John sent. > > > > Note that I have not considered so far the issue of submission or > > insert/delete. > > > > I think it is primarily important to consider what the code looks > like > > to the form author. It has to be easily understandable. After all, > > that is our primary goal in simplification. > > > > The 3 files look almost entirely the same, except for the way you > > refer to elements. But this has subtle and potentially far-reaching > > implications: > > > > 1. By referring directly to the implicit data model's nodes > > ----------------------------------------------------------- > > > > The benefit is that it's super-plain XPath. The drawback is that you > > need, as a form author, to be aware of: > > > > * The implied structure of the underlying data model. > > > > * "where" you currently are in that model, i.e. a notion of what the > > current XPath context is. > > > > So is this too much XPath knowledge to ask from form authors for a > > simplified syntax? For us old-timers it is not that difficult, but > for > > simple use cases like John's PO it is disappointing to require that > > much from the form author. > > > > 2. By using a "control()" XPath function > > ---------------------------------------- > > > > This functions allows referring to the value associated with the > > control, specified by name (or id, see below). Note that I say > > "associated", which means that it could be the actual value of the > > control, or it could be pointing to instance data through implicit > > binds. The point is that it doesn't matter much as we define what > > "control()" means. > > > > Note that control() could return a node-set (or even a sequence of > > values in XPath 2.0) when the control is within a repeat. This > allows > > the sum() function to work as expected. > > > > The big benefit is that you don't worry about the current XPath > > context anymore. It is unambiguous to which control you are > referring > > to, assuming you use unique control names. > > > > This would be easier to enforce if we actually referred to the > control > > by id instead of name. In HTML, there is a distinction between the > two > > though, where the id is, well, the id of the element, and the name > > defines something in the data model (name/value in HTML, element > name > > in XForms). But it is a pain to have to define a name AND an > > id. Anyway, this is probably something that can be figured out. > > > > 3. By using XPath variables > > --------------------------- > > > > The use of variables (i.e. the $foo syntax) has the same benefits as > > the "control()" function. > > > > The benefit over the "control()" function is that the syntax is > > simpler, and you use a well-understood XPath construct instead of a > > custom function. > > > > Here my main worry is that of scoping and future-proofing. It is > > important IMO that we do not mess up how we use XPath variables in > > order to leave open the specification of locally-scoped variables in > > the future. > > > > But: > > > > * IF <xf:input name="foo"> implies an <xf:bind> > > * AND that <xf:bind> is considered in scope where the variable is > used > > > > THEN the scoping rule becomes palatable. Certainly, it will be if > you > > look at the corresponding canonical XForms. > > > > But this still raises a few questions: > > > > Q1: When writing canonical XForms, do binds in a model always define > > XPath variables, and if so, do they expose them by id? > > > > The issue here is that ids are global in a document, while currently > > in XForms models are scoped with the @model attribute. If you don't > > use an id, then you can have variables with the same name defined in > > multiple models. This enhances reusability. > > > > In most languages, variables can be scoped in a similar way. The > same > > I think would be desirable for XForms, therefore using global ids to > > expose variable names is a serious drawback IMO (even though > > currently, binds are exposed this way). > > > > Do we need to introduce <xforms:bind name="foo"> ? > > > > Q2: Do we want to call our future "variables" "binds" instead? > > > > I like the idea of calling a cat a cat and naming variables > > <xforms:variable>, as this is a notion familiar to every developer > on > > the planet and every mainstream programming language has them and > > calls them "variables". > > > > Binds are familiar to long-time XForms people, but not so much to > > programmers who come from other languages. > > > > So the day we introduce locally-scoped variables a la eXforms [1], > > will we call them <xforms:variable>, or <xforms:bind>? You know what > > my vote is. > > > > Q3: Further, a variable in XPath has a name and a value. Binds do > not > > quite work this way. > > > > Instead, they are currently defined to bind to one or more nodes > (and > > possibly, when using the @calculate MIP, assign a value to the > > node(s)). > > > > This does not quite map in my mind to the notion of a variable > > today. Yes, we can define the behavior of <xforms:bind> as exposing > > the value of the node as the value of the variable, as a node-set > for > > example. > > > > But that is not enough for generalized variables. So how do we get > > there? Certainly, we could modify <xforms:bind> to get closer to the > > XSLT notion of <xforms:variable>, as a holder for any XPath type. > But > > then why not introduce <xforms:variable> instead? > > > > One solution could look like this: > > > > * Only <xforms:bind> elements having a "name" attribute expose > > themselves as variables. This solves the issue of scoping by > model. > > > > * We do not extend <xforms:bind> in the future to look more like > > variables. Instead, we introduce <xforms:variable name="foo"/>. > So > > you can expose variables to XPath either with binds, or with > actual > > variables which are more generic and more author-friendly IMO, > when > > actually used as variables. This is especially important for > > locally-scoped variables, whether in the model, in the view, or > in > > actions. > > > > The bottom line for me at this point remains that I still have > quite a > > few concerns about the use of the $foo syntax. I believe that we > need > > to fully understand the implications of this before going forward > with > > this solution. > > > > BUT if we find a consistent, future-proof solution for the $foo > syntax, > > then I would favor it over other solutions because the benefits are > > so appealing. > > > > -Erik > > > > [1] http://www.exforms.org/variable.html > > > > -- > > Orbeon Forms - Web Forms for the Enterprise Done the Right Way > > http://www.orbeon.com/ > > > > > > > > > > -------------------------------- > > ----------------- > > > > Inventive Designers' Email Disclaimer: > > > > http://www.inventivedesigners.com/ > > mail-disclaimer > > > > [attachment "po1.xhtml" deleted by Nick Van den Bleeken/Inventive > > Group] [attachment "po2.xhtml" deleted by Nick Van den Bleeken/ > > Inventive Group] [attachment "po3.xhtml" deleted by Nick Van den > > Bleeken/Inventive Group] > Inventive Designers' Email Disclaimer: > http://www.inventivedesigners.com/email-disclaimer > > -- Orbeon Forms - Web Forms for the Enterprise Done the Right Way http://www.orbeon.com/
Received on Thursday, 6 March 2008 18:14:34 UTC