getodk/javarosa

Literal strings for value attribute of the setvalue action don't work

lognaturel opened this issue · 5 comments

Software versions

JavaRosa v3 and most likely all prior

Problem description

Steps to reproduce the problem

Add a setvalue action such as
<setvalue event="odk-instance-first-load" ref="/data/my-node" value="a literal string"/>

This can be done by creating an XLSForm with a value in the default column that has hyphens in it (e.g. my-value). pyxform will treat this as a dynamic default and create a setvalue.

Expected behavior

The literal string value should populate the target node when the event is fired.

Other information

I think we may have introduced a special case for empty strings without realizing literal strings didn't work.

According to the XForms docs "setvalue" section: https://www.w3.org/TR/xforms/#action-setvalue

In order to set a literal value, you must use <setvalue>literal string</setvalue>. Otherwise value is treated as an expression. I was able to get it to work using <setvalue value="&quot;literal string&quot;"/> as well.

Thanks for looking at this! When I read "specifying a computed value via attribute value", I'm imagining that a literal is just a very simple expression so would also be allowed there. I'm not entirely sure whether that's the case but that'd be my interpretation. pyxform does currently generate forms with actions such as <setvalue event="odk-instance-first-load" ref="/data/my-node" value="a-literal-string"/> so even if it does stretch the W3C definition I think we need to do it if possible.

I think the issue is that there is no way for the user to hint on how to evaluate the "value" expression. Without some other way, the code doesn't know to treat "value" as an XPath expression or a literal value. So, if "value" happens to be a valid XPath value but the user really meant it as a literal value, there is no way to tell how to treat it unless we do something like evaluate as XPath first, and if that results in null, assume it was meant to be a literal value. The docs are pretty specific that "value" is an XPath expression. So something like concat('', 'string-value') would also work.

I think I'm getting confused between languages. So just a literal is not an XPath expression then? As you say, that may make what I'm suggesting impossible/nonsense.

I'm losing my mind. value="a-literal-string" means the child node with name a-literal-string. So we have to come up with a way to address this on the pyxform end of things. Thank you, @macdude357!