FS FormScript

The second corpus: XForms

The first corpus asked what FormScript cannot say about FHIR. This one asks the same question about a different source language, and it is a probe, not a census: it takes every XForms document in three named directories at three named commits, and reports what the language could and could not carry over. It does not claim to represent every XForm ever written.

The point is generality. A language that can absorb one shape of source is not a language; it is a front end. XForms is a good second shape because it is a form language in its own right — it has its own expression language (XPath 1.0), its own way of saying "ask this only if that", and its own way of saying "compute this".

This report is generated by npm run corpus:xreport, which re-reads every converted document and runs it through the lexer, the parser, the analyzer and the engine before writing a word of it.

The headline

  • 166 sources from 4 publishers, covering 4 domains.
  • 163 forms converted from 2422 source nodes into 1931 FormScript fields.
  • 163 of 163 parse and analyse with no error.
  • 163 of 163 evaluate: the engine builds a transaction and produces an output document from each one.
  • 0 carry an advisory from the language itself.
  • 3 sources rejected outright, with a code.
  • 704 gaps were recorded, of which 404 lossy — something the source said that FormScript cannot say.
  • 61 of 163 forms lost nothing at all; 102 lost something.

The rejects

The rejects come first, because they are the measurement.

source code why
vellum-form_with_no_instance_block REJECT-NOT-AN-XFORM the model declares no instance
openmrs-form-entry-xml REJECT-NOT-AN-XFORM the document has no model; it is not an XForm
openmrs-form-entry-relationship REJECT-NOT-AN-XFORM the document has no body; it is not an XForm

The rejects are XML that came from a form system and turned out not to be an XForm. The shape check says so instead of converting half of it.

The sources

