Fixing the XML wrapper regarding the existence ops - Was: Handling missing node values with NodeModel

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

Fixing the XML wrapper regarding the existence ops - Was: Handling missing node values with NodeModel

Daniel Dekany
Tuesday, June 21, 2011, 4:36:26 PM, Tom Fennelly wrote:

> Awesome..... that worked perfect... thanks Daniel !!!!

No, it's in fact awful, but this is how it is for now. I see two ways
out of this situation:

a) Introduce a marker (empty) interface, freemarker.template.DefaultValue.
   If a TemplatModel implements this interface, that tells FreeMarker
   that this value is to be used only as the last chance, and the
   locally provided default (like "anonymous" in name!"anonymous")
   should take precedence. This feature would be, coincidentally,
   useful for XML, because if empty XPath result sets are marked with
   DefaultValue, then something like myXmlNode.foo!"default" would
   magically work, just like myXmlNode.foo[0]!"default" does. However,
   the empty results set is not "last chance" value (not a default
   value), so it's kind of a dirty trick.

b) When people write myXmlNode.foo, they either expect 1 or 0 matches
   (a single node which is optional), or multiple matches (a list of
   nodes, even if possibly 0 or 1 long). XPath however doesn't have a
   notation to express these two intents, so the current XML wrapper
   doesn't have either. This is mathematically nice and everything,
   but in practice it leads to all those voodoo tricks (like if and
   only if myXmlNode.foo returns 1 matching node, the result is both a
   scalar and a sequence - explain that to Average Joe Jr.) and
   confusion. So, how about making these two cases different like:

   - myXmlNode.foo means "I want that *single* node". If there are no
     matches, that's a undefined variable error, thus `!`, `??` etc.
     works as expected. If there are multiple marching nodes, that's a
     TemplateModelException, that can't be suppressed (except with
     #attempt, of course).

   - myXmlNode.foo$ means "I want the list of the matching nodes".
     This would always return a sequence, even if 0 long. Why "$"?
     It could be read as the "S" of the plural form, "foos". (I think
     this was originally the idea of Jonathan.) The drawback is of
     course that this way we deviate from XPath, so XPath expression
     couldn't be written as myXmlNode["foo//bar"] and like. Instead,
     they had to be written as myXmlNode("foo//bar") maybe.

Neither of these are strictly backward-compatible, but since we can
have multiple wrapper instances and instances can be configured or of
different classes, that's manageable.

Another thing... I find it scary that we depend on internal API-s to
do XPath with Xerces. If they still haven't added the required API-s
as public, well... in the new wrapper we should just require Jaxen.
Unless, there are performance problems with that or like... anybody is
aware of such issues?

--
Best regards,
 Daniel Dekany


