Base64 decode support

I am hoping to scan a QR code with the barcode scanner that is encoded via base64. I thought I found an XPath function base64Decode that might work, but I think that's possibly only available as an extension.

Short of creating a separate Android app to provide the scanning and decoding via an intent, are there other workaround that might allow for base64-decoding a value in ODK?

The function doesn't exist, but it's something we can add to the next release (rough ETA end of March) if it'd be helpful.

1 Like

The base64-decode function is available in the latest 2023.1 beta and should be released on Monday.

Documentation for the function is available here.

1 Like

We updated Central to 2023.3 but are seeing this error when attempting to upload a new draft with this function:

The XLSForm could not be converted: ODK Validate Errors:
>> Something broke the parser. See above for a hint.
Error evaluating field 'scan_decoded' (${item}[1]/scan_decoded[1]): The problem was located in Calculate expression for ${scan_decoded}
XPath evaluation: cannot handle function 'base64-decode'
Caused by: org.javarosa.xpath.XPathUnhandledException: The problem was located in Calculate expression for ${scan_decoded}
XPath evaluation: cannot handle function 'base64-decode'
	... 10 more

The following files failed validation:
foo.xml

Result: Invalid

We were able to work around this temporarily by changing validate=True to validate=False here: https://github.com/getodk/pyxform-http/blob/37821e90554ffdc0b312b3840feaeff37fd8bfc0/app/main.py#L48

EDIT: See better fix below.

We need to update JavaRosa in Validate and update Validate in pyxform. Sorry about that.

I believe another option would be to change your form design to wrap the call in a conditional that relies on some value in the form being filled in. For example, if you want to decode the value from a field called scanned, you could use if(${scanned}!='', base64-decode(${scanned}}, '').

This works because Validate doesn't perform any kind of analysis on the form definition, it just runs the form. In general this is not ideal behavior because it misses some validation. In this case it's something you can use to your advantage.

Thanks for the quick response! That workaround does the trick, too. Many thanks. It's certainly nice to keep server-side validation enabled.

1 Like