document published by nodes fields outputs sha256
enketo-SOAR_facilitysurvey_full_2017May11_Kenya enketo/enketo 487 425 242 cb28c242da33
enketo-XSS-test enketo/enketo 2 2 2 704afcc9615a
enketo-all-widgets enketo/enketo 84 72 72 29527dbf1463
enketo-audio-recording enketo/enketo 4 4 4 e34e24b97331
enketo-autocomplete-cascade enketo/enketo 2 2 2 6e4806bda5b8
enketo-background-audio-recording enketo/enketo 3 3 3 29f7430e1ea2
enketo-calc-control enketo/enketo 1 1 1 12b4893c5c94
enketo-calc-in-group-with-relevant enketo/enketo 8 7 7 ca91391fc6cc
enketo-calcs-cascade enketo/enketo 3 3 3 d6e46fd133b3
enketo-calcs enketo/enketo 5 5 5 6b86c6cd40d9
enketo-calcs_in_repeats enketo/enketo 12 9 8 2a94437f2790
enketo-calcs_in_repeats_2 enketo/enketo 4 2 2 8b99f97fe9e1
enketo-cascading_mixture_itext_noitext enketo/enketo 3 3 3 7c94e2f3678c
enketo-collections enketo/enketo 12 8 5 98a5dfd019bc
enketo-comment enketo/enketo 2 2 2 e0d3a9fe6938
enketo-constraint-dependency enketo/enketo 2 2 2 dd6e919e0570
enketo-count-repeated-nodes enketo/enketo 5 3 3 8aa89f371473
enketo-dynamic-required enketo/enketo 3 3 3 44c688048df0
enketo-exclude-non-relevant-basic enketo/enketo 20 15 15 8b7721f8b978
enketo-exclude-non-relevant-cascade-across-repeats enketo/enketo 19 11 10 d95996ec26fa
enketo-exclude-non-relevant-repeat-calculate-single enketo/enketo 4 2 3 aaa29fd6ef3c
enketo-exclude-non-relevant-repeat-count enketo/enketo 8 6 5 6f66eb508b12
enketo-exclude-non-relevant-repeat-irrelevant-date enketo/enketo 5 3 2 a472d7ccccf4
enketo-external-data-v2 enketo/enketo 4 4 4 44302b6abbca
enketo-focus enketo/enketo 21 16 10 4a9d8bee5ec1
enketo-group-relevant-indexed-repeat enketo/enketo 11 5 5 140ed85503eb
enketo-group_branch enketo/enketo 5 3 3 75c22995bc11
enketo-groups-pages enketo/enketo 14 9 9 8ec681231854
enketo-images-used-as-labels enketo/enketo 1 1 1 b290fd245a79
enketo-issue208 enketo/enketo 5 3 2 bbdbd3242ba4
enketo-itemset-relevant-2 enketo/enketo 17 12 12 8cb19156f2d5
enketo-itemset-relevant enketo/enketo 7 5 4 2781a6bcaa8f
enketo-itemset-repeat-relevant-current-new enketo/enketo 7 4 2 2043e768c920
enketo-itemset-repeat-relevant-current-old enketo/enketo 7 4 2 c0ee38d4b35a
enketo-jr-choice-name-autocomplete enketo/enketo 4 4 4 04bb5e5f9861
enketo-jr-choice-name-external enketo/enketo 2 2 2 902ec3d55f93
enketo-jr-choice-name-repeats enketo/enketo 5 3 2 4b95e41015ef
enketo-jr-choice-name.issue-490 enketo/enketo 4 4 4 2f3ecc7f8659
enketo-jr-choice-name enketo/enketo 8 8 8 7e8f92148065
enketo-malicious-svg enketo/enketo 1 1 1 3535aad814a4
enketo-merge-empty-instance enketo/enketo 2 2 2 076aee02acb6
enketo-meta-namespace enketo/enketo 2 2 2 252012cab127
enketo-missing-external-instance enketo/enketo 0 0 0 6b93d130f12b
enketo-multiple_repeats_relevant enketo/enketo 6 4 3 89d3b930c7f4
enketo-nested-branches enketo/enketo 5 4 4 8d7c7722d640
enketo-nested-repeat-count enketo/enketo 15 9 9 07250575027b
enketo-nested-repeat-v5 enketo/enketo 6 2 2 277fed5b628b
enketo-nested-repeats-itemset enketo/enketo 7 3 3 c9e6303fa2c8
enketo-nested-repeats-nasty enketo/enketo 9 2 3 64d4fc1996b5
enketo-nested_repeats enketo/enketo 16 10 8 1aec6e53d7f2
enketo-nested_repeats_triple enketo/enketo 7 1 3 2faa356f8568
enketo-new_cascading_selections enketo/enketo 17 13 13 48c9d29b29dc
enketo-new_cascading_selections_inside_repeats enketo/enketo 6 4 2 9e8ec39008e3
enketo-nodename enketo/enketo 3 1 1 5f5b49ad3553
enketo-number-input-widgets enketo/enketo 2 2 2 8bd775ed759e
enketo-numbers-missing-after-language-switch enketo/enketo 3 3 3 ed21cf34d7b8
enketo-output-dynamic-itemset-no-repeat enketo/enketo 2 2 2 707705cfc7c8
enketo-output-dynamic-itemset enketo/enketo 7 5 5 344935e30e5b
enketo-output-irrelevant enketo/enketo 4 3 3 d05aca23f053
enketo-outputs_in_repeats enketo/enketo 8 6 2 f0d36599d205
enketo-pages-comment enketo/enketo 4 4 4 73bb0abefa1c
enketo-pages-nolabel enketo/enketo 5 3 3 592a066e9079
enketo-pages enketo/enketo 23 12 13 8c31e3615f68
enketo-preload-input enketo/enketo 6 6 6 75fe57b7e646
enketo-preload enketo/enketo 8 8 8 4fe302d5069e
enketo-radio enketo/enketo 2 2 2 8d08b3eddae7
enketo-radio2 enketo/enketo 1 1 1 ae5e3cf1c0a6
enketo-random enketo/enketo 6 6 6 0cae464d76d9
enketo-randomize-outside-repeat enketo/enketo 3 1 2 263f8ff256cb
enketo-randomize enketo/enketo 2 2 2 417b9e023319
enketo-range enketo/enketo 0 0 0 a905bfcb3c9c
enketo-rank enketo/enketo 2 2 2 7268a2abd447
enketo-readonly-invalid enketo/enketo 4 4 4 a3118592cfd2
enketo-readonly enketo/enketo 4 4 4 25e23f830bb3
enketo-recalculations enketo/enketo 5 4 4 8cde5d5bf753
enketo-relative enketo/enketo 4 4 4 f2c17a2ee3c5
enketo-relevant-calcs enketo/enketo 6 5 5 402b30cfeae5
enketo-relevant-default enketo/enketo 6 5 5 f079f1c1e3b9
enketo-repeat-autocomplete enketo/enketo 5 3 2 25aa59dc9a79
enketo-repeat-calc enketo/enketo 4 2 2 7975c8bd472a
enketo-repeat-child-relevant enketo/enketo 5 3 3 ba72d9da1ec2
enketo-repeat-count-calc-only enketo/enketo 7 5 6 79a5075298ba
enketo-repeat-count-calculate-irrelevant enketo/enketo 6 3 3 061d1083f84c
enketo-repeat-count-nested-2 enketo/enketo 8 4 4 53d4b016349f
enketo-repeat-count-nested-3 enketo/enketo 8 4 4 b245b8a6459b
enketo-repeat-count-relative-nested enketo/enketo 8 4 4 7862f929a85c
enketo-repeat-count-relative enketo/enketo 8 4 4 c813d0a1afcf
enketo-repeat-count-relevant-on-calculate enketo/enketo 5 3 3 d1587aa29bf8
enketo-repeat-count-relevant enketo/enketo 4 2 2 7e98c3acc8de
enketo-repeat-count-widget-global-init enketo/enketo 4 2 2 651e3dfdfcff
enketo-repeat-count enketo/enketo 9 7 6 b3b66c413096
enketo-repeat-default enketo/enketo 3 1 1 6cee706f5fbc
enketo-repeat-dot enketo/enketo 4 2 2 1c260c35d653
enketo-repeat-irrelevant-date enketo/enketo 5 3 2 f5cb260355f0
enketo-repeat-multiple-shared-datalist-itemsets enketo/enketo 4 2 1 ad6b6dc60d4b
enketo-repeat-only-pages enketo/enketo 4 2 2 262b21ebeb84
enketo-repeat-position enketo/enketo 5 3 3 f092295f133d
enketo-repeat-radio-itemset enketo/enketo 3 1 1 a991cbea2eac
enketo-repeat-radio enketo/enketo 3 1 1 d61edb58b51a
enketo-repeat-relevant-calculate-single enketo/enketo 4 2 2 57036449d170
enketo-repeat-relevant-calculate enketo/enketo 4 2 2 1667074b7813
enketo-repeat-relevant-on-calculate enketo/enketo 4 2 2 40990469fabb
enketo-repeat-relevant-select enketo/enketo 6 4 3 9f70d33bf5ce
enketo-repeat-relevant-select1 enketo/enketo 6 4 3 2bc571c74da3
enketo-repeat-required enketo/enketo 5 3 3 68d759f11bc2
enketo-required enketo/enketo 2 2 2 2b24ebd0b00c
enketo-secondary-lang-form-nolang enketo/enketo 1 1 1 e728f33b2aea
enketo-secondary-lang enketo/enketo 1 1 1 c455eceb554a
enketo-select-dynamic-readonly enketo/enketo 1 1 1 d998d69c0a63
enketo-select-from-selected enketo/enketo 3 3 3 e890d3ec53f4
enketo-setgeopoint-multiple-under-one enketo/enketo 3 3 3 1c456c4cca18
enketo-setgeopoint enketo/enketo 3 3 3 d944cc5bada2
enketo-setvalue-multiple-under-one enketo/enketo 3 3 3 1646bcd11f11
enketo-setvalue-order enketo/enketo 2 2 2 115a248d229d
enketo-setvalue-repeat-order enketo/enketo 4 2 1 598839fe20ce
enketo-setvalue-repeat-tricky-trigger-target enketo/enketo 4 2 2 bbe389405038
enketo-setvalue-repeat-value-changed enketo/enketo 4 2 1 dd0be21c89a5
enketo-setvalue-repeat enketo/enketo 5 2 2 5a5c80333d56
enketo-setvalue-setgeopoint-geopoint enketo/enketo 16 14 13 76c7f83bb2a6
enketo-setvalue-template enketo/enketo 4 3 3 67bfb8f6fd1d
enketo-setvalue-triggered-by-calc enketo/enketo 3 3 3 e48f46899c73
enketo-setvalue enketo/enketo 4 3 3 dd97f2fcc88d
enketo-svg-xss-test enketo/enketo 1 1 1 a6001763f38a
enketo-thedata enketo/enketo 7 5 5 a02e1591369f
enketo-va-who-minimal enketo/enketo 6 3 3 8114acd24348
enketo-va_who_v1_5_3 enketo/enketo 475 444 444 d890e78b429b
enketo-widgets_on_pages enketo/enketo 66 51 51 fc92bbaa9f4a
vellum-form0 dimagi/Vellum 5 5 5 fb664258908d
vellum-form1 dimagi/Vellum 3 2 2 e2b45857be62
vellum-form3 dimagi/Vellum 10 7 6 f7dbd6e1aeb9
vellum-form4 dimagi/Vellum 6 6 6 75a0c264799e
vellum-form5 dimagi/Vellum 26 19 19 3e3cdd735599
vellum-form6 dimagi/Vellum 8 8 8 242345932fcd
vellum-form7 dimagi/Vellum 6 6 6 868c34dc34a0
vellum-form8 dimagi/Vellum 1 1 1 2b2d46ff131a
vellum-form_with_3_languages dimagi/Vellum 3 2 2 7cb5715441d8
vellum-form_with_crufty_itext1 dimagi/Vellum 5 5 5 68bd01be3d46
vellum-form_with_many_diff_qtypes dimagi/Vellum 11 7 5 69e34c4e3e89
vellum-form_with_no_body dimagi/Vellum 0 0 0 576f0466fbbe
vellum-form_with_no_children_data dimagi/Vellum 5 5 5 fc6d52e172be
vellum-form_with_no_data_attrs dimagi/Vellum 5 5 5 f762672a8b72
vellum-form_with_secret dimagi/Vellum 4 4 4 e35e5db87ef0
vellum-cchq-Close-a-pregnancy dimagi/Vellum 49 43 43 eaa24304704b
vellum-cchq-Follow-up-a-Household-Referral dimagi/Vellum 8 8 8 242345932fcd
vellum-cchq-Follow-up-a-pregnancy-referral dimagi/Vellum 19 13 13 47eea83fb5f2
vellum-cchq-Follow-up-a-pregnancy dimagi/Vellum 26 19 19 3e3cdd735599
vellum-cchq-Follow-up-at-household dimagi/Vellum 36 25 22 2298eb06b142
vellum-cchq-Gravidez dimagi/Vellum 50 29 29 7fbac6fdbf79
vellum-cchq-NutritionAndHealth dimagi/Vellum 15 9 9 52fd7f18b754
vellum-cchq-Pos-Parto dimagi/Vellum 52 11 11 56650d415cf0
vellum-cchq-Register-a-household dimagi/Vellum 6 6 6 75a0c264799e
vellum-cchq-Register-a-pregnancy dimagi/Vellum 40 27 27 f4e1d52b6dbe
vellum-cchq-Registo dimagi/Vellum 8 7 7 b686350c34cb
vellum-cchq-ff dimagi/Vellum 8 8 8 b7a0b9b535ab
vellum-nested_form_with_complex_qs dimagi/Vellum 10 7 6 3865275bf96c
pyxform-attribute_columns_test XLSForm/pyxform 50 43 36 27183e9c44e0
pyxform-flat_xlsform_test XLSForm/pyxform 47 42 42 2edb2e068ccf
pyxform-or_other XLSForm/pyxform 3 3 3 e60e51ca8e30
pyxform-pull_data XLSForm/pyxform 2 2 2 e7183a45ed32
pyxform-repeat_date_test XLSForm/pyxform 7 5 4 58f60d4633f1
pyxform-survey_no_name XLSForm/pyxform 1 1 1 f3f3cdbf8586
pyxform-widgets XLSForm/pyxform 40 35 35 646104a7bc90
pyxform-xlsform_spec_test XLSForm/pyxform 49 42 35 d7b7a7b0d70c