> On 21/06/2011 15:29, Daniel Dekany wrote:
>> I recommend reading this:
>>
>>    http://freemarker.org/docs/xgui_imperative_learn.html
>>
>> It answers this question among others. Anyway, you could do it like
>> this:
>>
>>    ${.vars["com.acme.Travel"].checkIn[0]!}
>>
>> The relevant change I did here is the adding of [0]; the others are
>> just aesthetical. You see, the result of the XPath query exists even
>> if it's an empty node list, so what you want to know if it has a 1st
>> element.
>>
>>
>> Tuesday, June 21, 2011, 3:26:15 PM, Tom Fennelly wrote:
>>
>>> Hi.
>>>
>>> I'm using a NodeModel and was wondering how missing nodes can be
>>> handled?  I'm looking for the equivalent of the
>>> unsafe_expr!default_expr notation
>>> (http://freemarker.sourceforge.net/docs/dgui_template_exp.html#dgui_template_exp_missing),
>>> but something that works for NodeModels (the default did not work for me).
>>>
>>> BTW.. the template's in question use the .vars syntax in the
>>> expressions.  So, when I do the following I get an exception -
>>> ${.vars["com.acme.Travel"]["checkIn"]!""}.  The exception is...
>>>      Expecting a string, date or number here, Expression
>>> .vars["com.acme.Travel"]["checkIn"]!"" is instead a freemarker.ext.dom.NodeListModel
>>>      The problematic instruction:
>>>      ----------
>>>      ==>  ${.vars["com.acme.Travel"]["checkIn"]!""} [on line 3,
>>> column 19 in free-marker-template]
>>>      ----------
>>>
>>>      Java backtrace for programmers:
>>>      ----------
>>>      freemarker.core.NonStringException: Error on line 3, column 21 in free-marker-template
>>>
>>> Thanks in advance.
>>>
>>> T.
>
> ------------------------------------------------------------------------------
> EditLive Enterprise is the world's most technically advanced content
> authoring tool. Experience the power of Track Changes, Inline Image
> Editing and ensure content is compliant with Accessibility Checking.
> http://p.sf.net/sfu/ephox-dev2dev
> _______________________________________________
> FreeMarker-user mailing list
> [hidden email]
> https://lists.sourceforge.net/lists/listinfo/freemarker-user
>


------------------------------------------------------------------------------
EditLive Enterprise is the world's most technically advanced content
authoring tool. Experience the power of Track Changes, Inline Image
Editing and ensure content is compliant with Accessibility Checking.
http://p.sf.net/sfu/ephox-dev2dev
_______________________________________________
FreeMarker-devel mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/freemarker-devel
Reply | Threaded
Open this post in threaded view
|

Re: Fixing the XML wrapper regarding the existence ops - Was: Handling missing node values with NodeModel

Denis Bredelet

On 21 Jun 2011, at 18:28, Daniel Dekany <[hidden email]> wrote:

> Tuesday, June 21, 2011, 4:36:26 PM, Tom Fennelly wrote:
>
>> Awesome..... that worked perfect... thanks Daniel !!!!
>
> No, it's in fact awful, but this is how it is for now. I see two ways
> out of this situation:
>
> a) Introduce a marker (empty) interface, freemarker.template.DefaultValue.
>   If a TemplatModel implements this interface, that tells FreeMarker
>   that this value is to be used only as the last chance, and the
>   locally provided default (like "anonymous" in name!"anonymous")
>   should take precedence. This feature would be, coincidentally,
>   useful for XML, because if empty XPath result sets are marked with
>   DefaultValue, then something like myXmlNode.foo!"default" would
>   magically work, just like myXmlNode.foo[0]!"default" does. However,
>   the empty results set is not "last chance" value (not a default
>   value), so it's kind of a dirty trick.
>