The upstream files are not redistributed. corpus/manifest/xforms-sources.json pins each one by URL and SHA-256; npm run corpus:xfetch reads them again and checks the bytes it gets against the pin.

What the toolchain said

document lexed parsed analysed warnings transaction output keys runtime
enketo-SOAR_facilitysurvey_full_2017May11_Kenya ok ok ok 0 committed 150 —
enketo-XSS-test ok ok ok 0 committed 2 —
enketo-all-widgets ok ok ok 0 committed 72 —
enketo-audio-recording ok ok ok 0 committed 4 —
enketo-autocomplete-cascade ok ok ok 0 committed 2 —
enketo-background-audio-recording ok ok ok 0 committed 3 —
enketo-calc-control ok ok ok 0 committed 1 —
enketo-calc-in-group-with-relevant ok ok ok 0 committed 3 —
enketo-calcs-cascade ok ok ok 0 committed 3 —
enketo-calcs ok ok ok 0 committed 4 —
enketo-calcs_in_repeats ok ok ok 0 committed 7 —
enketo-calcs_in_repeats_2 ok ok ok 0 committed 2 —
enketo-cascading_mixture_itext_noitext ok ok ok 0 committed 3 —
enketo-collections ok ok ok 0 committed 5 —
enketo-comment ok ok ok 0 committed 2 E-VAL-05 constraint deferred: its guard is undetermined
enketo-constraint-dependency ok ok ok 0 committed 2 —
enketo-count-repeated-nodes ok ok ok 0 committed 3 —
enketo-dynamic-required ok ok ok 0 committed 3 E-VAL-05 constraint deferred: its guard is undetermined
enketo-exclude-non-relevant-basic ok ok ok 0 committed 8 —
enketo-exclude-non-relevant-cascade-across-repeats ok ok ok 0 committed 9 —
enketo-exclude-non-relevant-repeat-calculate-single ok ok ok 0 committed 2 —
enketo-exclude-non-relevant-repeat-count ok ok ok 0 committed 5 —
enketo-exclude-non-relevant-repeat-irrelevant-date ok ok ok 0 committed 2 —
enketo-external-data-v2 ok ok ok 0 committed 4 —
enketo-focus ok ok ok 0 committed 9 —
enketo-group-relevant-indexed-repeat ok ok ok 0 committed 5 —
enketo-group_branch ok ok ok 0 committed 1 —
enketo-groups-pages ok ok ok 0 committed 9 —
enketo-images-used-as-labels ok ok ok 0 committed 1 —
enketo-issue208 ok ok ok 0 committed 2 —
enketo-itemset-relevant-2 ok ok ok 0 committed 12 —
enketo-itemset-relevant ok ok ok 0 committed 3 —
enketo-itemset-repeat-relevant-current-new ok ok ok 0 committed 2 —
enketo-itemset-repeat-relevant-current-old ok ok ok 0 committed 2 —
enketo-jr-choice-name-autocomplete ok ok ok 0 committed 4 —
enketo-jr-choice-name-external ok ok ok 0 committed 2 —
enketo-jr-choice-name-repeats ok ok ok 0 committed 2 —
enketo-jr-choice-name.issue-490 ok ok ok 0 committed 4 —
enketo-jr-choice-name ok ok ok 0 committed 8 —
enketo-malicious-svg ok ok ok 0 committed 1 —
enketo-merge-empty-instance ok ok ok 0 committed 2 —
enketo-meta-namespace ok ok ok 0 committed 2 —
enketo-missing-external-instance ok ok ok 0 committed 0 —
enketo-multiple_repeats_relevant ok ok ok 0 committed 3 —
enketo-nested-branches ok ok ok 0 committed 3 —
enketo-nested-repeat-count ok ok ok 0 committed 9 —
enketo-nested-repeat-v5 ok ok ok 0 committed 2 —
enketo-nested-repeats-itemset ok ok ok 0 committed 3 —
enketo-nested-repeats-nasty ok ok ok 0 committed 3 —
enketo-nested_repeats ok ok ok 0 committed 8 —
enketo-nested_repeats_triple ok ok ok 0 committed 3 —
enketo-new_cascading_selections ok ok ok 0 committed 13 —
enketo-new_cascading_selections_inside_repeats ok ok ok 0 committed 2 —
enketo-nodename ok ok ok 0 committed 1 —
enketo-number-input-widgets ok ok ok 0 committed 2 —
enketo-numbers-missing-after-language-switch ok ok ok 0 committed 3 —
enketo-output-dynamic-itemset-no-repeat ok ok ok 0 committed 2 —
enketo-output-dynamic-itemset ok ok ok 0 committed 5 —
enketo-output-irrelevant ok ok ok 0 committed 2 —
enketo-outputs_in_repeats ok ok ok 0 committed 2 —
enketo-pages-comment ok ok ok 0 committed 4 —
enketo-pages-nolabel ok ok ok 0 committed 3 —
enketo-pages ok ok ok 0 committed 13 —
enketo-preload-input ok ok ok 0 committed 6 —
enketo-preload ok ok ok 0 committed 8 —
enketo-radio ok ok ok 0 committed 2 —
enketo-radio2 ok ok ok 0 committed 1 —
enketo-random ok ok ok 0 committed 6 —
enketo-randomize-outside-repeat ok ok ok 0 committed 2 —
enketo-randomize ok ok ok 0 committed 2 —
enketo-range ok ok ok 0 committed 0 —
enketo-rank ok ok ok 0 committed 2 —
enketo-readonly-invalid ok ok ok 0 committed 4 —
enketo-readonly ok ok ok 0 committed 4 —
enketo-recalculations ok ok ok 0 committed 3 —
enketo-relative ok ok ok 0 committed 3 —
enketo-relevant-calcs ok ok ok 0 committed 3 —
enketo-relevant-default ok ok ok 0 committed 3 —
enketo-repeat-autocomplete ok ok ok 0 committed 2 —
enketo-repeat-calc ok ok ok 0 committed 2 —
enketo-repeat-child-relevant ok ok ok 0 committed 3 —
enketo-repeat-count-calc-only ok ok ok 0 committed 6 —
enketo-repeat-count-calculate-irrelevant ok ok ok 0 committed 2 —
enketo-repeat-count-nested-2 ok ok ok 0 committed 4 —
enketo-repeat-count-nested-3 ok ok ok 0 committed 4 —
enketo-repeat-count-relative-nested ok ok ok 0 committed 4 —
enketo-repeat-count-relative ok ok ok 0 committed 4 —
enketo-repeat-count-relevant-on-calculate ok ok ok 0 committed 2 —
enketo-repeat-count-relevant ok ok ok 0 committed 1 —
enketo-repeat-count-widget-global-init ok ok ok 0 committed 2 —
enketo-repeat-count ok ok ok 0 committed 0 —
enketo-repeat-default ok ok ok 0 committed 1 —
enketo-repeat-dot ok ok ok 0 committed 2 —
enketo-repeat-irrelevant-date ok ok ok 0 committed 2 —
enketo-repeat-multiple-shared-datalist-itemsets ok ok ok 0 committed 1 —
enketo-repeat-only-pages ok ok ok 0 committed 2 —
enketo-repeat-position ok ok ok 0 committed 3 —
enketo-repeat-radio-itemset ok ok ok 0 committed 1 —
enketo-repeat-radio ok ok ok 0 committed 1 —
enketo-repeat-relevant-calculate-single ok ok ok 0 committed 1 —
enketo-repeat-relevant-calculate ok ok ok 0 committed 1 —
enketo-repeat-relevant-on-calculate ok ok ok 0 committed 1 —
enketo-repeat-relevant-select ok ok ok 0 committed 3 —
enketo-repeat-relevant-select1 ok ok ok 0 committed 3 —
enketo-repeat-required ok ok ok 0 committed 3 —
enketo-required ok ok ok 0 committed 2 E-VAL-05 constraint deferred: its guard is undetermined
enketo-secondary-lang-form-nolang ok ok ok 0 committed 1 —
enketo-secondary-lang ok ok ok 0 committed 1 —
enketo-select-dynamic-readonly ok ok ok 0 committed 1 —
enketo-select-from-selected ok ok ok 0 committed 3 —
enketo-setgeopoint-multiple-under-one ok ok ok 0 committed 3 —
enketo-setgeopoint ok ok ok 0 committed 3 —
enketo-setvalue-multiple-under-one ok ok ok 0 committed 3 —
enketo-setvalue-order ok ok ok 0 committed 2 —
enketo-setvalue-repeat-order ok ok ok 0 committed 1 —
enketo-setvalue-repeat-tricky-trigger-target ok ok ok 0 committed 2 —
enketo-setvalue-repeat-value-changed ok ok ok 0 committed 1 —
enketo-setvalue-repeat ok ok ok 0 committed 1 —
enketo-setvalue-setgeopoint-geopoint ok ok ok 0 committed 13 —
enketo-setvalue-template ok ok ok 0 committed 3 —
enketo-setvalue-triggered-by-calc ok ok ok 0 committed 3 —
enketo-setvalue ok ok ok 0 committed 3 —
enketo-svg-xss-test ok ok ok 0 committed 1 —
enketo-thedata ok ok ok 0 committed 5 —
enketo-va-who-minimal ok ok ok 0 committed 1 —
enketo-va_who_v1_5_3 ok ok ok 0 committed 37 —
enketo-widgets_on_pages ok ok ok 0 committed 51 —
vellum-form0 ok ok ok 0 committed 5 —
vellum-form1 ok ok ok 0 committed 2 —
vellum-form3 ok ok ok 0 committed 6 —
vellum-form4 ok ok ok 0 committed 6 —
vellum-form5 ok ok ok 0 committed 16 —
vellum-form6 ok ok ok 0 committed 1 —
vellum-form7 ok ok ok 0 committed 6 —
vellum-form8 ok ok ok 0 committed 1 —
vellum-form_with_3_languages ok ok ok 0 committed 2 —
vellum-form_with_crufty_itext1 ok ok ok 0 committed 5 —
vellum-form_with_many_diff_qtypes ok ok ok 0 committed 5 —
vellum-form_with_no_body ok ok ok 0 committed 0 —
vellum-form_with_no_children_data ok ok ok 0 committed 5 —
vellum-form_with_no_data_attrs ok ok ok 0 committed 5 —
vellum-form_with_secret ok ok ok 0 committed 4 —
vellum-cchq-Close-a-pregnancy ok ok ok 0 committed 1 —
vellum-cchq-Follow-up-a-Household-Referral ok ok ok 0 committed 1 —
vellum-cchq-Follow-up-a-pregnancy-referral ok ok ok 0 committed 1 —
vellum-cchq-Follow-up-a-pregnancy ok ok ok 0 committed 16 —
vellum-cchq-Follow-up-at-household ok ok ok 0 committed 4 —
vellum-cchq-Gravidez ok ok ok 0 committed 1 —
vellum-cchq-NutritionAndHealth ok ok ok 0 committed 6 —
vellum-cchq-Pos-Parto ok ok ok 0 committed 1 —
vellum-cchq-Register-a-household ok ok ok 0 committed 6 —
vellum-cchq-Register-a-pregnancy ok ok ok 0 committed 16 —
vellum-cchq-Registo ok ok ok 0 committed 5 —
vellum-cchq-ff ok ok ok 0 committed 1 —
vellum-nested_form_with_complex_qs ok ok ok 0 committed 6 —
pyxform-attribute_columns_test ok ok ok 0 committed 5 —
pyxform-flat_xlsform_test ok ok ok 0 committed 5 —
pyxform-or_other ok ok ok 0 committed 2 —
pyxform-pull_data ok ok ok 0 committed 2 —
pyxform-repeat_date_test ok ok ok 0 committed 4 —
pyxform-survey_no_name ok ok ok 0 committed 1 —
pyxform-widgets ok ok ok 0 committed 35 —
pyxform-xlsform_spec_test ok ok ok 0 committed 5 —