I vote for keeping the current notation. I would prefer not deviating from Xpath not to cause surprise (maybe Xpath needs fixing, that's another story)

I am not sure I understand all the consequences of (a) though. Will any empty sequence be replaced with the new default value?

-- Denis.

> b) When people write myXmlNode.foo, they either expect 1 or 0 matches
>   (a single node which is optional), or multiple matches (a list of
>   nodes, even if possibly 0 or 1 long). XPath however doesn't have a
>   notation to express these two intents, so the current XML wrapper
>   doesn't have either. This is mathematically nice and everything,
>   but in practice it leads to all those voodoo tricks (like if and
>   only if myXmlNode.foo returns 1 matching node, the result is both a
>   scalar and a sequence - explain that to Average Joe Jr.) and
>   confusion. So, how about making these two cases different like:
>
>   - myXmlNode.foo means "I want that *single* node". If there are no
>     matches, that's a undefined variable error, thus `!`, `??` etc.
>     works as expected. If there are multiple marching nodes, that's a
>     TemplateModelException, that can't be suppressed (except with
>     #attempt, of course).
>
>   - myXmlNode.foo$ means "I want the list of the matching nodes".
>     This would always return a sequence, even if 0 long. Why "$"?
>     It could be read as the "S" of the plural form, "foos". (I think
>     this was originally the idea of Jonathan.) The drawback is of
>     course that this way we deviate from XPath, so XPath expression
>     couldn't be written as myXmlNode["foo//bar"] and like. Instead,
>     they had to be written as myXmlNode("foo//bar") maybe.
>
> Neither of these are strictly backward-compatible, but since we can
> have multiple wrapper instances and instances can be configured or of
> different classes, that's manageable.
>
> Another thing... I find it scary that we depend on internal API-s to
> do XPath with Xerces. If they still haven't added the required API-s
> as public, well... in the new wrapper we should just require Jaxen.
> Unless, there are performance problems with that or like... anybody is
> aware of such issues?
>
> --
> Best regards,
> Daniel Dekany
>
>
>> On 21/06/2011 15:29, Daniel Dekany wrote:
>>> I recommend reading this:
>>>
>>>   http://freemarker.org/docs/xgui_imperative_learn.html
>>>
>>> It answers this question among others. Anyway, you could do it like
>>> this:
>>>
>>>   ${.vars["com.acme.Travel"].checkIn[0]!}
>>>
>>> The relevant change I did here is the adding of [0]; the others are
>>> just aesthetical. You see, the result of the XPath query exists even
>>> if it's an empty node list, so what you want to know if it has a 1st
>>> element.
>>>
>>>
>>> Tuesday, June 21, 2011, 3:26:15 PM, Tom Fennelly wrote:
>>>
>>>> Hi.
>>>>
>>>> I'm using a NodeModel and was wondering how missing nodes can be
>>>> handled?  I'm looking for the equivalent of the
>>>> unsafe_expr!default_expr notation
>>>> (http://freemarker.sourceforge.net/docs/dgui_template_exp.html#dgui_template_exp_missing),
>>>> but something that works for NodeModels (the default did not work for me).
>>>>
>>>> BTW.. the template's in question use the .vars syntax in the
>>>> expressions.  So, when I do the following I get an exception -
>>>> ${.vars["com.acme.Travel"]["checkIn"]!""}.  The exception is...
>>>>     Expecting a string, date or number here, Expression
>>>> .vars["com.acme.Travel"]["checkIn"]!"" is instead a freemarker.ext.dom.NodeListModel
>>>>     The problematic instruction:
>>>>     ----------
>>>>     ==>  ${.vars["com.acme.Travel"]["checkIn"]!""} [on line 3,
>>>> column 19 in free-marker-template]
>>>>     ----------
>>>>
>>>>     Java backtrace for programmers:
>>>>     ----------
>>>>     freemarker.core.NonStringException: Error on line 3, column 21 in free-marker-template
>>>>
>>>> Thanks in advance.
>>>>
>>>> T.
>>
>> ------------------------------------------------------------------------------
>> EditLive Enterprise is the world's most technically advanced content
>> authoring tool. Experience the power of Track Changes, Inline Image
>> Editing and ensure content is compliant with Accessibility Checking.
>> http://p.sf.net/sfu/ephox-dev2dev
>> _______________________________________________
>> FreeMarker-user mailing list
>> [hidden email]
>> https://lists.sourceforge.net/lists/listinfo/freemarker-user
>>
>
>
> ------------------------------------------------------------------------------
> EditLive Enterprise is the world's most technically advanced content
> authoring tool. Experience the power of Track Changes, Inline Image
> Editing and ensure content is compliant with Accessibility Checking.
> http://p.sf.net/sfu/ephox-dev2dev
> _______________________________________________
> FreeMarker-devel mailing list
> [hidden email]
> https://lists.sourceforge.net/lists/listinfo/freemarker-devel

------------------------------------------------------------------------------
EditLive Enterprise is the world's most technically advanced content
authoring tool. Experience the power of Track Changes, Inline Image
Editing and ensure content is compliant with Accessibility Checking.
http://p.sf.net/sfu/ephox-dev2dev
_______________________________________________
FreeMarker-devel mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/freemarker-devel
Reply | Threaded
Open this post in threaded view
|

Re: Fixing the XML wrapper regarding the existence ops - Was: Handling missing node values with NodeModel

Daniel Dekany
Tuesday, June 21, 2011, 9:21:05 PM, Denis Bredelet wrote:

>
> On 21 Jun 2011, at 18:28, Daniel Dekany <[hidden email]> wrote:
>
>> Tuesday, June 21, 2011, 4:36:26 PM, Tom Fennelly wrote:
>>
>>> Awesome..... that worked perfect... thanks Daniel !!!!
>>
>> No, it's in fact awful, but this is how it is for now. I see two ways
>> out of this situation:
>>
>> a) Introduce a marker (empty) interface, freemarker.template.DefaultValue.
>>   If a TemplatModel implements this interface, that tells FreeMarker
>>   that this value is to be used only as the last chance, and the
>>   locally provided default (like "anonymous" in name!"anonymous")
>>   should take precedence. This feature would be, coincidentally,
>>   useful for XML, because if empty XPath result sets are marked with
>>   DefaultValue, then something like myXmlNode.foo!"default" would
>>   magically work, just like myXmlNode.foo[0]!"default" does. However,
>>   the empty results set is not "last chance" value (not a default
>>   value), so it's kind of a dirty trick.
>>
>
> I vote for keeping the current notation. I would prefer not
> deviating from Xpath not to cause surprise (maybe Xpath needs
> fixing, that's another story)

For a language that is specialized on transforming XML (i.e., for
XSLT), the approach of XPath is probably OK. Only when you mix it with
a more general purpose language, or with FreeMarker, there's a
mismatch.

> I am not sure I understand all the consequences of (a) though. Will
> any empty sequence be replaced with the new default value?

Yes. So, these would become equivalent:
- `myNode.foo[0]!"blah"` and `myNode.foo!"blah"`
- `myNode.foo[0]! and `myNode.foo!`
- `myNode.foo[0]?? and `myNode.foo??`

That is, `myNode.foo`, if you have no matching node, will still return
an empty sequence, however as far as the existence operators are
concerned, the value is missing. Yeah, this is even more magic... and
I hate magic in languages. But then the `[0]!` thing looks horrid,
it's anti-intuitive, and a FAQ generator.

--
Best regards,
 Daniel Dekany


> -- Denis.
>
>> b) When people write myXmlNode.foo, they either expect 1 or 0 matches
>>   (a single node which is optional), or multiple matches (a list of
>>   nodes, even if possibly 0 or 1 long). XPath however doesn't have a
>>   notation to express these two intents, so the current XML wrapper
>>   doesn't have either. This is mathematically nice and everything,
>>   but in practice it leads to all those voodoo tricks (like if and
>>   only if myXmlNode.foo returns 1 matching node, the result is both a
>>   scalar and a sequence - explain that to Average Joe Jr.) and
>>   confusion. So, how about making these two cases different like:
>>
>>   - myXmlNode.foo means "I want that *single* node". If there are no
>>     matches, that's a undefined variable error, thus `!`, `??` etc.
>>     works as expected. If there are multiple marching nodes, that's a
>>     TemplateModelException, that can't be suppressed (except with
>>     #attempt, of course).
>>
>>   - myXmlNode.foo$ means "I want the list of the matching nodes".
>>     This would always return a sequence, even if 0 long. Why "$"?
>>     It could be read as the "S" of the plural form, "foos". (I think
>>     this was originally the idea of Jonathan.) The drawback is of
>>     course that this way we deviate from XPath, so XPath expression
>>     couldn't be written as myXmlNode["foo//bar"] and like. Instead,
>>     they had to be written as myXmlNode("foo//bar") maybe.
>>
>> Neither of these are strictly backward-compatible, but since we can
>> have multiple wrapper instances and instances can be configured or of
>> different classes, that's manageable.
>>
>> Another thing... I find it scary that we depend on internal API-s to
>> do XPath with Xerces. If they still haven't added the required API-s
>> as public, well... in the new wrapper we should just require Jaxen.
>> Unless, there are performance problems with that or like... anybody is
>> aware of such issues?
>>
>> --
>> Best regards,
>> Daniel Dekany
>>
>>
>>> On 21/06/2011 15:29, Daniel Dekany wrote:
>>>> I recommend reading this:
>>>>
>>>>   http://freemarker.org/docs/xgui_imperative_learn.html
>>>>
>>>> It answers this question among others. Anyway, you could do it like
>>>> this:
>>>>
>>>>   ${.vars["com.acme.Travel"].checkIn[0]!}
>>>>
>>>> The relevant change I did here is the adding of [0]; the others are
>>>> just aesthetical. You see, the result of the XPath query exists even
>>>> if it's an empty node list, so what you want to know if it has a 1st
>>>> element.
>>>>
>>>>
>>>> Tuesday, June 21, 2011, 3:26:15 PM, Tom Fennelly wrote:
>>>>
>>>>> Hi.
>>>>>
>>>>> I'm using a NodeModel and was wondering how missing nodes can be
>>>>> handled?  I'm looking for the equivalent of the
>>>>> unsafe_expr!default_expr notation
>>>>> (http://freemarker.sourceforge.net/docs/dgui_template_exp.html#dgui_template_exp_missing),
>>>>> but something that works for NodeModels (the default did not work for me).
>>>>>
>>>>> BTW.. the template's in question use the .vars syntax in the
>>>>> expressions.  So, when I do the following I get an exception -
>>>>> ${.vars["com.acme.Travel"]["checkIn"]!""}.  The exception is...
>>>>>     Expecting a string, date or number here, Expression
>>>>> .vars["com.acme.Travel"]["checkIn"]!"" is instead a freemarker.ext.dom.NodeListModel
>>>>>     The problematic instruction:
>>>>>     ----------
>>>>>     ==>  ${.vars["com.acme.Travel"]["checkIn"]!""} [on line 3,
>>>>> column 19 in free-marker-template]
>>>>>     ----------
>>>>>
>>>>>     Java backtrace for programmers:
>>>>>     ----------
>>>>>     freemarker.core.NonStringException: Error on line 3, column 21 in free-marker-template
>>>>>
>>>>> Thanks in advance.
>>>>>
>>>>> T.


------------------------------------------------------------------------------
EditLive Enterprise is the world's most technically advanced content
authoring tool. Experience the power of Track Changes, Inline Image
Editing and ensure content is compliant with Accessibility Checking.
http://p.sf.net/sfu/ephox-dev2dev
_______________________________________________
FreeMarker-devel mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/freemarker-devel