What could not be carried over

Every gap names the XForms location that produced it. A gap is either lossy — something meaningful was dropped — or informational, which records something that does not change what the form means.

code what it means times lossy documents
XFORM-RENDER The control asked to be rendered in a particular way. FormScript has no renderer hint for it, so the hint was dropped. 175 0 29
XFORM-ITEMSET The control's options came from a secondary instance rather than from the form. FormScript's choices are written down or fetched from a source, and a secondary instance is neither. 141 141 38
XFORM-XPATH-UNSUPPORTED The behaviour was written in XPath and used something FormScript cannot say — an extension function, a node position, a predicate. The expression was dropped, so the behaviour it carried was lost. 131 131 72
XFORM-TRIGGER A trigger is a button that runs an action. It is not a question, so it was not converted. 125 0 20
XFORM-TYPE-MISMATCH The source declared a node one type and calculated a value of another. An XForms bind's type is a hint for the user interface; FormScript's types are static, so the field took the type of the calculation. 65 65 20
XFORM-XPATH-UNRESOLVED The behaviour named a node the converted form does not have, so part of the expression could not be carried over. 21 21 5
XFORM-UNCONTROLLED-VALUE The instance held a node the body never shows, and the node held a value. FormScript has fields, and a field is something the form shows or computes, so the value had nowhere to go. 18 18 6
XFORM-TYPE-GEO The node held a shape or a trace. FormScript has a geo type, but only for a point. 10 10 2
XFORM-TYPE-BARCODE The node held a barcode. FormScript has no barcode type. 7 7 7
XFORM-TYPE-TIME The node held a time of day. FormScript has no time type. 6 6 6
XFORM-DEFAULT-TYPE The instance held an initial value that was not of the kind the field holds, so the initial value was dropped. 4 4 4
XFORM-CHOICE-DUPLICATE Two options shared a key. The later one was renamed so the choice set stays a set. 1 1 1

The three findings

1. The model holds; the expression language does not. All 163 forms parse, analyse and evaluate. The shape of an XForm — groups, repeats, questions, choices, calculated values, relevance, constraints — maps onto FormScript almost entirely. What does not map is XPath. 131 expressions used something FormScript cannot say: extension functions (uuid, int, regex, household-exists, indexed-repeat), node positions (position(), current()), and predicates. Every one of those is a behaviour the form had.

2. XForms has an instance model; FormScript has a form. An XForm carries a whole tree of data nodes, including nodes the body never shows. FormScript has fields, and a field is something the form shows or computes. 18 nodes across the corpus held a value that had nowhere to go.

3. Options from elsewhere are not options. 141 controls took their options from a secondary instance rather than from the form — how ODK builds cascading and dynamic choice lists. FormScript has optionsFrom for a list fetched from a server, but the list is not in the document, and an XForm carries its list inside itself.

Document by document

Each row is one converted form. The gap codes say what was lost; corpus/reports/xforms-conversion.json has the detail.

document fields outputs lossy gaps first error
enketo-SOAR_facilitysurvey_full_2017May11_Kenya 425 242 41 —
XFORM-ITEMSET XFORM-RENDER XFORM-TYPE-MISMATCH XFORM-XPATH-UNRESOLVED XFORM-XPATH-UNSUPPORTED
enketo-XSS-test 2 2 1 —
XFORM-XPATH-UNSUPPORTED
enketo-all-widgets 72 72 29 —
XFORM-ITEMSET XFORM-RENDER XFORM-TRIGGER XFORM-TYPE-BARCODE XFORM-TYPE-GEO XFORM-TYPE-TIME
enketo-audio-recording 4 4 0 —
enketo-autocomplete-cascade 2 2 1 —
XFORM-ITEMSET XFORM-RENDER
enketo-background-audio-recording 3 3 1 —
XFORM-ITEMSET
enketo-calc-control 1 1 0 —
enketo-calc-in-group-with-relevant 7 7 1 —
XFORM-XPATH-UNSUPPORTED
enketo-calcs-cascade 3 3 0 —
enketo-calcs 5 5 3 —
XFORM-TYPE-MISMATCH XFORM-XPATH-UNSUPPORTED
enketo-calcs_in_repeats 9 8 3 —
XFORM-TYPE-MISMATCH XFORM-XPATH-UNSUPPORTED
enketo-calcs_in_repeats_2 2 2 2 —
XFORM-TYPE-MISMATCH XFORM-UNCONTROLLED-VALUE
enketo-cascading_mixture_itext_noitext 3 3 3 —
XFORM-ITEMSET
enketo-collections 8 5 1 —
XFORM-XPATH-UNSUPPORTED
enketo-comment 2 2 0 —
XFORM-RENDER
enketo-constraint-dependency 2 2 0 —
enketo-count-repeated-nodes 3 3 2 —
XFORM-RENDER XFORM-XPATH-UNSUPPORTED
enketo-dynamic-required 3 3 1 —
XFORM-XPATH-UNSUPPORTED
enketo-exclude-non-relevant-basic 15 15 4 —
XFORM-TYPE-MISMATCH
enketo-exclude-non-relevant-cascade-across-repeats 11 10 11 —
XFORM-XPATH-UNSUPPORTED
enketo-exclude-non-relevant-repeat-calculate-single 2 3 2 —
XFORM-XPATH-UNSUPPORTED
enketo-exclude-non-relevant-repeat-count 6 5 2 —
XFORM-TYPE-MISMATCH XFORM-XPATH-UNSUPPORTED
enketo-exclude-non-relevant-repeat-irrelevant-date 3 2 1 —
XFORM-XPATH-UNSUPPORTED
enketo-external-data-v2 4 4 3 —
XFORM-ITEMSET
enketo-focus 16 10 1 —
XFORM-RENDER XFORM-XPATH-UNSUPPORTED
enketo-group-relevant-indexed-repeat 5 5 2 —
XFORM-RENDER XFORM-XPATH-UNSUPPORTED
enketo-group_branch 3 3 0 —
enketo-groups-pages 9 9 0 —
enketo-images-used-as-labels 1 1 1 —
XFORM-ITEMSET XFORM-RENDER
enketo-issue208 3 2 0 —
enketo-itemset-relevant-2 12 12 19 —
XFORM-ITEMSET XFORM-RENDER XFORM-TRIGGER XFORM-XPATH-UNRESOLVED
enketo-itemset-relevant 5 4 2 —
XFORM-ITEMSET XFORM-RENDER XFORM-XPATH-UNSUPPORTED
enketo-itemset-repeat-relevant-current-new 4 2 3 —
XFORM-ITEMSET XFORM-XPATH-UNSUPPORTED
enketo-itemset-repeat-relevant-current-old 4 2 3 —
XFORM-ITEMSET XFORM-XPATH-UNSUPPORTED
enketo-jr-choice-name-autocomplete 4 4 2 —
XFORM-RENDER XFORM-XPATH-UNSUPPORTED
enketo-jr-choice-name-external 2 2 2 —
XFORM-ITEMSET XFORM-XPATH-UNSUPPORTED
enketo-jr-choice-name-repeats 3 2 2 —
XFORM-ITEMSET XFORM-XPATH-UNSUPPORTED
enketo-jr-choice-name.issue-490 4 4 2 —
XFORM-XPATH-UNSUPPORTED
enketo-jr-choice-name 8 8 3 —
XFORM-XPATH-UNSUPPORTED
enketo-malicious-svg 1 1 1 —
XFORM-ITEMSET XFORM-RENDER
enketo-merge-empty-instance 2 2 2 —
XFORM-DEFAULT-TYPE XFORM-ITEMSET
enketo-meta-namespace 2 2 0 —
enketo-missing-external-instance 0 0 0 —
enketo-multiple_repeats_relevant 4 3 1 —
XFORM-XPATH-UNSUPPORTED
enketo-nested-branches 4 4 1 —
XFORM-XPATH-UNSUPPORTED
enketo-nested-repeat-count 9 9 6 —
XFORM-TYPE-MISMATCH XFORM-XPATH-UNSUPPORTED
enketo-nested-repeat-v5 2 2 0 —
enketo-nested-repeats-itemset 3 3 2 —
XFORM-ITEMSET XFORM-RENDER XFORM-XPATH-UNSUPPORTED
enketo-nested-repeats-nasty 2 3 1 —
XFORM-XPATH-UNSUPPORTED
enketo-nested_repeats 10 8 0 —
enketo-nested_repeats_triple 1 3 0 —
enketo-new_cascading_selections 13 13 13 —
XFORM-ITEMSET XFORM-XPATH-UNSUPPORTED
enketo-new_cascading_selections_inside_repeats 4 2 3 —
XFORM-ITEMSET XFORM-XPATH-UNSUPPORTED
enketo-nodename 1 1 0 —
enketo-number-input-widgets 2 2 0 —
enketo-numbers-missing-after-language-switch 3 3 0 —
enketo-output-dynamic-itemset-no-repeat 2 2 1 —
XFORM-ITEMSET
enketo-output-dynamic-itemset 5 5 4 —
XFORM-ITEMSET XFORM-TYPE-MISMATCH XFORM-XPATH-UNSUPPORTED
enketo-output-irrelevant 3 3 0 —
enketo-outputs_in_repeats 6 2 1 —
XFORM-XPATH-UNSUPPORTED
enketo-pages-comment 4 4 0 —
XFORM-RENDER
enketo-pages-nolabel 3 3 1 —
XFORM-XPATH-UNSUPPORTED
enketo-pages 12 13 11 —
XFORM-TRIGGER XFORM-TYPE-MISMATCH XFORM-XPATH-UNRESOLVED XFORM-XPATH-UNSUPPORTED
enketo-preload-input 6 6 3 —
XFORM-XPATH-UNSUPPORTED
enketo-preload 8 8 0 —
enketo-radio 2 2 2 —
XFORM-ITEMSET XFORM-XPATH-UNSUPPORTED
enketo-radio2 1 1 0 —
enketo-random 6 6 2 —
XFORM-XPATH-UNSUPPORTED
enketo-randomize-outside-repeat 1 2 1 —
XFORM-ITEMSET
enketo-randomize 2 2 2 —
XFORM-ITEMSET XFORM-XPATH-UNSUPPORTED
enketo-range 0 0 1 —
XFORM-UNCONTROLLED-VALUE
enketo-rank 2 2 1 —
XFORM-XPATH-UNSUPPORTED
enketo-readonly-invalid 4 4 1 —
XFORM-XPATH-UNSUPPORTED
enketo-readonly 4 4 1 —
XFORM-XPATH-UNSUPPORTED
enketo-recalculations 4 4 0 —
enketo-relative 4 4 1 —
XFORM-XPATH-UNSUPPORTED
enketo-relevant-calcs 5 5 0 —
enketo-relevant-default 5 5 1 —
XFORM-XPATH-UNSUPPORTED
enketo-repeat-autocomplete 3 2 2 —
XFORM-ITEMSET XFORM-RENDER XFORM-XPATH-UNSUPPORTED
enketo-repeat-calc 2 2 1 —
XFORM-XPATH-UNSUPPORTED
enketo-repeat-child-relevant 3 3 2 —
XFORM-TYPE-MISMATCH XFORM-XPATH-UNSUPPORTED
enketo-repeat-count-calc-only 5 6 4 —
XFORM-RENDER XFORM-TYPE-MISMATCH XFORM-XPATH-UNSUPPORTED
enketo-repeat-count-calculate-irrelevant 3 3 2 —
XFORM-RENDER XFORM-UNCONTROLLED-VALUE XFORM-XPATH-UNSUPPORTED
enketo-repeat-count-nested-2 4 4 1 —
XFORM-XPATH-UNSUPPORTED
enketo-repeat-count-nested-3 4 4 1 —
XFORM-XPATH-UNSUPPORTED
enketo-repeat-count-relative-nested 4 4 1 —
XFORM-XPATH-UNSUPPORTED
enketo-repeat-count-relative 4 4 1 —
XFORM-XPATH-UNSUPPORTED
enketo-repeat-count-relevant-on-calculate 3 3 1 —
XFORM-TYPE-MISMATCH
enketo-repeat-count-relevant 2 2 0 —
enketo-repeat-count-widget-global-init 2 2 0 —
enketo-repeat-count 7 6 4 —
XFORM-TYPE-MISMATCH XFORM-XPATH-UNSUPPORTED
enketo-repeat-default 1 1 0 —
enketo-repeat-dot 2 2 1 —
XFORM-XPATH-UNSUPPORTED
enketo-repeat-irrelevant-date 3 2 1 —
XFORM-RENDER XFORM-XPATH-UNSUPPORTED
enketo-repeat-multiple-shared-datalist-itemsets 2 1 2 —
XFORM-ITEMSET XFORM-RENDER
enketo-repeat-only-pages 2 2 0 —
enketo-repeat-position 3 3 2 —
XFORM-TYPE-MISMATCH XFORM-XPATH-UNSUPPORTED
enketo-repeat-radio-itemset 1 1 1 —
XFORM-ITEMSET
enketo-repeat-radio 1 1 0 —
enketo-repeat-relevant-calculate-single 2 2 1 —
XFORM-XPATH-UNSUPPORTED
enketo-repeat-relevant-calculate 2 2 1 —
XFORM-XPATH-UNSUPPORTED
enketo-repeat-relevant-on-calculate 2 2 1 —
XFORM-TYPE-MISMATCH
enketo-repeat-relevant-select 4 3 1 —
XFORM-XPATH-UNSUPPORTED
enketo-repeat-relevant-select1 4 3 1 —
XFORM-XPATH-UNSUPPORTED
enketo-repeat-required 3 3 1 —
XFORM-XPATH-UNSUPPORTED
enketo-required 2 2 0 —
enketo-secondary-lang-form-nolang 1 1 1 —
XFORM-ITEMSET
enketo-secondary-lang 1 1 1 —
XFORM-ITEMSET XFORM-RENDER
enketo-select-dynamic-readonly 1 1 1 —
XFORM-ITEMSET
enketo-select-from-selected 3 3 2 —
XFORM-ITEMSET XFORM-XPATH-UNSUPPORTED
enketo-setgeopoint-multiple-under-one 3 3 0 —
enketo-setgeopoint 3 3 0 —
enketo-setvalue-multiple-under-one 3 3 0 —
enketo-setvalue-order 2 2 0 —
enketo-setvalue-repeat-order 2 1 0 —
enketo-setvalue-repeat-tricky-trigger-target 2 2 0 —
enketo-setvalue-repeat-value-changed 2 1 0 —
enketo-setvalue-repeat 2 2 0 —
XFORM-RENDER
enketo-setvalue-setgeopoint-geopoint 14 13 8 —
XFORM-TYPE-GEO
enketo-setvalue-template 3 3 4 —
XFORM-UNCONTROLLED-VALUE
enketo-setvalue-triggered-by-calc 3 3 0 —
enketo-setvalue 3 3 4 —
XFORM-DEFAULT-TYPE XFORM-UNCONTROLLED-VALUE
enketo-svg-xss-test 1 1 1 —
XFORM-ITEMSET XFORM-RENDER
enketo-thedata 5 5 9 —
XFORM-RENDER XFORM-UNCONTROLLED-VALUE XFORM-XPATH-UNSUPPORTED
enketo-va-who-minimal 3 3 0 —
enketo-va_who_v1_5_3 444 444 35 —
XFORM-RENDER XFORM-TRIGGER XFORM-TYPE-MISMATCH XFORM-XPATH-UNRESOLVED XFORM-XPATH-UNSUPPORTED
enketo-widgets_on_pages 51 51 7 —
XFORM-DEFAULT-TYPE XFORM-ITEMSET XFORM-RENDER XFORM-TRIGGER XFORM-TYPE-BARCODE XFORM-TYPE-TIME
vellum-form0 5 5 0 —
vellum-form1 2 2 0 —
vellum-form3 7 6 0 —
vellum-form4 6 6 1 —
XFORM-XPATH-UNSUPPORTED
vellum-form5 19 19 0 —
XFORM-TRIGGER
vellum-form6 8 8 0 —
vellum-form7 6 6 3 —
XFORM-CHOICE-DUPLICATE XFORM-TYPE-BARCODE XFORM-XPATH-UNSUPPORTED
vellum-form8 1 1 0 —
vellum-form_with_3_languages 2 2 0 —
vellum-form_with_crufty_itext1 5 5 0 —
vellum-form_with_many_diff_qtypes 7 5 0 —
XFORM-TRIGGER
vellum-form_with_no_body 0 0 0 —
vellum-form_with_no_children_data 5 5 0 —
vellum-form_with_no_data_attrs 5 5 0 —
vellum-form_with_secret 4 4 1 —
XFORM-XPATH-UNRESOLVED
vellum-cchq-Close-a-pregnancy 43 43 0 —
XFORM-TRIGGER
vellum-cchq-Follow-up-a-Household-Referral 8 8 0 —
vellum-cchq-Follow-up-a-pregnancy-referral 13 13 0 —
XFORM-TRIGGER
vellum-cchq-Follow-up-a-pregnancy 19 19 0 —
XFORM-TRIGGER
vellum-cchq-Follow-up-at-household 25 22 1 —
XFORM-TRIGGER XFORM-XPATH-UNSUPPORTED
vellum-cchq-Gravidez 29 29 0 —
XFORM-TRIGGER
vellum-cchq-NutritionAndHealth 9 9 0 —
XFORM-TRIGGER
vellum-cchq-Pos-Parto 11 11 0 —
XFORM-TRIGGER
vellum-cchq-Register-a-household 6 6 1 —
XFORM-XPATH-UNSUPPORTED
vellum-cchq-Register-a-pregnancy 27 27 0 —
XFORM-TRIGGER
vellum-cchq-Registo 7 7 1 —
XFORM-TRIGGER XFORM-XPATH-UNSUPPORTED
vellum-cchq-ff 8 8 0 —
vellum-nested_form_with_complex_qs 7 6 0 —
pyxform-attribute_columns_test 43 36 15 —
XFORM-ITEMSET XFORM-RENDER XFORM-TRIGGER XFORM-TYPE-BARCODE XFORM-TYPE-MISMATCH XFORM-TYPE-TIME XFORM-XPATH-UNSUPPORTED
pyxform-flat_xlsform_test 42 42 14 —
XFORM-ITEMSET XFORM-RENDER XFORM-TRIGGER XFORM-TYPE-BARCODE XFORM-TYPE-MISMATCH XFORM-TYPE-TIME XFORM-XPATH-UNSUPPORTED
pyxform-or_other 3 3 2 —
XFORM-ITEMSET
pyxform-pull_data 2 2 1 —
XFORM-XPATH-UNSUPPORTED
pyxform-repeat_date_test 5 4 3 —
XFORM-ITEMSET XFORM-TYPE-MISMATCH
pyxform-survey_no_name 1 1 0 —
pyxform-widgets 35 35 22 —
XFORM-DEFAULT-TYPE XFORM-ITEMSET XFORM-RENDER XFORM-TRIGGER XFORM-TYPE-BARCODE XFORM-TYPE-TIME
pyxform-xlsform_spec_test 42 35 15 —
XFORM-ITEMSET XFORM-RENDER XFORM-TRIGGER XFORM-TYPE-BARCODE XFORM-TYPE-MISMATCH XFORM-TYPE-TIME XFORM-XPATH-UNSUPPORTED